diff options
| author | Zhan Xusheng <zhanxusheng1024@gmail.com> | 2026-09-28 10:02:04 +0800 |
|---|---|---|
| committer | Joel Granados <joel.granados@kernel.org> | 2026-09-28 15:43:06 +0200 |
| commit | b60237dc2146b45b0a6f72d2645220bd9fb4cb81 (patch) | |
| tree | d3a5018a98c8c00fc9466b043f73a2fd0ccf8d05 /tools/perf | |
| parent | 7b08e5851884e4ad207a6401b1dcffdb03d43c28 (diff) | |
| download | linux-next-b60237dc2146b45b0a6f72d2645220bd9fb4cb81.tar.gz linux-next-b60237dc2146b45b0a6f72d2645220bd9fb4cb81.zip | |
sysctl: Negate before converting in the int read path
proc_int_k2u_conv_kop() reports the sign through *negp and the magnitude
through *u_ptr, but for a negative value it hands the sign-extended int to
the converter and negates the result:
*u_ptr = k_ptr_op ? -k_ptr_op((ulong)val) : -(ulong)val;
With div_hz() and CONFIG_HZ=1000 a stored -1000 becomes
(ulong)-1000 / 1000 == 18446744073709550, and negating that wraps:
# echo -1 > /proc/sys/net/ipv4/tcp_fin_timeout
# cat /proc/sys/net/ipv4/tcp_fin_timeout
-18428297329635842066
The magnitude is HZ dependent but the wrap is not: the negation happens
after the division at every CONFIG_HZ.
Take the magnitude first and convert that, which is what the open-coded
version did before commit 2dc164a48e6f ("sysctl: Create converter
functions with two new macros") folded it into a macro. The
k_ptr_op == NULL branch was already correct.
All three int converters that pass a k_ptr_op are affected:
proc_dointvec_jiffies(), proc_dointvec_userhz_jiffies() and
proc_dointvec_ms_jiffies().
Fixes: 2dc164a48e6f ("sysctl: Create converter functions with two new macros")
Cc: stable@vger.kernel.org
Reviewed-by: Bradley Morgan <brads@mainlining.org>
Signed-off-by: Zhan Xusheng <zhanxusheng@xiaomi.com>
Signed-off-by: Joel Granados <joel.granados@kernel.org>
Diffstat (limited to 'tools/perf')
0 files changed, 0 insertions, 0 deletions
