diff --git a/debian/changelog b/debian/changelog index bd599b5e4..0ce8d663b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,8 @@ linux (4.19.98-1+deb10u1) UNRELEASED; urgency=medium * [x86] KVM: nVMX: Don't emulate instructions in guest mode (CVE-2020-2732) + * do_last(): fetch directory ->i_mode and ->i_uid before it's too late + (CVE-2020-8428) -- Salvatore Bonaccorso Sun, 26 Apr 2020 20:32:58 +0200 diff --git a/debian/patches/bugfix/all/do_last-fetch-directory-i_mode-and-i_uid-before-it-s.patch b/debian/patches/bugfix/all/do_last-fetch-directory-i_mode-and-i_uid-before-it-s.patch new file mode 100644 index 000000000..bce29b1ad --- /dev/null +++ b/debian/patches/bugfix/all/do_last-fetch-directory-i_mode-and-i_uid-before-it-s.patch @@ -0,0 +1,70 @@ +From: Al Viro +Date: Sun, 26 Jan 2020 09:29:34 -0500 +Subject: do_last(): fetch directory ->i_mode and ->i_uid before it's too late +Origin: https://git.kernel.org/linus/d0cb50185ae942b03c4327be322055d622dc79f6 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2020-8428 + +may_create_in_sticky() call is done when we already have dropped the +reference to dir. + +Fixes: 30aba6656f61e (namei: allow restricted O_CREAT of FIFOs and regular files) +Signed-off-by: Al Viro +[Salvatore Bonaccorso: Backport to 4.19.98 for context changes] +--- + fs/namei.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -1009,7 +1009,8 @@ static int may_linkat(struct path *link) + * may_create_in_sticky - Check whether an O_CREAT open in a sticky directory + * should be allowed, or not, on files that already + * exist. +- * @dir: the sticky parent directory ++ * @dir_mode: mode bits of directory ++ * @dir_uid: owner of directory + * @inode: the inode of the file to open + * + * Block an O_CREAT open of a FIFO (or a regular file) when: +@@ -1025,18 +1026,18 @@ static int may_linkat(struct path *link) + * + * Returns 0 if the open is allowed, -ve on error. + */ +-static int may_create_in_sticky(struct dentry * const dir, ++static int may_create_in_sticky(umode_t dir_mode, kuid_t dir_uid, + struct inode * const inode) + { + if ((!sysctl_protected_fifos && S_ISFIFO(inode->i_mode)) || + (!sysctl_protected_regular && S_ISREG(inode->i_mode)) || +- likely(!(dir->d_inode->i_mode & S_ISVTX)) || +- uid_eq(inode->i_uid, dir->d_inode->i_uid) || ++ likely(!(dir_mode & S_ISVTX)) || ++ uid_eq(inode->i_uid, dir_uid) || + uid_eq(current_fsuid(), inode->i_uid)) + return 0; + +- if (likely(dir->d_inode->i_mode & 0002) || +- (dir->d_inode->i_mode & 0020 && ++ if (likely(dir_mode & 0002) || ++ (dir_mode & 0020 && + ((sysctl_protected_fifos >= 2 && S_ISFIFO(inode->i_mode)) || + (sysctl_protected_regular >= 2 && S_ISREG(inode->i_mode))))) { + return -EACCES; +@@ -3258,6 +3259,8 @@ static int do_last(struct nameidata *nd, + struct file *file, const struct open_flags *op) + { + struct dentry *dir = nd->path.dentry; ++ kuid_t dir_uid = dir->d_inode->i_uid; ++ umode_t dir_mode = dir->d_inode->i_mode; + int open_flag = op->open_flag; + bool will_truncate = (open_flag & O_TRUNC) != 0; + bool got_write = false; +@@ -3393,7 +3396,7 @@ finish_open: + error = -EISDIR; + if (d_is_dir(nd->path.dentry)) + goto out; +- error = may_create_in_sticky(dir, ++ error = may_create_in_sticky(dir_mode, dir_uid, + d_backing_inode(nd->path.dentry)); + if (unlikely(error)) + goto out; diff --git a/debian/patches/series b/debian/patches/series index 2a903f935..adb75e895 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -305,6 +305,7 @@ bugfix/all/libertas-fix-two-buffer-overflows-at-parsing-bss-descriptor.patch bugfix/all/wimax-i2400-fix-memory-leak.patch bugfix/all/wimax-i2400-fix-memory-leak-in-i2400m_op_rfkill_sw_toggle.patch bugfix/x86/KVM-nVMX-Don-t-emulate-instructions-in-guest-mode.patch +bugfix/all/do_last-fetch-directory-i_mode-and-i_uid-before-it-s.patch # Backported change to provide boot-time entropy bugfix/all/random-try-to-actively-add-entropy-rather-than-passi.patch