From: Christophe Leroy (CS GROUP) Date: Tue, 24 Mar 2026 11:41:16 +0000 (+0100) Subject: fs: Replace user_access_{begin/end} by scoped user access X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b98f7363f72ff83b9f5194d26e7f9fe74f45b46a;p=thirdparty%2Fkernel%2Flinux.git 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) Link: https://patch.msgid.link/16daf33a8190a771a93e294d050bd8153521ffca.1774350128.git.chleroy@kernel.org Signed-off-by: Christian Brauner --- diff --git a/fs/readdir.c b/fs/readdir.c index fb910dc2f52b5..76bb1ae3a4504 100644 --- a/fs/readdir.c +++ b/fs/readdir.c @@ -200,16 +200,13 @@ static bool fillonedir(struct dir_context *ctx, const char *name, int namlen, } buf->result++; dirent = buf->dirent; - if (!user_write_access_begin(dirent, dirent_size(dirent, namlen + 1))) - goto efault; - unsafe_put_user(d_ino, &dirent->d_ino, efault_end); - unsafe_put_user(offset, &dirent->d_offset, efault_end); - unsafe_put_user(namlen, &dirent->d_namlen, efault_end); - unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end); - user_write_access_end(); + scoped_user_write_access_size(dirent, dirent_size(dirent, namlen + 1), efault) { + unsafe_put_user(d_ino, &dirent->d_ino, efault); + unsafe_put_user(offset, &dirent->d_offset, efault); + unsafe_put_user(namlen, &dirent->d_namlen, efault); + unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault); + } return true; -efault_end: - user_write_access_end(); efault: buf->result = -EFAULT; return false; @@ -286,23 +283,19 @@ static bool filldir(struct dir_context *ctx, const char *name, int namlen, return false; dirent = buf->current_dir; prev = (void __user *) dirent - prev_reclen; - if (!user_write_access_begin(prev, reclen + prev_reclen)) - goto efault; - - /* This might be 'dirent->d_off', but if so it will get overwritten */ - unsafe_put_user(offset, &prev->d_off, efault_end); - unsafe_put_user(d_ino, &dirent->d_ino, efault_end); - unsafe_put_user(reclen, &dirent->d_reclen, efault_end); - unsafe_put_user(d_type, (char __user *) dirent + reclen - 1, efault_end); - unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end); - user_write_access_end(); + scoped_user_write_access_size(prev, reclen + prev_reclen, efault) { + /* This might be 'dirent->d_off', but if so it will get overwritten */ + unsafe_put_user(offset, &prev->d_off, efault); + unsafe_put_user(d_ino, &dirent->d_ino, efault); + unsafe_put_user(reclen, &dirent->d_reclen, efault); + unsafe_put_user(d_type, (char __user *)dirent + reclen - 1, efault); + unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault); + } buf->current_dir = (void __user *)dirent + reclen; buf->prev_reclen = reclen; ctx->count -= reclen; return true; -efault_end: - user_write_access_end(); efault: buf->error = -EFAULT; return false; @@ -369,24 +362,20 @@ static bool filldir64(struct dir_context *ctx, const char *name, int namlen, return false; dirent = buf->current_dir; prev = (void __user *)dirent - prev_reclen; - if (!user_write_access_begin(prev, reclen + prev_reclen)) - goto efault; - - /* This might be 'dirent->d_off', but if so it will get overwritten */ - unsafe_put_user(offset, &prev->d_off, efault_end); - unsafe_put_user(ino, &dirent->d_ino, efault_end); - unsafe_put_user(reclen, &dirent->d_reclen, efault_end); - unsafe_put_user(d_type, &dirent->d_type, efault_end); - unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end); - user_write_access_end(); + scoped_user_write_access_size(prev, reclen + prev_reclen, efault) { + /* This might be 'dirent->d_off', but if so it will get overwritten */ + unsafe_put_user(offset, &prev->d_off, efault); + unsafe_put_user(ino, &dirent->d_ino, efault); + unsafe_put_user(reclen, &dirent->d_reclen, efault); + unsafe_put_user(d_type, &dirent->d_type, efault); + unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault); + } buf->prev_reclen = reclen; buf->current_dir = (void __user *)dirent + reclen; ctx->count -= reclen; return true; -efault_end: - user_write_access_end(); efault: buf->error = -EFAULT; return false; @@ -458,16 +447,13 @@ static bool compat_fillonedir(struct dir_context *ctx, const char *name, } buf->result++; dirent = buf->dirent; - if (!user_write_access_begin(dirent, dirent_size(dirent, namlen + 1))) - goto efault; - unsafe_put_user(d_ino, &dirent->d_ino, efault_end); - unsafe_put_user(offset, &dirent->d_offset, efault_end); - unsafe_put_user(namlen, &dirent->d_namlen, efault_end); - unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end); - user_write_access_end(); + scoped_user_write_access_size(dirent, dirent_size(dirent, namlen + 1), efault) { + unsafe_put_user(d_ino, &dirent->d_ino, efault); + unsafe_put_user(offset, &dirent->d_offset, efault); + unsafe_put_user(namlen, &dirent->d_namlen, efault); + unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault); + } return true; -efault_end: - user_write_access_end(); efault: buf->result = -EFAULT; return false; @@ -538,22 +524,18 @@ static bool compat_filldir(struct dir_context *ctx, const char *name, int namlen return false; dirent = buf->current_dir; prev = (void __user *) dirent - prev_reclen; - if (!user_write_access_begin(prev, reclen + prev_reclen)) - goto efault; - - unsafe_put_user(offset, &prev->d_off, efault_end); - unsafe_put_user(d_ino, &dirent->d_ino, efault_end); - unsafe_put_user(reclen, &dirent->d_reclen, efault_end); - unsafe_put_user(d_type, (char __user *) dirent + reclen - 1, efault_end); - unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end); - user_write_access_end(); + scoped_user_write_access_size(prev, reclen + prev_reclen, efault) { + unsafe_put_user(offset, &prev->d_off, efault); + unsafe_put_user(d_ino, &dirent->d_ino, efault); + unsafe_put_user(reclen, &dirent->d_reclen, efault); + unsafe_put_user(d_type, (char __user *)dirent + reclen - 1, efault); + unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault); + } buf->prev_reclen = reclen; buf->current_dir = (void __user *)dirent + reclen; ctx->count -= reclen; return true; -efault_end: - user_write_access_end(); efault: buf->error = -EFAULT; return false; diff --git a/fs/select.c b/fs/select.c index 78a1508c84d3d..eef27707f9122 100644 --- a/fs/select.c +++ b/fs/select.c @@ -1005,17 +1005,17 @@ static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, fdcount = do_poll(head, &table, end_time); poll_freewait(&table); - if (!user_write_access_begin(ufds, nfds * sizeof(*ufds))) - goto out_fds; + scoped_user_write_access_size(ufds, nfds * sizeof(*ufds), out_fds) { + struct pollfd __user *_ufds = ufds; - for (walk = head; walk; walk = walk->next) { - struct pollfd *fds = walk->entries; - unsigned int j; + for (walk = head; walk; walk = walk->next) { + struct pollfd *fds = walk->entries; + unsigned int j; - for (j = walk->len; j; fds++, ufds++, j--) - unsafe_put_user(fds->revents, &ufds->revents, Efault); - } - user_write_access_end(); + for (j = walk->len; j; fds++, _ufds++, j--) + unsafe_put_user(fds->revents, &_ufds->revents, out_fds); + } + } err = fdcount; out_fds: @@ -1027,11 +1027,6 @@ out_fds: } return err; - -Efault: - user_write_access_end(); - err = -EFAULT; - goto out_fds; } 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, struct compat_sigset_argpack __user *from) { if (from) { - if (!user_read_access_begin(from, sizeof(*from))) - return -EFAULT; - unsafe_get_user(to->p, &from->p, Efault); - unsafe_get_user(to->size, &from->size, Efault); - user_read_access_end(); + scoped_user_read_access(from, efault) { + unsafe_get_user(to->p, &from->p, efault); + unsafe_get_user(to->size, &from->size, efault); + } } return 0; -Efault: - user_read_access_end(); +efault: return -EFAULT; }