]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
afs: Fix uncancelled rxrpc OOB message handler
authorDavid Howells <dhowells@redhat.com>
Wed, 24 Jun 2026 16:38:12 +0000 (17:38 +0100)
committerJakub Kicinski <kuba@kernel.org>
Thu, 25 Jun 2026 17:07:18 +0000 (10:07 -0700)
Fix AFS to cancel its OOB message processing (typically to respond to
security challenges).  Also move OOB message processing to afs_wq so that
it's also waited for and make the OOB handler just return if the net
namespace is no longer live.

Fixes: 5800b1cf3fd8 ("rxrpc: Allow CHALLENGEs to the passed to the app for a RESPONSE")
Link: https://sashiko.dev/#/patchset/20260609140911.838677-1-dhowells%40redhat.com
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Li Daming <d4n.for.sec@gmail.com>
cc: Ren Wei <n05ec@lzu.edu.cn>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: Jeffrey Altman <jaltman@auristor.com>
cc: Simon Horman <horms@kernel.org>
cc: linux-afs@lists.infradead.org
cc: stable@kernel.org
Link: https://patch.msgid.link/20260624163819.3017002-6-dhowells@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
fs/afs/cm_security.c
fs/afs/rxrpc.c

index edcbd249d2024aacfad8e5a1a4840d336911cc47..103168c70dd4df6a056b5f3d90ef1dc12e6f9d50 100644 (file)
@@ -101,7 +101,8 @@ void afs_process_oob_queue(struct work_struct *work)
        struct sk_buff *oob;
        enum rxrpc_oob_type type;
 
-       while ((oob = rxrpc_kernel_dequeue_oob(net->socket, &type))) {
+       while (READ_ONCE(net->live) &&
+              (oob = rxrpc_kernel_dequeue_oob(net->socket, &type))) {
                switch (type) {
                case RXRPC_OOB_CHALLENGE:
                        afs_respond_to_challenge(oob);
index 6714a189d58fbdc590dd394453768942df392e34..d82916657a3ddf6d899533742d17b51a2e889877 100644 (file)
@@ -128,6 +128,7 @@ void afs_close_socket(struct afs_net *net)
        _enter("");
 
        cancel_work_sync(&net->charge_preallocation_work);
+       cancel_work_sync(&net->rx_oob_work);
        /* Future work items should now see ->live is false. */
 
        kernel_listen(net->socket, 0);
@@ -148,6 +149,7 @@ void afs_close_socket(struct afs_net *net)
 
        kernel_sock_shutdown(net->socket, SHUT_RDWR);
        flush_workqueue(afs_async_calls);
+       cancel_work_sync(&net->rx_oob_work);
        net->socket->sk->sk_user_data = NULL;
        sock_release(net->socket);
        key_put(net->fs_cm_token_key);
@@ -989,5 +991,6 @@ static void afs_rx_notify_oob(struct sock *sk, struct sk_buff *oob)
 {
        struct afs_net *net = sk->sk_user_data;
 
-       schedule_work(&net->rx_oob_work);
+       if (READ_ONCE(net->live))
+               queue_work(afs_wq, &net->rx_oob_work);
 }