aboutsummaryrefslogtreecommitdiffstats
path: root/fs/pnode.h
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2020-10-31 21:40:21 -0700
committerAl Viro <viro@zeniv.linux.org.uk>2020-12-10 17:33:17 -0500
commitedf7ddbf1c5eb98b720b063b73e20e8a4a1ce673 (patch)
tree5321f8cfe08651844642d27d217b012701f0dbc3 /fs/pnode.h
parentLinux 5.10-rc6 (diff)
downloadlinux-dev-edf7ddbf1c5eb98b720b063b73e20e8a4a1ce673.tar.xz
linux-dev-edf7ddbf1c5eb98b720b063b73e20e8a4a1ce673.zip
fs/namespace.c: WARN if mnt_count has become negative
Missing calls to mntget() (or equivalently, too many calls to mntput()) are hard to detect because mntput() delays freeing mounts using task_work_add(), then again using call_rcu(). As a result, mnt_count can often be decremented to -1 without getting a KASAN use-after-free report. Such cases are still bugs though, and they point to real use-after-frees being possible. For an example of this, see the bug fixed by commit 1b0b9cc8d379 ("vfs: fsmount: add missing mntget()"), discussed at https://lkml.kernel.org/linux-fsdevel/20190605135401.GB30925@xxxxxxxxxxxxxxxxxxxxxxxxx/T/#u. This bug *should* have been trivial to find. But actually, it wasn't found until syzkaller happened to use fchdir() to manipulate the reference count just right for the bug to be noticeable. Address this by making mntput_no_expire() issue a WARN if mnt_count has become negative. Suggested-by: Miklos Szeredi <miklos@szeredi.hu> Signed-off-by: Eric Biggers <ebiggers@google.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/pnode.h')
-rw-r--r--fs/pnode.h2
1 files changed, 1 insertions, 1 deletions
diff --git a/fs/pnode.h b/fs/pnode.h
index 49a058c73e4c..26f74e092bd9 100644
--- a/fs/pnode.h
+++ b/fs/pnode.h
@@ -44,7 +44,7 @@ int propagate_mount_busy(struct mount *, int);
void propagate_mount_unlock(struct mount *);
void mnt_release_group_id(struct mount *);
int get_dominating_id(struct mount *mnt, const struct path *root);
-unsigned int mnt_get_count(struct mount *mnt);
+int mnt_get_count(struct mount *mnt);
void mnt_set_mountpoint(struct mount *, struct mountpoint *,
struct mount *);
void mnt_change_mountpoint(struct mount *parent, struct mountpoint *mp,