forked from luck/tmp_suning_uos_patched
fanotify: update connector fsid cache on add mark
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: 77115225ac
("fanotify: cache fsid in fsnotify_mark_connector")
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
This commit is contained in:
parent
c6d9c35d16
commit
c285a2f01d
|
@ -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;
|
||||
|
|
|
@ -482,10 +482,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));
|
||||
/*
|
||||
|
@ -560,7 +563,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] */
|
||||
|
|
Loading…
Reference in New Issue
Block a user