mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
backing-file: use credential guards for writes
Use credential guards for scoped credential override with automatic restoration on scope exit. Link: https://patch.msgid.link/20251103-work-creds-guards-simple-v1-4-a3e156839e7f@kernel.org Reviewed-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
@@ -210,11 +210,47 @@ ssize_t backing_file_read_iter(struct file *file, struct iov_iter *iter,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(backing_file_read_iter);
|
EXPORT_SYMBOL_GPL(backing_file_read_iter);
|
||||||
|
|
||||||
|
static int do_backing_file_write_iter(struct file *file, struct iov_iter *iter,
|
||||||
|
struct kiocb *iocb, int flags,
|
||||||
|
void (*end_write)(struct kiocb *, ssize_t))
|
||||||
|
{
|
||||||
|
struct backing_aio *aio;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (is_sync_kiocb(iocb)) {
|
||||||
|
rwf_t rwf = iocb_to_rw_flags(flags);
|
||||||
|
|
||||||
|
ret = vfs_iter_write(file, iter, &iocb->ki_pos, rwf);
|
||||||
|
if (end_write)
|
||||||
|
end_write(iocb, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = backing_aio_init_wq(iocb);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
aio = kmem_cache_zalloc(backing_aio_cachep, GFP_KERNEL);
|
||||||
|
if (!aio)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
aio->orig_iocb = iocb;
|
||||||
|
aio->end_write = end_write;
|
||||||
|
kiocb_clone(&aio->iocb, iocb, get_file(file));
|
||||||
|
aio->iocb.ki_flags = flags;
|
||||||
|
aio->iocb.ki_complete = backing_aio_queue_completion;
|
||||||
|
refcount_set(&aio->ref, 2);
|
||||||
|
ret = vfs_iocb_iter_write(file, &aio->iocb, iter);
|
||||||
|
backing_aio_put(aio);
|
||||||
|
if (ret != -EIOCBQUEUED)
|
||||||
|
backing_aio_cleanup(aio, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
ssize_t backing_file_write_iter(struct file *file, struct iov_iter *iter,
|
ssize_t backing_file_write_iter(struct file *file, struct iov_iter *iter,
|
||||||
struct kiocb *iocb, int flags,
|
struct kiocb *iocb, int flags,
|
||||||
struct backing_file_ctx *ctx)
|
struct backing_file_ctx *ctx)
|
||||||
{
|
{
|
||||||
const struct cred *old_cred;
|
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
if (WARN_ON_ONCE(!(file->f_mode & FMODE_BACKING)))
|
if (WARN_ON_ONCE(!(file->f_mode & FMODE_BACKING)))
|
||||||
@@ -237,40 +273,8 @@ ssize_t backing_file_write_iter(struct file *file, struct iov_iter *iter,
|
|||||||
*/
|
*/
|
||||||
flags &= ~IOCB_DIO_CALLER_COMP;
|
flags &= ~IOCB_DIO_CALLER_COMP;
|
||||||
|
|
||||||
old_cred = override_creds(ctx->cred);
|
scoped_with_creds(ctx->cred)
|
||||||
if (is_sync_kiocb(iocb)) {
|
return do_backing_file_write_iter(file, iter, iocb, flags, ctx->end_write);
|
||||||
rwf_t rwf = iocb_to_rw_flags(flags);
|
|
||||||
|
|
||||||
ret = vfs_iter_write(file, iter, &iocb->ki_pos, rwf);
|
|
||||||
if (ctx->end_write)
|
|
||||||
ctx->end_write(iocb, ret);
|
|
||||||
} else {
|
|
||||||
struct backing_aio *aio;
|
|
||||||
|
|
||||||
ret = backing_aio_init_wq(iocb);
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ret = -ENOMEM;
|
|
||||||
aio = kmem_cache_zalloc(backing_aio_cachep, GFP_KERNEL);
|
|
||||||
if (!aio)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
aio->orig_iocb = iocb;
|
|
||||||
aio->end_write = ctx->end_write;
|
|
||||||
kiocb_clone(&aio->iocb, iocb, get_file(file));
|
|
||||||
aio->iocb.ki_flags = flags;
|
|
||||||
aio->iocb.ki_complete = backing_aio_queue_completion;
|
|
||||||
refcount_set(&aio->ref, 2);
|
|
||||||
ret = vfs_iocb_iter_write(file, &aio->iocb, iter);
|
|
||||||
backing_aio_put(aio);
|
|
||||||
if (ret != -EIOCBQUEUED)
|
|
||||||
backing_aio_cleanup(aio, ret);
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
revert_creds(old_cred);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(backing_file_write_iter);
|
EXPORT_SYMBOL_GPL(backing_file_write_iter);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user