]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commit
watch_queue: Fix missing locking in add_watch_to_object()
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 28 Jul 2022 09:31:12 +0000 (10:31 +0100)
committerStefan Bader <stefan.bader@canonical.com>
Fri, 16 Sep 2022 08:53:39 +0000 (10:53 +0200)
commit346f0743313e25f13e31eb546e4fa6469aa0d6f3
treeca5cb0f7f3503008238f5150820294a8117627b7
parent2d6a1c0c07b5d41122cc9fda302663b6d0455776
watch_queue: Fix missing locking in add_watch_to_object()

BugLink: https://bugs.launchpad.net/bugs/1989218
commit e64ab2dbd882933b65cd82ff6235d705ad65dbb6 upstream.

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: c73be61cede5 ("pipe: Add general notification queue support")
Reported-by: syzbot+03d7b43290037d1f87ca@syzkaller.appspotmail.com
Signed-off-by: David Howells <dhowells@redhat.com>
cc: keyrings@vger.kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
kernel/watch_queue.c