fs/namespace.c: fix use-after-free of mount in mnt_warn_timestamp_expiry()

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: f8b92ba67c ("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>
This commit is contained in:
Eric Biggers 2019-10-16 19:48:14 -07:00 коммит произвёл Al Viro
Родитель 4f5cafb5cb
Коммит 0ecee66990
1 изменённых файлов: 7 добавлений и 8 удалений

Просмотреть файл

@ -2478,8 +2478,10 @@ static void mnt_warn_timestamp_expiry(struct path *mountpoint, struct vfsmount *
time64_to_tm(sb->s_time_max, 0, &tm); time64_to_tm(sb->s_time_max, 0, &tm);
pr_warn("Mounted %s file system at %s supports timestamps until %04ld (0x%llx)\n", pr_warn("%s filesystem being %s at %s supports timestamps until %04ld (0x%llx)\n",
sb->s_type->name, mntpath, sb->s_type->name,
is_mounted(mnt) ? "remounted" : "mounted",
mntpath,
tm.tm_year+1900, (unsigned long long)sb->s_time_max); tm.tm_year+1900, (unsigned long long)sb->s_time_max);
free_page((unsigned long)buf); 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)) if (IS_ERR(mnt))
return PTR_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); mnt_warn_timestamp_expiry(mountpoint, mnt);
error = do_add_mount(real_mount(mnt), mountpoint, mnt_flags);
if (error < 0)
mntput(mnt);
return error; return error;
} }