• Linus Torvalds's avatar
    watch_queue: Fix missing locking in add_watch_to_object() · e64ab2db
    Linus Torvalds authored
    If a watch is being added to a queue, it needs to guard against
    interference from addition of a new watch, manual removal of a watch and
    removal of a watch due to some other queue being destroyed.
    
    KEYCTL_WATCH_KEY guards against this for the same {key,queue} pair by
    holding the key->sem writelocked and by holding refs on both the key and
    the queue - but that doesn't prevent interaction from other {key,queue}
    pairs.
    
    While add_watch_to_object() does take the spinlock on the event queue,
    it doesn't take the lock on the source's watch list.  The assumption was
    that the caller would prevent that (say by taking key->sem) - but that
    doesn't prevent interference from the destruction of another queue.
    
    Fix this by locking the watcher list in add_watch_to_object().
    
    Fixes: c73be61c ("pipe: Add general notification queue support")
    Reported-by: syzbot+03d7b43290037d1f87ca@syzkaller.appspotmail.com
    Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    cc: keyrings@vger.kernel.org
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    e64ab2db
watch_queue.c 17.2 KB