* [PATCH 1/7] afs: handle CB.InitCallBackState3 requests without a server record
2026-06-09 8:17 [PATCH 0/7] afs: Miscellaneous fixes David Howells
@ 2026-06-09 8:17 ` David Howells
2026-06-09 8:17 ` [PATCH 2/7] afs: Fix error code in afs_extract_vl_addrs() David Howells
` (5 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: David Howells @ 2026-06-09 8:17 UTC (permalink / raw)
To: Christian Brauner
Cc: David Howells, Marc Dionne, linux-afs, linux-fsdevel,
linux-kernel, Nan Li, stable, Yuan Tan, Yifan Wu, Juefei Pu,
Xin Liu, Ren Wei
From: Nan Li <tonanli66@gmail.com>
The cache manager callback path now attaches the server record to an
incoming call through the rxrpc peer's app data. That association is
not guaranteed to exist for every callback request, and most callback
handlers already tolerate that case.
Make CB.InitCallBackState3 follow the same pattern by checking whether a
server record was attached before using it. If the peer is not mapped
to a server record, trace the request and ignore it, matching the
existing behaviour for other unmatched callback requests.
This keeps the callback handler consistent with the rest of the cache
manager service and avoids depending on peer state that may not be
available for a given request.
Fixes: 40e8b52fe8c8 ("afs: Use the per-peer app data provided by rxrpc")
Cc: stable@kernel.org
Reported-by: Yuan Tan <yuantan098@gmail.com>
Reported-by: Yifan Wu <yifanwucs@gmail.com>
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
Reported-by: Xin Liu <bird@lzu.edu.cn>
Signed-off-by: Nan Li <tonanli66@gmail.com>
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
---
fs/afs/cmservice.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c
index 5540ae1cad59..263c60c811a5 100644
--- a/fs/afs/cmservice.c
+++ b/fs/afs/cmservice.c
@@ -364,6 +364,11 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
return afs_io_error(call, afs_io_error_cm_reply);
+ if (!call->server) {
+ trace_afs_cm_no_server_u(call, call->request);
+ return 0;
+ }
+
if (memcmp(call->request, &call->server->_uuid, sizeof(call->server->_uuid)) != 0) {
pr_notice("Callback UUID does not match fileserver UUID\n");
trace_afs_cm_no_server_u(call, call->request);
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 2/7] afs: Fix error code in afs_extract_vl_addrs()
2026-06-09 8:17 [PATCH 0/7] afs: Miscellaneous fixes David Howells
2026-06-09 8:17 ` [PATCH 1/7] afs: handle CB.InitCallBackState3 requests without a server record David Howells
@ 2026-06-09 8:17 ` David Howells
2026-06-09 8:17 ` [PATCH 3/7] afs: fix NULL pointer dereference in afs_get_tree() David Howells
` (4 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: David Howells @ 2026-06-09 8:17 UTC (permalink / raw)
To: Christian Brauner
Cc: David Howells, Marc Dionne, linux-afs, linux-fsdevel,
linux-kernel, Dan Carpenter
From: Dan Carpenter <error27@gmail.com>
The error codes on these paths are only set on the first iteration
through the loop. Set the correct error code on every iteration.
Fixes: 0a5143f2f89c ("afs: Implement VL server rotation")
Signed-off-by: Dan Carpenter <error27@gmail.com>
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
---
fs/afs/vl_list.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/afs/vl_list.c b/fs/afs/vl_list.c
index 3e4966915ea4..003889cf0f18 100644
--- a/fs/afs/vl_list.c
+++ b/fs/afs/vl_list.c
@@ -92,7 +92,7 @@ static struct afs_addr_list *afs_extract_vl_addrs(struct afs_net *net,
{
struct afs_addr_list *alist;
const u8 *b = *_b;
- int ret = -EINVAL;
+ int ret;
alist = afs_alloc_addrlist(nr_addrs);
if (!alist)
@@ -110,6 +110,7 @@ static struct afs_addr_list *afs_extract_vl_addrs(struct afs_net *net,
case DNS_ADDRESS_IS_IPV4:
if (end - b < 4) {
_leave(" = -EINVAL [short inet]");
+ ret = -EINVAL;
goto error;
}
memcpy(x, b, 4);
@@ -122,6 +123,7 @@ static struct afs_addr_list *afs_extract_vl_addrs(struct afs_net *net,
case DNS_ADDRESS_IS_IPV6:
if (end - b < 16) {
_leave(" = -EINVAL [short inet6]");
+ ret = -EINVAL;
goto error;
}
memcpy(x, b, 16);
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 3/7] afs: fix NULL pointer dereference in afs_get_tree()
2026-06-09 8:17 [PATCH 0/7] afs: Miscellaneous fixes David Howells
2026-06-09 8:17 ` [PATCH 1/7] afs: handle CB.InitCallBackState3 requests without a server record David Howells
2026-06-09 8:17 ` [PATCH 2/7] afs: Fix error code in afs_extract_vl_addrs() David Howells
@ 2026-06-09 8:17 ` David Howells
2026-06-09 8:17 ` [PATCH 4/7] afs: Remove setting of AS_RELEASE_ALWAYS for symlinks and mountpoints David Howells
` (3 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: David Howells @ 2026-06-09 8:17 UTC (permalink / raw)
To: Christian Brauner
Cc: David Howells, Marc Dionne, linux-afs, linux-fsdevel,
linux-kernel, Matvey Kovalev, stable
From: Matvey Kovalev <matvey.kovalev@ispras.ru>
afs_alloc_sbi() uses kzalloc for memory allocation. And, if
ctx->dyn_root is not null, as->cell and as->volume are null.
In trace_afs_get_tree() they are dereferenced.
KASAN error message:
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
CPU: 2 PID: 18478 Comm: syz-executor.7 Not tainted 5.10.246-syzkaller #0
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1
04/01/2014
RIP: 0010:perf_trace_afs_get_tree+0x1d9/0x550
include/trace/events/afs.h:1365
Call Trace:
trace_afs_get_tree include/trace/events/afs.h:1365 [inline]
afs_get_tree+0x922/0x1350 fs/afs/super.c:599
vfs_get_tree+0x8e/0x300 fs/super.c:1572
do_new_mount fs/namespace.c:3011 [inline]
path_mount+0x14a5/0x2220 fs/namespace.c:3341
do_mount fs/namespace.c:3354 [inline]
__do_sys_mount fs/namespace.c:3562 [inline]
__se_sys_mount fs/namespace.c:3539 [inline]
__x64_sys_mount+0x283/0x300 fs/namespace.c:3539
do_syscall_64+0x33/0x50 arch/x86/entry/common.c:46
entry_SYSCALL_64_after_hwframe+0x67/0xd1
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
Fixes: 80548b03991f5 ("afs: Add more tracepoints")
Cc: stable@vger.kernel.org
Signed-off-by: Matvey Kovalev <matvey.kovalev@ispras.ru>
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
---
fs/afs/super.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/afs/super.c b/fs/afs/super.c
index 942f3e9800d7..dec091e569c4 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -587,7 +587,8 @@ static int afs_get_tree(struct fs_context *fc)
}
fc->root = dget(sb->s_root);
- trace_afs_get_tree(as->cell, as->volume);
+ if (!ctx->dyn_root)
+ trace_afs_get_tree(as->cell, as->volume);
_leave(" = 0 [%p]", sb);
return 0;
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 4/7] afs: Remove setting of AS_RELEASE_ALWAYS for symlinks and mountpoints
2026-06-09 8:17 [PATCH 0/7] afs: Miscellaneous fixes David Howells
` (2 preceding siblings ...)
2026-06-09 8:17 ` [PATCH 3/7] afs: fix NULL pointer dereference in afs_get_tree() David Howells
@ 2026-06-09 8:17 ` David Howells
2026-06-09 8:17 ` [PATCH 5/7] afs: use kvfree() to free memory allocated by kvcalloc() David Howells
` (2 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: David Howells @ 2026-06-09 8:17 UTC (permalink / raw)
To: Christian Brauner
Cc: David Howells, Marc Dionne, linux-afs, linux-fsdevel,
linux-kernel, Deepakkumar Karn
Regular AFS files correctly use afs_file_aops which have release_folio
set as netfs_release_folio, so AS_RELEASE_ALWAYS is valid for them
when fscache is enabled (set via afs_vnode_set_cache()).
Symlinks and mountpoints in AFS use afs_dir_aops, which does not provide
a release_folio callback. However, afs_apply_status() unconditionally
calls mapping_set_release_always() for these.
In such case when memory management code attempts to release folios,
filemap_release_folio() checks folio_needs_release() which
returns true due to AS_RELEASE_ALWAYS being set. Since there is no
release_folio callback, it falls through to try_to_free_buffers(),
which at present expects buffer_heads to be not null. For symlinks
and mountpoints without buffer_heads, this causes pointer dereference.
Fixes: eae9e78951bb ("afs: Use netfslib for symlinks, allowing them to be cached")
Signed-off-by: Deepakkumar Karn <dkarn@redhat.com>
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
---
fs/afs/inode.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index 3f48458694ba..21ac098d03ef 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -126,7 +126,6 @@ static int afs_inode_init_from_status(struct afs_operation *op,
}
inode->i_mapping->a_ops = &afs_symlink_aops;
inode_nohighmem(inode);
- mapping_set_release_always(inode->i_mapping);
break;
default:
dump_vnode(vnode, op->file[0].vnode != vnode ? op->file[0].vnode : NULL);
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 5/7] afs: use kvfree() to free memory allocated by kvcalloc()
2026-06-09 8:17 [PATCH 0/7] afs: Miscellaneous fixes David Howells
` (3 preceding siblings ...)
2026-06-09 8:17 ` [PATCH 4/7] afs: Remove setting of AS_RELEASE_ALWAYS for symlinks and mountpoints David Howells
@ 2026-06-09 8:17 ` David Howells
2026-06-09 8:17 ` [PATCH 6/7] afs: Remove erroneous seq |= 1 in volume lookup loop David Howells
2026-06-09 8:17 ` [PATCH 7/7] afs: check for duplicate servers in VL server list David Howells
6 siblings, 0 replies; 11+ messages in thread
From: David Howells @ 2026-06-09 8:17 UTC (permalink / raw)
To: Christian Brauner
Cc: David Howells, Marc Dionne, linux-afs, linux-fsdevel,
linux-kernel, Zilin Guan
From: Zilin Guan <zilin@seu.edu.cn>
op->more_files is allocated with kvcalloc() but released via
afs_put_operation(), which uses kfree() internally. This mismach prevents
the resource from being released properly and may lead to undefined
behavior.
Fix this by using kvfree() to free op->more_files to match its allocation
method.
Fixes: e49c7b2f6de7 ("afs: Build an abstraction around an "operation" concept")
Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
---
fs/afs/fs_operation.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/afs/fs_operation.c b/fs/afs/fs_operation.c
index c0dbbc6d3716..20801b29521d 100644
--- a/fs/afs/fs_operation.c
+++ b/fs/afs/fs_operation.c
@@ -348,7 +348,7 @@ int afs_put_operation(struct afs_operation *op)
for (i = 0; i < op->nr_files - 2; i++)
if (op->more_files[i].put_vnode)
iput(&op->more_files[i].vnode->netfs.inode);
- kfree(op->more_files);
+ kvfree(op->more_files);
}
if (op->estate) {
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 6/7] afs: Remove erroneous seq |= 1 in volume lookup loop
2026-06-09 8:17 [PATCH 0/7] afs: Miscellaneous fixes David Howells
` (4 preceding siblings ...)
2026-06-09 8:17 ` [PATCH 5/7] afs: use kvfree() to free memory allocated by kvcalloc() David Howells
@ 2026-06-09 8:17 ` David Howells
2026-06-09 9:18 ` Oleg Nesterov
2026-06-09 8:17 ` [PATCH 7/7] afs: check for duplicate servers in VL server list David Howells
6 siblings, 1 reply; 11+ messages in thread
From: David Howells @ 2026-06-09 8:17 UTC (permalink / raw)
To: Christian Brauner
Cc: David Howells, Marc Dionne, linux-afs, linux-fsdevel,
linux-kernel, Li RongQing, Oleg Nesterov
From: Li RongQing <lirongqing@baidu.com>
The `seq |= 1` operation in the volume lookup loop is incorrect because:
seq is already incremented at start, making it odd in next iteration
which triggers lock, but The `|= 1` operation causes seq to be even
and unintended lockless operation
Remove this erroneous operation to maintain proper lock sequencing.
Fixes: 32222f09782f ("afs: Apply server breaks to mmap'd files in the call processor")
Signed-off-by: Li RongQing <lirongqing@baidu.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
---
fs/afs/callback.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/fs/afs/callback.c b/fs/afs/callback.c
index 894d2bad6b6c..833ac3178ddc 100644
--- a/fs/afs/callback.c
+++ b/fs/afs/callback.c
@@ -140,7 +140,6 @@ static struct afs_volume *afs_lookup_volume_rcu(struct afs_cell *cell,
break;
if (!need_seqretry(&cell->volume_lock, seq))
break;
- seq |= 1; /* Want a lock next time */
}
done_seqretry(&cell->volume_lock, seq);
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH 6/7] afs: Remove erroneous seq |= 1 in volume lookup loop
2026-06-09 8:17 ` [PATCH 6/7] afs: Remove erroneous seq |= 1 in volume lookup loop David Howells
@ 2026-06-09 9:18 ` Oleg Nesterov
2026-06-09 15:53 ` David Howells
0 siblings, 1 reply; 11+ messages in thread
From: Oleg Nesterov @ 2026-06-09 9:18 UTC (permalink / raw)
To: David Howells
Cc: Christian Brauner, Marc Dionne, linux-afs, linux-fsdevel,
linux-kernel, Li RongQing
On 06/09, David Howells wrote:
>
> From: Li RongQing <lirongqing@baidu.com>
>
> The `seq |= 1` operation in the volume lookup loop is incorrect because:
> seq is already incremented at start, making it odd in next iteration
> which triggers lock, but The `|= 1` operation causes seq to be even
> and unintended lockless operation
>
> Remove this erroneous operation to maintain proper lock sequencing.
>
> Fixes: 32222f09782f ("afs: Apply server breaks to mmap'd files in the call processor")
> Signed-off-by: Li RongQing <lirongqing@baidu.com>
> Signed-off-by: David Howells <dhowells@redhat.com>
> Reviewed-by: Oleg Nesterov <oleg@redhat.com>
> cc: Marc Dionne <marc.dionne@auristor.com>
> cc: linux-afs@lists.infradead.org
> ---
> fs/afs/callback.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/fs/afs/callback.c b/fs/afs/callback.c
> index 894d2bad6b6c..833ac3178ddc 100644
> --- a/fs/afs/callback.c
> +++ b/fs/afs/callback.c
> @@ -140,7 +140,6 @@ static struct afs_volume *afs_lookup_volume_rcu(struct afs_cell *cell,
> break;
> if (!need_seqretry(&cell->volume_lock, seq))
> break;
> - seq |= 1; /* Want a lock next time */
Yes, but now that we have scoped_seqlock_read() we can make another change
on top of this fix. afs_lookup_volume_rcu() can just do
static struct afs_volume *afs_lookup_volume_rcu(struct afs_cell *cell,
afs_volid_t vid)
{
struct afs_volume *volume = NULL;
struct rb_node *p;
scoped_seqlock_read (&cell->volume_lock, ss_lock) {
/* Unfortunately, rbtree walking doesn't give reliable results
* under just the RCU read lock, so we have to check for
* changes.
*/
p = rcu_dereference_raw(cell->volumes.rb_node);
while (p) {
volume = rb_entry(p, struct afs_volume, cell_node);
if (volume->vid < vid)
p = rcu_dereference_raw(p->rb_left);
else if (volume->vid > vid)
p = rcu_dereference_raw(p->rb_right);
else
break;
volume = NULL;
}
if (volume && afs_try_get_volume(volume, afs_volume_trace_get_callback))
break;
}
return volume;
}
Oleg.
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH 6/7] afs: Remove erroneous seq |= 1 in volume lookup loop
2026-06-09 9:18 ` Oleg Nesterov
@ 2026-06-09 15:53 ` David Howells
2026-06-09 16:43 ` Jeffrey E Altman
0 siblings, 1 reply; 11+ messages in thread
From: David Howells @ 2026-06-09 15:53 UTC (permalink / raw)
To: Oleg Nesterov
Cc: dhowells, Christian Brauner, Marc Dionne, linux-afs,
linux-fsdevel, linux-kernel, Li RongQing
Oleg Nesterov <oleg@redhat.com> wrote:
> Yes, but now that we have scoped_seqlock_read() we can make another change
> on top of this fix. afs_lookup_volume_rcu() can just do
I wonder if that would be better as a separate patch rather than merged into
this one.
David
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 6/7] afs: Remove erroneous seq |= 1 in volume lookup loop
2026-06-09 15:53 ` David Howells
@ 2026-06-09 16:43 ` Jeffrey E Altman
0 siblings, 0 replies; 11+ messages in thread
From: Jeffrey E Altman @ 2026-06-09 16:43 UTC (permalink / raw)
To: David Howells, Oleg Nesterov
Cc: Christian Brauner, Marc Dionne, linux-afs, linux-fsdevel,
linux-kernel, Li RongQing
On 6/9/2026 11:53 AM, David Howells wrote:
> Oleg Nesterov <oleg@redhat.com> wrote:
>
>> Yes, but now that we have scoped_seqlock_read() we can make another change
>> on top of this fix. afs_lookup_volume_rcu() can just do
> I wonder if that would be better as a separate patch rather than merged into
> this one.
>
> David
IMO, a separate change would be preferred so that this bug fix patch can
be back-ported
to stable where scoped_seqlock_read() is not present.
Jeffrey
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 7/7] afs: check for duplicate servers in VL server list
2026-06-09 8:17 [PATCH 0/7] afs: Miscellaneous fixes David Howells
` (5 preceding siblings ...)
2026-06-09 8:17 ` [PATCH 6/7] afs: Remove erroneous seq |= 1 in volume lookup loop David Howells
@ 2026-06-09 8:17 ` David Howells
6 siblings, 0 replies; 11+ messages in thread
From: David Howells @ 2026-06-09 8:17 UTC (permalink / raw)
To: Christian Brauner
Cc: David Howells, Marc Dionne, linux-afs, linux-fsdevel,
linux-kernel, Yuto Ohnuki
From: Yuto Ohnuki <ytohnuki@amazon.com>
The DNS response may contain the same server more than once. Check for
duplicates by name and port before inserting into the list to avoid
duplicate entries.
Addresses the TODO comment in afs_extract_vlserver_list().
Signed-off-by: Yuto Ohnuki <ytohnuki@amazon.com>
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
---
fs/afs/vl_list.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/fs/afs/vl_list.c b/fs/afs/vl_list.c
index 003889cf0f18..8e1cf6cdcf71 100644
--- a/fs/afs/vl_list.c
+++ b/fs/afs/vl_list.c
@@ -289,8 +289,20 @@ struct afs_vlserver_list *afs_extract_vlserver_list(struct afs_cell *cell,
afs_put_addrlist(old, afs_alist_trace_put_vlserver_old);
}
+ /* Check for duplicates in the server list */
+ for (j = 0; j < vllist->nr_servers; j++) {
+ struct afs_vlserver *s = vllist->servers[j].server;
- /* TODO: Might want to check for duplicates */
+ if (s->name_len == server->name_len &&
+ s->port == server->port &&
+ strncasecmp(s->name, server->name, server->name_len) == 0) {
+ afs_put_vlserver(cell->net, server);
+ server = NULL;
+ break;
+ }
+ }
+ if (!server)
+ continue;
/* Insertion-sort by priority and weight */
for (j = 0; j < vllist->nr_servers; j++) {
^ permalink raw reply related [flat|nested] 11+ messages in thread