From 3547448d2fd86248c11d256e4ae4f02adea67d47 Mon Sep 17 00:00:00 2001 From: Sona Sarmadi Date: Wed, 19 Sep 2018 12:48:03 +0200 Subject: linux-intel-rt: Fix for CVE-2018-13093 References: https://github.com/nluedtke/linux_kernel_cves/blob/master/4.14/4.14_security.txt https://nvd.nist.gov/vuln/detail/CVE-2018-13093 Change-Id: Ib4fb2a6efdbd4e47527618aaeb9151aeb2ec9738 Signed-off-by: Sona Sarmadi --- recipes-kernel/linux/linux-intel-rt_4.14.bbappend | 1 + .../linux/linux-intel/CVE-2018-13093.patch | 148 +++++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 recipes-kernel/linux/linux-intel/CVE-2018-13093.patch diff --git a/recipes-kernel/linux/linux-intel-rt_4.14.bbappend b/recipes-kernel/linux/linux-intel-rt_4.14.bbappend index 5578c7b..67e9661 100644 --- a/recipes-kernel/linux/linux-intel-rt_4.14.bbappend +++ b/recipes-kernel/linux/linux-intel-rt_4.14.bbappend @@ -8,6 +8,7 @@ KENEABRANCH = "intel-4.14" SRC_URI_append = " git://git@git.enea.com/linux/enea-kernel-cache.git;protocol=ssh;type=kmeta;name=metaenea;branch=${KENEABRANCH};destsuffix=enea-kernel-meta \ file://CVE-2018-14734.patch \ file://CVE-2018-12233.patch \ + file://CVE-2018-13093.patch \ " # Debug tools support diff --git a/recipes-kernel/linux/linux-intel/CVE-2018-13093.patch b/recipes-kernel/linux/linux-intel/CVE-2018-13093.patch new file mode 100644 index 0000000..87b53c3 --- /dev/null +++ b/recipes-kernel/linux/linux-intel/CVE-2018-13093.patch @@ -0,0 +1,148 @@ +From c2ae72c4e543148cfb4232617815942f3ad1d37a Mon Sep 17 00:00:00 2001 +From: Dave Chinner +Date: Fri, 23 Mar 2018 10:22:53 -0700 +Subject: [PATCH] xfs: validate cached inodes are free when allocated + +commit afca6c5b2595fc44383919fba740c194b0b76aff upstream. + +A recent fuzzed filesystem image cached random dcache corruption +when the reproducer was run. This often showed up as panics in +lookup_slow() on a null inode->i_ops pointer when doing pathwalks. + +BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 +.... +Call Trace: + lookup_slow+0x44/0x60 + walk_component+0x3dd/0x9f0 + link_path_walk+0x4a7/0x830 + path_lookupat+0xc1/0x470 + filename_lookup+0x129/0x270 + user_path_at_empty+0x36/0x40 + path_listxattr+0x98/0x110 + SyS_listxattr+0x13/0x20 + do_syscall_64+0xf5/0x280 + entry_SYSCALL_64_after_hwframe+0x42/0xb7 + +but had many different failure modes including deadlocks trying to +lock the inode that was just allocated or KASAN reports of +use-after-free violations. + +The cause of the problem was a corrupt INOBT on a v4 fs where the +root inode was marked as free in the inobt record. Hence when we +allocated an inode, it chose the root inode to allocate, found it in +the cache and re-initialised it. + +We recently fixed a similar inode allocation issue caused by inobt +record corruption problem in xfs_iget_cache_miss() in commit +ee457001ed6c ("xfs: catch inode allocation state mismatch +corruption"). This change adds similar checks to the cache-hit path +to catch it, and turns the reproducer into a corruption shutdown +situation. + +CVE: CVE-2018-13093 +Upstream-Status: Backport + +Reported-by: Wen Xu +Signed-Off-By: Dave Chinner +Reviewed-by: Christoph Hellwig +Reviewed-by: Carlos Maiolino +Reviewed-by: Darrick J. Wong +[darrick: fix typos in comment] +Signed-off-by: Darrick J. Wong +Cc: Eduardo Valentin +Signed-off-by: Greg Kroah-Hartman + +Signed-off-by: Sona Sarmadi +--- + fs/xfs/xfs_icache.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 51 insertions(+), 7 deletions(-) + +diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c +index 43005fb..544b521 100644 +--- a/fs/xfs/xfs_icache.c ++++ b/fs/xfs/xfs_icache.c +@@ -306,6 +306,46 @@ struct xfs_inode * + } + + /* ++ * If we are allocating a new inode, then check what was returned is ++ * actually a free, empty inode. If we are not allocating an inode, ++ * then check we didn't find a free inode. ++ * ++ * Returns: ++ * 0 if the inode free state matches the lookup context ++ * -ENOENT if the inode is free and we are not allocating ++ * -EFSCORRUPTED if there is any state mismatch at all ++ */ ++static int ++xfs_iget_check_free_state( ++ struct xfs_inode *ip, ++ int flags) ++{ ++ if (flags & XFS_IGET_CREATE) { ++ /* should be a free inode */ ++ if (VFS_I(ip)->i_mode != 0) { ++ xfs_warn(ip->i_mount, ++"Corruption detected! Free inode 0x%llx not marked free! (mode 0x%x)", ++ ip->i_ino, VFS_I(ip)->i_mode); ++ return -EFSCORRUPTED; ++ } ++ ++ if (ip->i_d.di_nblocks != 0) { ++ xfs_warn(ip->i_mount, ++"Corruption detected! Free inode 0x%llx has blocks allocated!", ++ ip->i_ino); ++ return -EFSCORRUPTED; ++ } ++ return 0; ++ } ++ ++ /* should be an allocated inode */ ++ if (VFS_I(ip)->i_mode == 0) ++ return -ENOENT; ++ ++ return 0; ++} ++ ++/* + * Check the validity of the inode we just found it the cache + */ + static int +@@ -354,12 +394,12 @@ struct xfs_inode * + } + + /* +- * If lookup is racing with unlink return an error immediately. ++ * Check the inode free state is valid. This also detects lookup ++ * racing with unlinks. + */ +- if (VFS_I(ip)->i_mode == 0 && !(flags & XFS_IGET_CREATE)) { +- error = -ENOENT; ++ error = xfs_iget_check_free_state(ip, flags); ++ if (error) + goto out_error; +- } + + /* + * If IRECLAIMABLE is set, we've torn down the VFS inode already. +@@ -475,10 +515,14 @@ struct xfs_inode * + + trace_xfs_iget_miss(ip); + +- if ((VFS_I(ip)->i_mode == 0) && !(flags & XFS_IGET_CREATE)) { +- error = -ENOENT; ++ ++ /* ++ * Check the inode free state is valid. This also detects lookup ++ * racing with unlinks. ++ */ ++ error = xfs_iget_check_free_state(ip, flags); ++ if (error) + goto out_destroy; +- } + + /* + * Preload the radix tree so we can insert safely under the +-- +1.9.1 + -- cgit v1.2.3-54-g00ecf