Skip to content

Commit a857879

Browse files
committed
Merge patch series "credentials guards: the easy cases"
Christian Brauner <brauner@kernel.org> says: This converts all users of override_creds() to rely on credentials guards. Leave all those that do the prepare_creds() + modify creds + override_creds() dance alone for now. Some of them qualify for their own variant. * patches from https://patch.msgid.link/20251103-work-creds-guards-simple-v1-0-a3e156839e7f@kernel.org: net/dns_resolver: use credential guards in dns_query() cgroup: use credential guards in cgroup_attach_permissions() act: use credential guards in acct_write_process() smb: use credential guards in cifs_get_spnego_key() nfs: use credential guards in nfs_idmap_get_key() nfs: use credential guards in nfs_local_call_write() nfs: use credential guards in nfs_local_call_read() erofs: use credential guards binfmt_misc: use credential guards backing-file: use credential guards for mmap backing-file: use credential guards for splice write backing-file: use credential guards for splice read backing-file: use credential guards for writes backing-file: use credential guards for reads aio: use credential guards cred: add {scoped_}with_creds() guards Link: https://patch.msgid.link/20251103-work-creds-guards-simple-v1-0-a3e156839e7f@kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
2 parents e0876bd + 4037e28 commit a857879

11 files changed

Lines changed: 141 additions & 148 deletions

File tree

fs/aio.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1640,10 +1640,10 @@ static int aio_write(struct kiocb *req, const struct iocb *iocb,
16401640
static void aio_fsync_work(struct work_struct *work)
16411641
{
16421642
struct aio_kiocb *iocb = container_of(work, struct aio_kiocb, fsync.work);
1643-
const struct cred *old_cred = override_creds(iocb->fsync.creds);
16441643

1645-
iocb->ki_res.res = vfs_fsync(iocb->fsync.file, iocb->fsync.datasync);
1646-
revert_creds(old_cred);
1644+
scoped_with_creds(iocb->fsync.creds)
1645+
iocb->ki_res.res = vfs_fsync(iocb->fsync.file, iocb->fsync.datasync);
1646+
16471647
put_cred(iocb->fsync.creds);
16481648
iocb_put(iocb);
16491649
}

fs/backing-file.c

Lines changed: 75 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -157,13 +157,37 @@ static int backing_aio_init_wq(struct kiocb *iocb)
157157
return sb_init_dio_done_wq(sb);
158158
}
159159

160+
static int do_backing_file_read_iter(struct file *file, struct iov_iter *iter,
161+
struct kiocb *iocb, int flags)
162+
{
163+
struct backing_aio *aio = NULL;
164+
int ret;
165+
166+
if (is_sync_kiocb(iocb)) {
167+
rwf_t rwf = iocb_to_rw_flags(flags);
168+
169+
return vfs_iter_read(file, iter, &iocb->ki_pos, rwf);
170+
}
171+
172+
aio = kmem_cache_zalloc(backing_aio_cachep, GFP_KERNEL);
173+
if (!aio)
174+
return -ENOMEM;
175+
176+
aio->orig_iocb = iocb;
177+
kiocb_clone(&aio->iocb, iocb, get_file(file));
178+
aio->iocb.ki_complete = backing_aio_rw_complete;
179+
refcount_set(&aio->ref, 2);
180+
ret = vfs_iocb_iter_read(file, &aio->iocb, iter);
181+
backing_aio_put(aio);
182+
if (ret != -EIOCBQUEUED)
183+
backing_aio_cleanup(aio, ret);
184+
return ret;
185+
}
160186

161187
ssize_t backing_file_read_iter(struct file *file, struct iov_iter *iter,
162188
struct kiocb *iocb, int flags,
163189
struct backing_file_ctx *ctx)
164190
{
165-
struct backing_aio *aio = NULL;
166-
const struct cred *old_cred;
167191
ssize_t ret;
168192

169193
if (WARN_ON_ONCE(!(file->f_mode & FMODE_BACKING)))
@@ -176,41 +200,57 @@ ssize_t backing_file_read_iter(struct file *file, struct iov_iter *iter,
176200
!(file->f_mode & FMODE_CAN_ODIRECT))
177201
return -EINVAL;
178202

179-
old_cred = override_creds(ctx->cred);
203+
scoped_with_creds(ctx->cred)
204+
ret = do_backing_file_read_iter(file, iter, iocb, flags);
205+
206+
if (ctx->accessed)
207+
ctx->accessed(iocb->ki_filp);
208+
209+
return ret;
210+
}
211+
EXPORT_SYMBOL_GPL(backing_file_read_iter);
212+
213+
static int do_backing_file_write_iter(struct file *file, struct iov_iter *iter,
214+
struct kiocb *iocb, int flags,
215+
void (*end_write)(struct kiocb *, ssize_t))
216+
{
217+
struct backing_aio *aio;
218+
int ret;
219+
180220
if (is_sync_kiocb(iocb)) {
181221
rwf_t rwf = iocb_to_rw_flags(flags);
182222

183-
ret = vfs_iter_read(file, iter, &iocb->ki_pos, rwf);
184-
} else {
185-
ret = -ENOMEM;
186-
aio = kmem_cache_zalloc(backing_aio_cachep, GFP_KERNEL);
187-
if (!aio)
188-
goto out;
189-
190-
aio->orig_iocb = iocb;
191-
kiocb_clone(&aio->iocb, iocb, get_file(file));
192-
aio->iocb.ki_complete = backing_aio_rw_complete;
193-
refcount_set(&aio->ref, 2);
194-
ret = vfs_iocb_iter_read(file, &aio->iocb, iter);
195-
backing_aio_put(aio);
196-
if (ret != -EIOCBQUEUED)
197-
backing_aio_cleanup(aio, ret);
223+
ret = vfs_iter_write(file, iter, &iocb->ki_pos, rwf);
224+
if (end_write)
225+
end_write(iocb, ret);
226+
return ret;
198227
}
199-
out:
200-
revert_creds(old_cred);
201228

202-
if (ctx->accessed)
203-
ctx->accessed(iocb->ki_filp);
229+
ret = backing_aio_init_wq(iocb);
230+
if (ret)
231+
return ret;
232+
233+
aio = kmem_cache_zalloc(backing_aio_cachep, GFP_KERNEL);
234+
if (!aio)
235+
return -ENOMEM;
204236

237+
aio->orig_iocb = iocb;
238+
aio->end_write = end_write;
239+
kiocb_clone(&aio->iocb, iocb, get_file(file));
240+
aio->iocb.ki_flags = flags;
241+
aio->iocb.ki_complete = backing_aio_queue_completion;
242+
refcount_set(&aio->ref, 2);
243+
ret = vfs_iocb_iter_write(file, &aio->iocb, iter);
244+
backing_aio_put(aio);
245+
if (ret != -EIOCBQUEUED)
246+
backing_aio_cleanup(aio, ret);
205247
return ret;
206248
}
207-
EXPORT_SYMBOL_GPL(backing_file_read_iter);
208249

209250
ssize_t backing_file_write_iter(struct file *file, struct iov_iter *iter,
210251
struct kiocb *iocb, int flags,
211252
struct backing_file_ctx *ctx)
212253
{
213-
const struct cred *old_cred;
214254
ssize_t ret;
215255

216256
if (WARN_ON_ONCE(!(file->f_mode & FMODE_BACKING)))
@@ -233,40 +273,8 @@ ssize_t backing_file_write_iter(struct file *file, struct iov_iter *iter,
233273
*/
234274
flags &= ~IOCB_DIO_CALLER_COMP;
235275

236-
old_cred = override_creds(ctx->cred);
237-
if (is_sync_kiocb(iocb)) {
238-
rwf_t rwf = iocb_to_rw_flags(flags);
239-
240-
ret = vfs_iter_write(file, iter, &iocb->ki_pos, rwf);
241-
if (ctx->end_write)
242-
ctx->end_write(iocb, ret);
243-
} else {
244-
struct backing_aio *aio;
245-
246-
ret = backing_aio_init_wq(iocb);
247-
if (ret)
248-
goto out;
249-
250-
ret = -ENOMEM;
251-
aio = kmem_cache_zalloc(backing_aio_cachep, GFP_KERNEL);
252-
if (!aio)
253-
goto out;
254-
255-
aio->orig_iocb = iocb;
256-
aio->end_write = ctx->end_write;
257-
kiocb_clone(&aio->iocb, iocb, get_file(file));
258-
aio->iocb.ki_flags = flags;
259-
aio->iocb.ki_complete = backing_aio_queue_completion;
260-
refcount_set(&aio->ref, 2);
261-
ret = vfs_iocb_iter_write(file, &aio->iocb, iter);
262-
backing_aio_put(aio);
263-
if (ret != -EIOCBQUEUED)
264-
backing_aio_cleanup(aio, ret);
265-
}
266-
out:
267-
revert_creds(old_cred);
268-
269-
return ret;
276+
scoped_with_creds(ctx->cred)
277+
return do_backing_file_write_iter(file, iter, iocb, flags, ctx->end_write);
270278
}
271279
EXPORT_SYMBOL_GPL(backing_file_write_iter);
272280

@@ -275,15 +283,13 @@ ssize_t backing_file_splice_read(struct file *in, struct kiocb *iocb,
275283
unsigned int flags,
276284
struct backing_file_ctx *ctx)
277285
{
278-
const struct cred *old_cred;
279286
ssize_t ret;
280287

281288
if (WARN_ON_ONCE(!(in->f_mode & FMODE_BACKING)))
282289
return -EIO;
283290

284-
old_cred = override_creds(ctx->cred);
285-
ret = vfs_splice_read(in, &iocb->ki_pos, pipe, len, flags);
286-
revert_creds(old_cred);
291+
scoped_with_creds(ctx->cred)
292+
ret = vfs_splice_read(in, &iocb->ki_pos, pipe, len, flags);
287293

288294
if (ctx->accessed)
289295
ctx->accessed(iocb->ki_filp);
@@ -297,7 +303,6 @@ ssize_t backing_file_splice_write(struct pipe_inode_info *pipe,
297303
size_t len, unsigned int flags,
298304
struct backing_file_ctx *ctx)
299305
{
300-
const struct cred *old_cred;
301306
ssize_t ret;
302307

303308
if (WARN_ON_ONCE(!(out->f_mode & FMODE_BACKING)))
@@ -310,11 +315,11 @@ ssize_t backing_file_splice_write(struct pipe_inode_info *pipe,
310315
if (ret)
311316
return ret;
312317

313-
old_cred = override_creds(ctx->cred);
314-
file_start_write(out);
315-
ret = out->f_op->splice_write(pipe, out, &iocb->ki_pos, len, flags);
316-
file_end_write(out);
317-
revert_creds(old_cred);
318+
scoped_with_creds(ctx->cred) {
319+
file_start_write(out);
320+
ret = out->f_op->splice_write(pipe, out, &iocb->ki_pos, len, flags);
321+
file_end_write(out);
322+
}
318323

319324
if (ctx->end_write)
320325
ctx->end_write(iocb, ret);
@@ -326,7 +331,6 @@ EXPORT_SYMBOL_GPL(backing_file_splice_write);
326331
int backing_file_mmap(struct file *file, struct vm_area_struct *vma,
327332
struct backing_file_ctx *ctx)
328333
{
329-
const struct cred *old_cred;
330334
struct file *user_file = vma->vm_file;
331335
int ret;
332336

@@ -338,9 +342,8 @@ int backing_file_mmap(struct file *file, struct vm_area_struct *vma,
338342

339343
vma_set_file(vma, file);
340344

341-
old_cred = override_creds(ctx->cred);
342-
ret = vfs_mmap(vma->vm_file, vma);
343-
revert_creds(old_cred);
345+
scoped_with_creds(ctx->cred)
346+
ret = vfs_mmap(vma->vm_file, vma);
344347

345348
if (ctx->accessed)
346349
ctx->accessed(user_file);

fs/binfmt_misc.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -782,18 +782,15 @@ static ssize_t bm_register_write(struct file *file, const char __user *buffer,
782782
return PTR_ERR(e);
783783

784784
if (e->flags & MISC_FMT_OPEN_FILE) {
785-
const struct cred *old_cred;
786-
787785
/*
788786
* Now that we support unprivileged binfmt_misc mounts make
789787
* sure we use the credentials that the register @file was
790788
* opened with to also open the interpreter. Before that this
791789
* didn't matter much as only a privileged process could open
792790
* the register file.
793791
*/
794-
old_cred = override_creds(file->f_cred);
795-
f = open_exec(e->interpreter);
796-
revert_creds(old_cred);
792+
scoped_with_creds(file->f_cred)
793+
f = open_exec(e->interpreter);
797794
if (IS_ERR(f)) {
798795
pr_notice("register: failed to install interpreter file %s\n",
799796
e->interpreter);

fs/erofs/fileio.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ static void erofs_fileio_ki_complete(struct kiocb *iocb, long ret)
4747

4848
static void erofs_fileio_rq_submit(struct erofs_fileio_rq *rq)
4949
{
50-
const struct cred *old_cred;
5150
struct iov_iter iter;
5251
int ret;
5352

@@ -61,9 +60,8 @@ static void erofs_fileio_rq_submit(struct erofs_fileio_rq *rq)
6160
rq->iocb.ki_flags = IOCB_DIRECT;
6261
iov_iter_bvec(&iter, ITER_DEST, rq->bvecs, rq->bio.bi_vcnt,
6362
rq->bio.bi_iter.bi_size);
64-
old_cred = override_creds(rq->iocb.ki_filp->f_cred);
65-
ret = vfs_iocb_iter_read(rq->iocb.ki_filp, &rq->iocb, &iter);
66-
revert_creds(old_cred);
63+
scoped_with_creds(rq->iocb.ki_filp->f_cred)
64+
ret = vfs_iocb_iter_read(rq->iocb.ki_filp, &rq->iocb, &iter);
6765
if (ret != -EIOCBQUEUED)
6866
erofs_fileio_ki_complete(&rq->iocb, ret);
6967
}

fs/nfs/localio.c

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -595,29 +595,26 @@ static void nfs_local_call_read(struct work_struct *work)
595595
struct nfs_local_kiocb *iocb =
596596
container_of(work, struct nfs_local_kiocb, work);
597597
struct file *filp = iocb->kiocb.ki_filp;
598-
const struct cred *save_cred;
599598
ssize_t status;
600599

601-
save_cred = override_creds(filp->f_cred);
602-
603-
for (int i = 0; i < iocb->n_iters ; i++) {
604-
if (iocb->iter_is_dio_aligned[i]) {
605-
iocb->kiocb.ki_flags |= IOCB_DIRECT;
606-
iocb->kiocb.ki_complete = nfs_local_read_aio_complete;
607-
iocb->aio_complete_work = nfs_local_read_aio_complete_work;
608-
}
600+
scoped_with_creds(filp->f_cred) {
601+
for (int i = 0; i < iocb->n_iters ; i++) {
602+
if (iocb->iter_is_dio_aligned[i]) {
603+
iocb->kiocb.ki_flags |= IOCB_DIRECT;
604+
iocb->kiocb.ki_complete = nfs_local_read_aio_complete;
605+
iocb->aio_complete_work = nfs_local_read_aio_complete_work;
606+
}
609607

610-
iocb->kiocb.ki_pos = iocb->offset[i];
611-
status = filp->f_op->read_iter(&iocb->kiocb, &iocb->iters[i]);
612-
if (status != -EIOCBQUEUED) {
613-
nfs_local_pgio_done(iocb->hdr, status);
614-
if (iocb->hdr->task.tk_status)
615-
break;
608+
iocb->kiocb.ki_pos = iocb->offset[i];
609+
status = filp->f_op->read_iter(&iocb->kiocb, &iocb->iters[i]);
610+
if (status != -EIOCBQUEUED) {
611+
nfs_local_pgio_done(iocb->hdr, status);
612+
if (iocb->hdr->task.tk_status)
613+
break;
614+
}
616615
}
617616
}
618617

619-
revert_creds(save_cred);
620-
621618
if (status != -EIOCBQUEUED) {
622619
nfs_local_read_done(iocb, status);
623620
nfs_local_pgio_release(iocb);
@@ -784,18 +781,11 @@ static void nfs_local_write_aio_complete(struct kiocb *kiocb, long ret)
784781
nfs_local_pgio_aio_complete(iocb); /* Calls nfs_local_write_aio_complete_work */
785782
}
786783

787-
static void nfs_local_call_write(struct work_struct *work)
784+
static ssize_t do_nfs_local_call_write(struct nfs_local_kiocb *iocb,
785+
struct file *filp)
788786
{
789-
struct nfs_local_kiocb *iocb =
790-
container_of(work, struct nfs_local_kiocb, work);
791-
struct file *filp = iocb->kiocb.ki_filp;
792-
unsigned long old_flags = current->flags;
793-
const struct cred *save_cred;
794787
ssize_t status;
795788

796-
current->flags |= PF_LOCAL_THROTTLE | PF_MEMALLOC_NOIO;
797-
save_cred = override_creds(filp->f_cred);
798-
799789
file_start_write(filp);
800790
for (int i = 0; i < iocb->n_iters ; i++) {
801791
if (iocb->iter_is_dio_aligned[i]) {
@@ -840,7 +830,22 @@ static void nfs_local_call_write(struct work_struct *work)
840830
}
841831
file_end_write(filp);
842832

843-
revert_creds(save_cred);
833+
return status;
834+
}
835+
836+
static void nfs_local_call_write(struct work_struct *work)
837+
{
838+
struct nfs_local_kiocb *iocb =
839+
container_of(work, struct nfs_local_kiocb, work);
840+
struct file *filp = iocb->kiocb.ki_filp;
841+
unsigned long old_flags = current->flags;
842+
ssize_t status;
843+
844+
current->flags |= PF_LOCAL_THROTTLE | PF_MEMALLOC_NOIO;
845+
846+
scoped_with_creds(filp->f_cred)
847+
status = do_nfs_local_call_write(iocb, filp);
848+
844849
current->flags = old_flags;
845850

846851
if (status != -EIOCBQUEUED) {

fs/nfs/nfs4idmap.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -306,15 +306,12 @@ static ssize_t nfs_idmap_get_key(const char *name, size_t namelen,
306306
const char *type, void *data,
307307
size_t data_size, struct idmap *idmap)
308308
{
309-
const struct cred *saved_cred;
310309
struct key *rkey;
311310
const struct user_key_payload *payload;
312311
ssize_t ret;
313312

314-
saved_cred = override_creds(id_resolver_cache);
315-
rkey = nfs_idmap_request_key(name, namelen, type, idmap);
316-
revert_creds(saved_cred);
317-
313+
scoped_with_creds(id_resolver_cache)
314+
rkey = nfs_idmap_request_key(name, namelen, type, idmap);
318315
if (IS_ERR(rkey)) {
319316
ret = PTR_ERR(rkey);
320317
goto out;

0 commit comments

Comments
 (0)