Patch "fs: fix NULL dereference due to data race in prepend_path()" has been added to the 5.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    fs: fix NULL dereference due to data race in prepend_path()

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     fs-fix-null-dereference-due-to-data-race-in-prepend_.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 1cb60beb7d6940a95e6c62af13ab9c95053e9e5f
Author: Andrii Nakryiko <andrii@xxxxxxxxxx>
Date:   Wed Oct 14 13:45:28 2020 -0700

    fs: fix NULL dereference due to data race in prepend_path()
    
    [ Upstream commit 09cad07547445bf3a41683e4d3abcd154c123ef5 ]
    
    Fix data race in prepend_path() with re-reading mnt->mnt_ns twice
    without holding the lock.
    
    is_mounted() does check for NULL, but is_anon_ns(mnt->mnt_ns) might
    re-read the pointer again which could be NULL already, if in between
    reads one of kern_unmount()/kern_unmount_array()/umount_tree() sets
    mnt->mnt_ns to NULL.
    
    This is seen in production with the following stack trace:
    
      BUG: kernel NULL pointer dereference, address: 0000000000000048
      ...
      RIP: 0010:prepend_path.isra.4+0x1ce/0x2e0
      Call Trace:
        d_path+0xe6/0x150
        proc_pid_readlink+0x8f/0x100
        vfs_readlink+0xf8/0x110
        do_readlinkat+0xfd/0x120
        __x64_sys_readlinkat+0x1a/0x20
        do_syscall_64+0x42/0x110
        entry_SYSCALL_64_after_hwframe+0x44/0xa9
    
    Fixes: f2683bd8d5bd ("[PATCH] fix d_absolute_path() interplay with fsmount()")
    Signed-off-by: Andrii Nakryiko <andrii@xxxxxxxxxx>
    Reviewed-by: Josef Bacik <josef@xxxxxxxxxxxxxx>
    Cc: Alexander Viro <viro@xxxxxxxxxxxxxxxxxx>
    Signed-off-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/fs/d_path.c b/fs/d_path.c
index 0f1fc1743302f..a69e2cd36e6e3 100644
--- a/fs/d_path.c
+++ b/fs/d_path.c
@@ -102,6 +102,8 @@ static int prepend_path(const struct path *path,
 
 		if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
 			struct mount *parent = READ_ONCE(mnt->mnt_parent);
+			struct mnt_namespace *mnt_ns;
+
 			/* Escaped? */
 			if (dentry != vfsmnt->mnt_root) {
 				bptr = *buffer;
@@ -116,7 +118,9 @@ static int prepend_path(const struct path *path,
 				vfsmnt = &mnt->mnt;
 				continue;
 			}
-			if (is_mounted(vfsmnt) && !is_anon_ns(mnt->mnt_ns))
+			mnt_ns = READ_ONCE(mnt->mnt_ns);
+			/* open-coded is_mounted() to use local mnt_ns */
+			if (!IS_ERR_OR_NULL(mnt_ns) && !is_anon_ns(mnt_ns))
 				error = 1;	// absolute root
 			else
 				error = 2;	// detached or not attached yet



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux