From: Greg Kroah-Hartman Date: Wed, 14 Aug 2024 18:08:03 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v4.19.320~43 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=389ee88c666a9e7fd0fb60bec28e6f4eac6f78b0;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: exec-fix-toctou-between-perm-check-and-set-uid-gid-usage.patch --- diff --git a/queue-5.4/exec-fix-toctou-between-perm-check-and-set-uid-gid-usage.patch b/queue-5.4/exec-fix-toctou-between-perm-check-and-set-uid-gid-usage.patch new file mode 100644 index 00000000000..d9ca4050c41 --- /dev/null +++ b/queue-5.4/exec-fix-toctou-between-perm-check-and-set-uid-gid-usage.patch @@ -0,0 +1,95 @@ +From f50733b45d865f91db90919f8311e2127ce5a0cb Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Thu, 8 Aug 2024 11:39:08 -0700 +Subject: exec: Fix ToCToU between perm check and set-uid/gid usage + +From: Kees Cook + +commit f50733b45d865f91db90919f8311e2127ce5a0cb upstream. + +When opening a file for exec via do_filp_open(), permission checking is +done against the file's metadata at that moment, and on success, a file +pointer is passed back. Much later in the execve() code path, the file +metadata (specifically mode, uid, and gid) is used to determine if/how +to set the uid and gid. However, those values may have changed since the +permissions check, meaning the execution may gain unintended privileges. + +For example, if a file could change permissions from executable and not +set-id: + +---------x 1 root root 16048 Aug 7 13:16 target + +to set-id and non-executable: + +---S------ 1 root root 16048 Aug 7 13:16 target + +it is possible to gain root privileges when execution should have been +disallowed. + +While this race condition is rare in real-world scenarios, it has been +observed (and proven exploitable) when package managers are updating +the setuid bits of installed programs. Such files start with being +world-executable but then are adjusted to be group-exec with a set-uid +bit. For example, "chmod o-x,u+s target" makes "target" executable only +by uid "root" and gid "cdrom", while also becoming setuid-root: + +-rwxr-xr-x 1 root cdrom 16048 Aug 7 13:16 target + +becomes: + +-rwsr-xr-- 1 root cdrom 16048 Aug 7 13:16 target + +But racing the chmod means users without group "cdrom" membership can +get the permission to execute "target" just before the chmod, and when +the chmod finishes, the exec reaches brpm_fill_uid(), and performs the +setuid to root, violating the expressed authorization of "only cdrom +group members can setuid to root". + +Re-check that we still have execute permissions in case the metadata +has changed. It would be better to keep a copy from the perm-check time, +but until we can do that refactoring, the least-bad option is to do a +full inode_permission() call (under inode lock). It is understood that +this is safe against dead-locks, but hardly optimal. + +Reported-by: Marco Vanotti +Tested-by: Marco Vanotti +Suggested-by: Linus Torvalds +Cc: stable@vger.kernel.org +Cc: Eric Biederman +Cc: Alexander Viro +Cc: Christian Brauner +Signed-off-by: Kees Cook +Signed-off-by: Greg Kroah-Hartman +--- + fs/exec.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -1558,6 +1558,7 @@ static void bprm_fill_uid(struct linux_b + unsigned int mode; + kuid_t uid; + kgid_t gid; ++ int err; + + /* + * Since this can be called multiple times (via prepare_binprm), +@@ -1582,12 +1583,17 @@ static void bprm_fill_uid(struct linux_b + /* Be careful if suid/sgid is set */ + inode_lock(inode); + +- /* reload atomically mode/uid/gid now that lock held */ ++ /* Atomically reload and check mode/uid/gid now that lock held. */ + mode = inode->i_mode; + uid = inode->i_uid; + gid = inode->i_gid; ++ err = inode_permission(inode, MAY_EXEC); + inode_unlock(inode); + ++ /* Did the exec bit vanish out from under us? Give up. */ ++ if (err) ++ return; ++ + /* We ignore suid/sgid if there are no mappings for them in the ns */ + if (!kuid_has_mapping(bprm->cred->user_ns, uid) || + !kgid_has_mapping(bprm->cred->user_ns, gid)) diff --git a/queue-5.4/series b/queue-5.4/series index a1a20eb6a9d..e07bf2d2e02 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -254,3 +254,4 @@ netfilter-nf_tables-prefer-nft_chain_validate.patch drm-i915-gem-fix-virtual-memory-mapping-boundaries-calculation.patch arm64-cpufeature-fix-the-visibility-of-compat-hwcaps.patch media-uvcvideo-use-entity-get_cur-in-uvc_ctrl_set.patch +exec-fix-toctou-between-perm-check-and-set-uid-gid-usage.patch