summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhan Xusheng <zhanxusheng1024@gmail.com>2026-09-23 22:49:37 +0800
committerJoel Granados <joel.granados@kernel.org>2026-09-25 14:00:00 +0200
commit7b08e5851884e4ad207a6401b1dcffdb03d43c28 (patch)
tree5843dd1071259649ce6da13ca4ca273441fbc667
parenta2c375789aa6c83fc85b8f528ee6d7d5f5666941 (diff)
downloadlinux-next-7b08e5851884e4ad207a6401b1dcffdb03d43c28.tar.gz
linux-next-7b08e5851884e4ad207a6401b1dcffdb03d43c28.zip
selftests: sysctl: Check the sign of a negative jiffies read
proc_int_k2u_conv_kop() returns the sign through *negp and the magnitude through *u_ptr. For a negative value it used to convert the sign-extended int and negate afterwards, so the magnitude came back as a wrapped 64-bit number. Nothing noticed, because no test wrote a negative value to a jiffies sysctl. Write one to each of the three int converters and require the value to read back unchanged. Each value is chosen to convert exactly at every CONFIG_HZ, so the test does not depend on it: converter write jiffies stored reads back jiffies -1 -HZ -1 ms_jiffies -1000 -HZ -1000 userhz_jiffies -100 -HZ -100 On a kernel without the fix, at CONFIG_HZ=250: # int_jiffies: got '-18372957097414713411', want '-1' # int_ms_jiffies: got '-18446744069414585320', want '-1000' # int_userhz_jiffies: got '-18446742229035144346', want '-100' not ok 1 test_int_jiffies_negative (paths shortened; the runner prints them under /proc/sys/debug/test_sysctl) Signed-off-by: Zhan Xusheng <zhanxusheng@xiaomi.com> Reviewed-by: Bradley Morgan <brads@mainlining.org> Tested-by: Bradley Morgan <brads@mainlining.org> Signed-off-by: Joel Granados <joel.granados@kernel.org>
-rwxr-xr-xtools/testing/selftests/sysctl/sysctl.sh23
1 files changed, 23 insertions, 0 deletions
diff --git a/tools/testing/selftests/sysctl/sysctl.sh b/tools/testing/selftests/sysctl/sysctl.sh
index ceb5cfa0cfd4..ad1ee0fccd7c 100755
--- a/tools/testing/selftests/sysctl/sysctl.sh
+++ b/tools/testing/selftests/sysctl/sysctl.sh
@@ -328,6 +328,29 @@ test_int_plain()
assert_int_range "$t" "$baseline" || RET=$KSFT_FAIL
}
+# The jiffies converters report the sign separately from the magnitude, so a
+# negative value must survive the round trip through the converter. Each
+# value below is chosen to convert exactly at every CONFIG_HZ.
+test_int_jiffies_negative()
+{
+ local t="${SYSCTL}/int_jiffies"
+ local m="${SYSCTL}/int_ms_jiffies"
+ local u="${SYSCTL}/int_userhz_jiffies"
+
+ [[ -f "$t" && -f "$m" && -f "$u" ]] || { RET=$KSFT_SKIP; return; }
+
+ printf '%s' "-1" > "$t"
+ assert_content "$t" "-1" || RET=$KSFT_FAIL
+ printf '%s' "-1000" > "$m"
+ assert_content "$m" "-1000" || RET=$KSFT_FAIL
+ printf '%s' "-100" > "$u"
+ assert_content "$u" "-100" || RET=$KSFT_FAIL
+
+ # The positive path was never broken; keep it covered.
+ printf '%s' "1" > "$t"
+ assert_content "$t" "1" || RET=$KSFT_FAIL
+}
+
test_uint_plain()
{
local t="${SYSCTL}/uint_0001"