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);
|
||||
|
||||
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,
|
||||
struct kiocb *iocb, int flags,
|
||||
struct backing_file_ctx *ctx)
|
||||
{
|
||||
const struct cred *old_cred;
|
||||
ssize_t ret;
|
||||
|
||||
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;
|
||||
|
||||
old_cred = override_creds(ctx->cred);
|
||||
if (is_sync_kiocb(iocb)) {
|
||||
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;
|
||||
scoped_with_creds(ctx->cred)
|
||||
return do_backing_file_write_iter(file, iter, iocb, flags, ctx->end_write);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(backing_file_write_iter);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user