fscache: Fix oops due to race with cookie_lru and use_cookie
authorDave Wysochanski <dwysocha@redhat.com>
Wed, 7 Dec 2022 13:49:15 +0000 (13:49 +0000)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 7 Dec 2022 19:49:18 +0000 (11:49 -0800)
commitb5b52de3214a29911f949459a79f6640969b5487
tree5588d71fd73c31833b67d712bea8db119151b72d
parent098e5edc5d048a8df8691fd9fde895af100be42b
fscache: Fix oops due to race with cookie_lru and use_cookie

If a cookie expires from the LRU and the LRU_DISCARD flag is set, but
the state machine has not run yet, it's possible another thread can call
fscache_use_cookie and begin to use it.

When the cookie_worker finally runs, it will see the LRU_DISCARD flag
set, transition the cookie->state to LRU_DISCARDING, which will then
withdraw the cookie.  Once the cookie is withdrawn the object is removed
the below oops will occur because the object associated with the cookie
is now NULL.

Fix the oops by clearing the LRU_DISCARD bit if another thread uses the
cookie before the cookie_worker runs.

  BUG: kernel NULL pointer dereference, address: 0000000000000008
  ...
  CPU: 31 PID: 44773 Comm: kworker/u130:1 Tainted: G     E    6.0.0-5.dneg.x86_64 #1
  Hardware name: Google Compute Engine/Google Compute Engine, BIOS Google 08/26/2022
  Workqueue: events_unbound netfs_rreq_write_to_cache_work [netfs]
  RIP: 0010:cachefiles_prepare_write+0x28/0x90 [cachefiles]
  ...
  Call Trace:
    netfs_rreq_write_to_cache_work+0x11c/0x320 [netfs]
    process_one_work+0x217/0x3e0
    worker_thread+0x4a/0x3b0
    kthread+0xd6/0x100

Fixes: 12bb21a29c19 ("fscache: Implement cookie user counting and resource pinning")
Reported-by: Daire Byrne <daire.byrne@gmail.com>
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Tested-by: Daire Byrne <daire@dneg.com>
Link: https://lore.kernel.org/r/20221117115023.1350181-1-dwysocha@redhat.com/
Link: https://lore.kernel.org/r/20221117142915.1366990-1-dwysocha@redhat.com/
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/fscache/cookie.c
include/trace/events/fscache.h