Merge patch series "afs: Miscellaneous fixes"

David Howells <dhowells@redhat.com> says:

(1) Fix afs_fs_fetch_data() to set call->async.

(2) Fix afs_fs_fetch_data() to subtract transferred from len instead of
    adding it.

(3) Fix a UAF when sending a message if the call is completed so quickly
    that the sending code hasn't finished with it when it gets freed.

* patches from https://patch.msgid.link/20260723113452.566619-1-dhowells@redhat.com:
  afs: Fix UAF when sending a message
  afs: Fix afs_fs_fetch_data() to subtract transferred from len
  afs: Fix afs_fs_fetch_data() to set call->async

Link: https://patch.msgid.link/20260723113452.566619-1-dhowells@redhat.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
This commit is contained in:
Christian Brauner 2026-07-28 09:20:47 +02:00
commit 2c1766964c
No known key found for this signature in database
GPG Key ID: 91C61BC06578DCA2
2 changed files with 6 additions and 2 deletions

View File

@ -477,6 +477,9 @@ void afs_fs_fetch_data(struct afs_operation *op)
if (!call)
return afs_op_nomem(op);
if (op->flags & AFS_OPERATION_ASYNC)
call->async = true;
/* marshall the parameters */
bp = call->request;
bp[0] = htonl(FSFETCHDATA);
@ -484,7 +487,7 @@ void afs_fs_fetch_data(struct afs_operation *op)
bp[2] = htonl(vp->fid.vnode);
bp[3] = htonl(vp->fid.unique);
bp[4] = htonl(lower_32_bits(subreq->start + subreq->transferred));
bp[5] = htonl(lower_32_bits(subreq->len + subreq->transferred));
bp[5] = htonl(lower_32_bits(subreq->len - subreq->transferred));
call->fid = vp->fid;
trace_afs_make_fs_call(call, &vp->fid);

View File

@ -1421,7 +1421,7 @@ static inline void afs_make_op_call(struct afs_operation *op, struct afs_call *c
{
struct afs_addr_list *alist = op->estate->addresses;
op->call = call;
op->call = afs_get_call(call, afs_call_trace_get);
op->type = call->type;
call->op = op;
call->key = op->key;
@ -1429,6 +1429,7 @@ static inline void afs_make_op_call(struct afs_operation *op, struct afs_call *c
call->peer = rxrpc_kernel_get_peer(alist->addrs[op->addr_index].peer);
call->service_id = op->server->service_id;
afs_make_call(call, gfp);
afs_put_call(call);
}
static inline void afs_extract_begin(struct afs_call *call, void *buf, size_t size)