fs/namespace.c: fix use-after-free of mount in mnt_warn_timestamp_expiry()
authorEric Biggers <ebiggers@google.com>
Thu, 17 Oct 2019 02:48:14 +0000 (19:48 -0700)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 17 Oct 2019 03:15:09 +0000 (23:15 -0400)
After do_add_mount() returns success, the caller doesn't hold a
reference to the 'struct mount' anymore.  So it's invalid to access it
in mnt_warn_timestamp_expiry().

Fix it by calling mnt_warn_timestamp_expiry() before do_add_mount()
rather than after, and adjusting the warning message accordingly.

Reported-by: syzbot+da4f525235510683d855@syzkaller.appspotmail.com
Fixes: f8b92ba67c5d ("mount: Add mount warning for impending timestamp expiry")
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/namespace.c

index fe0e9e1..2adfe7b 100644 (file)
@@ -2478,8 +2478,10 @@ static void mnt_warn_timestamp_expiry(struct path *mountpoint, struct vfsmount *
 
                time64_to_tm(sb->s_time_max, 0, &tm);
 
-               pr_warn("Mounted %s file system at %s supports timestamps until %04ld (0x%llx)\n",
-                       sb->s_type->name, mntpath,
+               pr_warn("%s filesystem being %s at %s supports timestamps until %04ld (0x%llx)\n",
+                       sb->s_type->name,
+                       is_mounted(mnt) ? "remounted" : "mounted",
+                       mntpath,
                        tm.tm_year+1900, (unsigned long long)sb->s_time_max);
 
                free_page((unsigned long)buf);
@@ -2764,14 +2766,11 @@ static int do_new_mount_fc(struct fs_context *fc, struct path *mountpoint,
        if (IS_ERR(mnt))
                return PTR_ERR(mnt);
 
-       error = do_add_mount(real_mount(mnt), mountpoint, mnt_flags);
-       if (error < 0) {
-               mntput(mnt);
-               return error;
-       }
-
        mnt_warn_timestamp_expiry(mountpoint, mnt);
 
+       error = do_add_mount(real_mount(mnt), mountpoint, mnt_flags);
+       if (error < 0)
+               mntput(mnt);
        return error;
 }