From: David Howells <dhowells@redhat.com>
To: netdev@vger.kernel.org
Cc: David Howells <dhowells@redhat.com>,
Marc Dionne <marc.dionne@auristor.com>,
Jakub Kicinski <kuba@kernel.org>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Paolo Abeni <pabeni@redhat.com>, Simon Horman <horms@kernel.org>,
linux-afs@lists.infradead.org, linux-kernel@vger.kernel.org,
Jeffrey Altman <jaltman@auristor.com>,
stable@kernel.org
Subject: [PATCH net v2 03/16] afs: Fix UAF when sending a message
Date: Fri, 10 Jul 2026 20:22:05 +0100 [thread overview]
Message-ID: <20260710192220.1922433-4-dhowells@redhat.com> (raw)
In-Reply-To: <20260710192220.1922433-1-dhowells@redhat.com>
In afs_make_call(), there's a race with async call reception and
destruction. If a call is dispatched that doesn't have call->write_iter
set (used to specify the data content for FS.StoreData), then the first
rxrpc_kernel_send_data() will not set MSG_MORE in the msghdr.
Once rxrpc_send_data() queues the last request packet, the response could
come in at any time and cause the call to be completed and put. However,
afs_make_call() will look at the call again to see it ->write_iter should
be handled - something it's only allowed to do if it has its own ref on the
call. Whilst this is the case for synchronous calls, it isn't true for
async calls such as FS.FetchData.
generic/650 plays games with randomly taking CPUs offline, and can
interject a significant delay such that the call is deallocated before
afs_make_call() gets to check call->write_iter - and a UAF ensues (caught
by KASAN).
BUG: KASAN: slab-use-after-free in afs_make_call+0x1c90/0x2210 [kafs]
Read of size 8 at addr ffff888035e050e8 by task fsstress/1409
Fix this by caching the call->write_iter and call->debug_id so that neither
variable needs to be accessed after the first send.
Fixes: eddf51f2bb2c ("afs: Make {Y,}FS.FetchData an asynchronous operation")
Reported-by: Marc Dionne <marc.dionne@auristor.com>
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Jeffrey Altman <jaltman@auristor.com>
cc: Eric Dumazet <edumazet@google.com>
cc: "David S. Miller" <davem@davemloft.net>
cc: Jakub Kicinski <kuba@kernel.org>
cc: Paolo Abeni <pabeni@redhat.com>
cc: Simon Horman <horms@kernel.org>
cc: linux-afs@lists.infradead.org
cc: stable@kernel.org
---
fs/afs/rxrpc.c | 12 ++++++++----
include/trace/events/afs.h | 6 +++---
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c
index d82916657a3d..06c711c75f55 100644
--- a/fs/afs/rxrpc.c
+++ b/fs/afs/rxrpc.c
@@ -347,7 +347,9 @@ void afs_make_call(struct afs_call *call, gfp_t gfp)
struct rxrpc_call *rxcall;
struct msghdr msg;
struct kvec iov[1];
+ unsigned int debug_id = call->debug_id;
size_t len;
+ bool write_iter = call->write_iter;
s64 tx_total_len;
int ret;
@@ -410,7 +412,7 @@ void afs_make_call(struct afs_call *call, gfp_t gfp)
iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, iov, 1, call->request_size);
msg.msg_control = NULL;
msg.msg_controllen = 0;
- msg.msg_flags = MSG_WAITALL | (call->write_iter ? MSG_MORE : 0);
+ msg.msg_flags = MSG_WAITALL | (write_iter ? MSG_MORE : 0);
ret = rxrpc_kernel_send_data(call->net->socket, rxcall,
&msg, call->request_size,
@@ -418,7 +420,9 @@ void afs_make_call(struct afs_call *call, gfp_t gfp)
if (ret < 0)
goto error_do_abort;
- if (call->write_iter) {
+ /* We lost our ref on call if MSG_MORE was not set and ret >= 0. */
+
+ if (write_iter) {
msg.msg_iter = *call->write_iter;
msg.msg_flags &= ~MSG_MORE;
trace_afs_send_data(call, &msg);
@@ -427,9 +431,9 @@ void afs_make_call(struct afs_call *call, gfp_t gfp)
call->rxcall, &msg,
iov_iter_count(&msg.msg_iter),
afs_notify_end_request_tx);
- *call->write_iter = msg.msg_iter;
+ /* We lost our ref on call if ret >= 0. */
- trace_afs_sent_data(call, &msg, ret);
+ trace_afs_sent_data(debug_id, &msg, ret);
if (ret < 0)
goto error_do_abort;
}
diff --git a/include/trace/events/afs.h b/include/trace/events/afs.h
index 1b3c48b5591d..cf7218efb861 100644
--- a/include/trace/events/afs.h
+++ b/include/trace/events/afs.h
@@ -937,9 +937,9 @@ TRACE_EVENT(afs_send_data,
);
TRACE_EVENT(afs_sent_data,
- TP_PROTO(struct afs_call *call, struct msghdr *msg, int ret),
+ TP_PROTO(unsigned int call_debug_id, struct msghdr *msg, int ret),
- TP_ARGS(call, msg, ret),
+ TP_ARGS(call_debug_id, msg, ret),
TP_STRUCT__entry(
__field(unsigned int, call)
@@ -949,7 +949,7 @@ TRACE_EVENT(afs_sent_data,
),
TP_fast_assign(
- __entry->call = call->debug_id;
+ __entry->call = call_debug_id;
__entry->ret = ret;
__entry->offset = msg->msg_iter.xarray_start + msg->msg_iter.iov_offset;
__entry->count = iov_iter_count(&msg->msg_iter);
next prev parent reply other threads:[~2026-07-10 19:22 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-10 19:22 [PATCH net v2 00/16] rxrpc: Fix CHALLENGE packet handling David Howells
2026-07-10 19:22 ` [PATCH net v2 01/16] afs: Fix NULL deref in afs_deliver_cb_init_call_back_state3() David Howells
2026-07-10 19:22 ` [PATCH net v2 02/16] rxrpc: Fix sendmsg to not return an error if last packet queued David Howells
2026-07-10 19:22 ` David Howells [this message]
2026-07-10 19:22 ` [PATCH net v2 04/16] afs: Fix two delivery functions to pass back -EAGAIN David Howells
2026-07-10 19:22 ` [PATCH net v2 05/16] afs: Fix afs_fs_fetch_data() to set call->async David Howells
2026-07-10 19:22 ` [PATCH net v2 06/16] rxrpc: Fix packet encryption error handling David Howells
2026-07-10 19:22 ` [PATCH net v2 07/16] rxrpc: Fix update of call->tx_pending without holding lock David Howells
2026-07-10 19:22 ` [PATCH net v2 08/16] rxrpc: Fix generation of notifications after call completion David Howells
2026-07-10 19:22 ` [PATCH net v2 09/16] afs: Simplify call refcounting David Howells
2026-07-10 19:22 ` [PATCH net v2 10/16] afs: Make afs_put_call() take trace argument David Howells
2026-07-10 19:22 ` [PATCH net v2 11/16] afs: Fix UAF in afs_make_call() David Howells
2026-07-10 19:22 ` [PATCH net v2 12/16] keys: Add refcounting to user-defined key type payload David Howells
2026-07-10 19:22 ` [PATCH net v2 13/16] afs: Create a server appdata key David Howells
2026-07-10 19:22 ` [PATCH net v2 14/16] rxrpc: Pass appdata key to rxrpc_call and thence to rxrpc_bundle David Howells
2026-07-10 19:22 ` [PATCH net v2 15/16] rxrpc: Fix CHALLENGE packet overqueuing and simplify RESPONSE generation David Howells
2026-07-10 19:22 ` [PATCH net v2 16/16] rxrpc: Remove OOB challenge/response code David Howells
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260710192220.1922433-4-dhowells@redhat.com \
--to=dhowells@redhat.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=jaltman@auristor.com \
--cc=kuba@kernel.org \
--cc=linux-afs@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=marc.dionne@auristor.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=stable@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox