diff options
author | Amir Goldstein <amir73il@gmail.com> | 2019-06-19 12:34:44 +0200 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2019-06-19 15:53:58 +0200 |
commit | c285a2f01d692ef48d7243cf1072897bbd237407 (patch) | |
tree | d6959488584787c33c90c971805e48920831289f /fs/notify/mark.c | |
parent | quota: fix a problem about transfer quota (diff) | |
download | linux-c285a2f01d692ef48d7243cf1072897bbd237407.tar.xz linux-c285a2f01d692ef48d7243cf1072897bbd237407.zip |
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: 77115225acc6 ("fanotify: cache fsid in fsnotify_mark_connector")
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/notify/mark.c')
-rw-r--r-- | fs/notify/mark.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/fs/notify/mark.c b/fs/notify/mark.c index 25eb247ea85a..99ddd126f6f0 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c @@ -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 @@ restart: 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])) { /* |