Skip to content

Commit b98f736

Browse files
Christophe Leroy (CS GROUP)brauner
authored andcommitted
fs: Replace user_access_{begin/end} by scoped user access
Scoped user access reduces code complexity and seamlessly bring masked user access on architectures that support it. Replace user_access_begin/user_access_end blocks by scoped user access. Signed-off-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org> Link: https://patch.msgid.link/16daf33a8190a771a93e294d050bd8153521ffca.1774350128.git.chleroy@kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent 4bf798e commit b98f736

2 files changed

Lines changed: 49 additions & 74 deletions

File tree

fs/readdir.c

Lines changed: 35 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -200,16 +200,13 @@ static bool fillonedir(struct dir_context *ctx, const char *name, int namlen,
200200
}
201201
buf->result++;
202202
dirent = buf->dirent;
203-
if (!user_write_access_begin(dirent, dirent_size(dirent, namlen + 1)))
204-
goto efault;
205-
unsafe_put_user(d_ino, &dirent->d_ino, efault_end);
206-
unsafe_put_user(offset, &dirent->d_offset, efault_end);
207-
unsafe_put_user(namlen, &dirent->d_namlen, efault_end);
208-
unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
209-
user_write_access_end();
203+
scoped_user_write_access_size(dirent, dirent_size(dirent, namlen + 1), efault) {
204+
unsafe_put_user(d_ino, &dirent->d_ino, efault);
205+
unsafe_put_user(offset, &dirent->d_offset, efault);
206+
unsafe_put_user(namlen, &dirent->d_namlen, efault);
207+
unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault);
208+
}
210209
return true;
211-
efault_end:
212-
user_write_access_end();
213210
efault:
214211
buf->result = -EFAULT;
215212
return false;
@@ -286,23 +283,19 @@ static bool filldir(struct dir_context *ctx, const char *name, int namlen,
286283
return false;
287284
dirent = buf->current_dir;
288285
prev = (void __user *) dirent - prev_reclen;
289-
if (!user_write_access_begin(prev, reclen + prev_reclen))
290-
goto efault;
291-
292-
/* This might be 'dirent->d_off', but if so it will get overwritten */
293-
unsafe_put_user(offset, &prev->d_off, efault_end);
294-
unsafe_put_user(d_ino, &dirent->d_ino, efault_end);
295-
unsafe_put_user(reclen, &dirent->d_reclen, efault_end);
296-
unsafe_put_user(d_type, (char __user *) dirent + reclen - 1, efault_end);
297-
unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
298-
user_write_access_end();
286+
scoped_user_write_access_size(prev, reclen + prev_reclen, efault) {
287+
/* This might be 'dirent->d_off', but if so it will get overwritten */
288+
unsafe_put_user(offset, &prev->d_off, efault);
289+
unsafe_put_user(d_ino, &dirent->d_ino, efault);
290+
unsafe_put_user(reclen, &dirent->d_reclen, efault);
291+
unsafe_put_user(d_type, (char __user *)dirent + reclen - 1, efault);
292+
unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault);
293+
}
299294

300295
buf->current_dir = (void __user *)dirent + reclen;
301296
buf->prev_reclen = reclen;
302297
ctx->count -= reclen;
303298
return true;
304-
efault_end:
305-
user_write_access_end();
306299
efault:
307300
buf->error = -EFAULT;
308301
return false;
@@ -369,24 +362,20 @@ static bool filldir64(struct dir_context *ctx, const char *name, int namlen,
369362
return false;
370363
dirent = buf->current_dir;
371364
prev = (void __user *)dirent - prev_reclen;
372-
if (!user_write_access_begin(prev, reclen + prev_reclen))
373-
goto efault;
374-
375-
/* This might be 'dirent->d_off', but if so it will get overwritten */
376-
unsafe_put_user(offset, &prev->d_off, efault_end);
377-
unsafe_put_user(ino, &dirent->d_ino, efault_end);
378-
unsafe_put_user(reclen, &dirent->d_reclen, efault_end);
379-
unsafe_put_user(d_type, &dirent->d_type, efault_end);
380-
unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
381-
user_write_access_end();
365+
scoped_user_write_access_size(prev, reclen + prev_reclen, efault) {
366+
/* This might be 'dirent->d_off', but if so it will get overwritten */
367+
unsafe_put_user(offset, &prev->d_off, efault);
368+
unsafe_put_user(ino, &dirent->d_ino, efault);
369+
unsafe_put_user(reclen, &dirent->d_reclen, efault);
370+
unsafe_put_user(d_type, &dirent->d_type, efault);
371+
unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault);
372+
}
382373

383374
buf->prev_reclen = reclen;
384375
buf->current_dir = (void __user *)dirent + reclen;
385376
ctx->count -= reclen;
386377
return true;
387378

388-
efault_end:
389-
user_write_access_end();
390379
efault:
391380
buf->error = -EFAULT;
392381
return false;
@@ -458,16 +447,13 @@ static bool compat_fillonedir(struct dir_context *ctx, const char *name,
458447
}
459448
buf->result++;
460449
dirent = buf->dirent;
461-
if (!user_write_access_begin(dirent, dirent_size(dirent, namlen + 1)))
462-
goto efault;
463-
unsafe_put_user(d_ino, &dirent->d_ino, efault_end);
464-
unsafe_put_user(offset, &dirent->d_offset, efault_end);
465-
unsafe_put_user(namlen, &dirent->d_namlen, efault_end);
466-
unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
467-
user_write_access_end();
450+
scoped_user_write_access_size(dirent, dirent_size(dirent, namlen + 1), efault) {
451+
unsafe_put_user(d_ino, &dirent->d_ino, efault);
452+
unsafe_put_user(offset, &dirent->d_offset, efault);
453+
unsafe_put_user(namlen, &dirent->d_namlen, efault);
454+
unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault);
455+
}
468456
return true;
469-
efault_end:
470-
user_write_access_end();
471457
efault:
472458
buf->result = -EFAULT;
473459
return false;
@@ -538,22 +524,18 @@ static bool compat_filldir(struct dir_context *ctx, const char *name, int namlen
538524
return false;
539525
dirent = buf->current_dir;
540526
prev = (void __user *) dirent - prev_reclen;
541-
if (!user_write_access_begin(prev, reclen + prev_reclen))
542-
goto efault;
543-
544-
unsafe_put_user(offset, &prev->d_off, efault_end);
545-
unsafe_put_user(d_ino, &dirent->d_ino, efault_end);
546-
unsafe_put_user(reclen, &dirent->d_reclen, efault_end);
547-
unsafe_put_user(d_type, (char __user *) dirent + reclen - 1, efault_end);
548-
unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
549-
user_write_access_end();
527+
scoped_user_write_access_size(prev, reclen + prev_reclen, efault) {
528+
unsafe_put_user(offset, &prev->d_off, efault);
529+
unsafe_put_user(d_ino, &dirent->d_ino, efault);
530+
unsafe_put_user(reclen, &dirent->d_reclen, efault);
531+
unsafe_put_user(d_type, (char __user *)dirent + reclen - 1, efault);
532+
unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault);
533+
}
550534

551535
buf->prev_reclen = reclen;
552536
buf->current_dir = (void __user *)dirent + reclen;
553537
ctx->count -= reclen;
554538
return true;
555-
efault_end:
556-
user_write_access_end();
557539
efault:
558540
buf->error = -EFAULT;
559541
return false;

fs/select.c

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,17 +1005,17 @@ static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,
10051005
fdcount = do_poll(head, &table, end_time);
10061006
poll_freewait(&table);
10071007

1008-
if (!user_write_access_begin(ufds, nfds * sizeof(*ufds)))
1009-
goto out_fds;
1008+
scoped_user_write_access_size(ufds, nfds * sizeof(*ufds), out_fds) {
1009+
struct pollfd __user *_ufds = ufds;
10101010

1011-
for (walk = head; walk; walk = walk->next) {
1012-
struct pollfd *fds = walk->entries;
1013-
unsigned int j;
1011+
for (walk = head; walk; walk = walk->next) {
1012+
struct pollfd *fds = walk->entries;
1013+
unsigned int j;
10141014

1015-
for (j = walk->len; j; fds++, ufds++, j--)
1016-
unsafe_put_user(fds->revents, &ufds->revents, Efault);
1017-
}
1018-
user_write_access_end();
1015+
for (j = walk->len; j; fds++, _ufds++, j--)
1016+
unsafe_put_user(fds->revents, &_ufds->revents, out_fds);
1017+
}
1018+
}
10191019

10201020
err = fdcount;
10211021
out_fds:
@@ -1027,11 +1027,6 @@ static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,
10271027
}
10281028

10291029
return err;
1030-
1031-
Efault:
1032-
user_write_access_end();
1033-
err = -EFAULT;
1034-
goto out_fds;
10351030
}
10361031

10371032
static long do_restart_poll(struct restart_block *restart_block)
@@ -1339,15 +1334,13 @@ static inline int get_compat_sigset_argpack(struct compat_sigset_argpack *to,
13391334
struct compat_sigset_argpack __user *from)
13401335
{
13411336
if (from) {
1342-
if (!user_read_access_begin(from, sizeof(*from)))
1343-
return -EFAULT;
1344-
unsafe_get_user(to->p, &from->p, Efault);
1345-
unsafe_get_user(to->size, &from->size, Efault);
1346-
user_read_access_end();
1337+
scoped_user_read_access(from, efault) {
1338+
unsafe_get_user(to->p, &from->p, efault);
1339+
unsafe_get_user(to->size, &from->size, efault);
1340+
}
13471341
}
13481342
return 0;
1349-
Efault:
1350-
user_read_access_end();
1343+
efault:
13511344
return -EFAULT;
13521345
}
13531346

0 commit comments

Comments
 (0)