Commit b74063b5 authored by Amir Goldstein's avatar Amir Goldstein Committed by Greg Kroah-Hartman

fanotify: update connector fsid cache on add mark

commit c285a2f0 upstream.

When implementing connector fsid cache, we only initialized the cache
when the first mark added to object was added by FAN_REPORT_FID group.
We forgot to update conn->fsid when the second mark is added by
FAN_REPORT_FID group to an already attached connector without fsid
cache.

Reported-and-tested-by: syzbot+c277e8e2f46414645508@syzkaller.appspotmail.com
Fixes: 77115225 ("fanotify: cache fsid in fsnotify_mark_connector")
Signed-off-by: default avatarAmir Goldstein <amir73il@gmail.com>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 993a0821
......@@ -355,6 +355,10 @@ static __kernel_fsid_t fanotify_get_fsid(struct fsnotify_iter_info *iter_info)
/* Mark is just getting destroyed or created? */
if (!conn)
continue;
if (!(conn->flags & FSNOTIFY_CONN_FLAG_HAS_FSID))
continue;
/* Pairs with smp_wmb() in fsnotify_add_mark_list() */
smp_rmb();
fsid = conn->fsid;
if (WARN_ON_ONCE(!fsid.val[0] && !fsid.val[1]))
continue;
......
......@@ -495,10 +495,13 @@ static int fsnotify_attach_connector_to_object(fsnotify_connp_t *connp,
conn->type = type;
conn->obj = connp;
/* Cache fsid of filesystem containing the object */
if (fsid)
if (fsid) {
conn->fsid = *fsid;
else
conn->flags = FSNOTIFY_CONN_FLAG_HAS_FSID;
} else {
conn->fsid.val[0] = conn->fsid.val[1] = 0;
conn->flags = 0;
}
if (conn->type == FSNOTIFY_OBJ_TYPE_INODE)
inode = igrab(fsnotify_conn_inode(conn));
/*
......@@ -573,7 +576,12 @@ static int fsnotify_add_mark_list(struct fsnotify_mark *mark,
if (err)
return err;
goto restart;
} else if (fsid && (conn->fsid.val[0] || conn->fsid.val[1]) &&
} else if (fsid && !(conn->flags & FSNOTIFY_CONN_FLAG_HAS_FSID)) {
conn->fsid = *fsid;
/* Pairs with smp_rmb() in fanotify_get_fsid() */
smp_wmb();
conn->flags |= FSNOTIFY_CONN_FLAG_HAS_FSID;
} else if (fsid && (conn->flags & FSNOTIFY_CONN_FLAG_HAS_FSID) &&
(fsid->val[0] != conn->fsid.val[0] ||
fsid->val[1] != conn->fsid.val[1])) {
/*
......
......@@ -292,7 +292,9 @@ typedef struct fsnotify_mark_connector __rcu *fsnotify_connp_t;
*/
struct fsnotify_mark_connector {
spinlock_t lock;
unsigned int type; /* Type of object [lock] */
unsigned short type; /* Type of object [lock] */
#define FSNOTIFY_CONN_FLAG_HAS_FSID 0x01
unsigned short flags; /* flags [lock] */
__kernel_fsid_t fsid; /* fsid of filesystem containing object */
union {
/* Object pointer [lock] */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment