NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/60980: rcu_replace_pointer() fails to update the original pointer
>Number: 60980
>Category: kern
>Synopsis: rcu_replace_pointer() fails to update the original pointer
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Nov 07 09:40:01 +0000 2026
>Originator: hoshinomori
>Release: NetBSD 11.0_STABLE
>Organization:
>Environment:
System: NetBSD xps13-7390-2in1.owarisekai.moe 11.0_STABLE NetBSD 11.0_STABLE (GENERIC) #8: Wed Nov 4 20:13:26 CST 2026 root%xps13-7390-2in1.owarisekai.moe@localhost:/usr/obj/sys/arch/amd64/compile/GENERIC amd64
Architecture: x86_64
Machine: amd64
>Description:
The rcu_replace_pointer() macro in src/sys/external/bsd/common/include/linux/rcupdate.h doesn't update the original pointer.
The macro copy PTRP into a local var __rrp_ptrp and then call rcu_assign_pointer on it instead of the original one.
>How-To-Repeat:
cc rcu_replace_pointer_test.c -o test && ./test
expect output:
returned_old=1 updated_caller=0 still_old=1
=== rcu_replace_pointer_test.c ===
#include <stdio.h>
#define WARN_ON(c) ((void)(c))
#define atomic_store_release(p, v) __atomic_store_n((p), (v), __ATOMIC_RELEASE)
#define rcu_assign_pointer(P,V) atomic_store_release(&(P), (V))
#define rcu_dereference_protected(P, C) ({ \
WARN_ON(!(C)); \
(P); \
})
#define rcu_replace_pointer(PTRP, NEWPTR, C) ({ \
__typeof__(PTRP) __rrp_ptrp = (PTRP); \
__typeof__(PTRP) __rrp_oldptr = \
rcu_dereference_protected(__rrp_ptrp, C); \
rcu_assign_pointer(__rrp_ptrp, NEWPTR); \
__rrp_oldptr; \
})
int
main(void)
{
int old_object = 1, new_object = 2;
struct { int *engines; } ctx = { &old_object };
int *ret = rcu_replace_pointer(ctx.engines, &new_object, 1);
printf("returned_old=%d updated_caller=%d still_old=%d\n",
ret == &old_object, ctx.engines == &new_object,
ctx.engines == &old_object);
return !(ret == &old_object && ctx.engines == &new_object);
}
=== EOF ===
>Fix:
Index: rcupdate.h
===================================================================
RCS file: /cvsroot/src/sys/external/bsd/common/include/linux/rcupdate.h,v
retrieving revision 1.8
diff -u -r1.8 rcupdate.h
--- rcupdate.h 19 Dec 2021 11:49:11 -0000 1.8
+++ rcupdate.h 7 Nov 2026 09:16:14 -0000
@@ -54,10 +54,10 @@
})
#define rcu_replace_pointer(PTRP, NEWPTR, C) ({ \
- __typeof__(PTRP) __rrp_ptrp = (PTRP); \
+ __typeof__(&(PTRP)) __rrp_ptrp = &(PTRP); \
__typeof__(PTRP) __rrp_oldptr = \
- rcu_dereference_protected(__rrp_ptrp, C); \
- rcu_assign_pointer(__rrp_ptrp, NEWPTR); \
+ rcu_dereference_protected(*__rrp_ptrp, C); \
+ rcu_assign_pointer(*__rrp_ptrp, NEWPTR); \
__rrp_oldptr; \
})
Home |
Main Index |
Thread Index |
Old Index