* [RFC PATCH 3/4] sysctl: support encoding values directly in the table entry
2026-01-13 17:40 [RFC PATCH 0/4] sysctl: refactor ctl_table creation and change extra{1,2} type wen.yang
@ 2026-01-13 17:40 ` wen.yang
0 siblings, 0 replies; 2+ messages in thread
From: wen.yang @ 2026-01-13 17:40 UTC (permalink / raw)
To: Joel Granados; +Cc: linux-kernel, Wen Yang
From: Wen Yang <wen.yang@linux.dev>
Eric points out: "by turning .extra1 and .extra2 into longs instead of
keeping them as pointers and needing constants to be pointed at somewhere
.. The only people I can see who find a significant benefit by
consolidating all of the constants into one place are people who know how
to stomp kernel memory."
This patch supports encoding values directly in table entries.
This patch also adds a kunit test case:
[15:09:24] ================ sysctl_test (11 subtests) =================
[15:09:24] [PASSED] sysctl_test_api_dointvec_null_tbl_data
[15:09:24] [PASSED] sysctl_test_api_dointvec_table_maxlen_unset
[15:09:24] [PASSED] sysctl_test_api_dointvec_table_len_is_zero
[15:09:24] [PASSED] sysctl_test_api_dointvec_table_read_but_position_set
[15:09:24] [PASSED] sysctl_test_dointvec_read_happy_single_positive
[15:09:24] [PASSED] sysctl_test_dointvec_read_happy_single_negative
[15:09:24] [PASSED] sysctl_test_dointvec_write_happy_single_positive
[15:09:24] [PASSED] sysctl_test_dointvec_write_happy_single_negative
[15:09:24] [PASSED] sysctl_test_api_dointvec_write_single_less_int_min
[15:09:24] [PASSED] sysctl_test_api_dointvec_write_single_greater_int_max
[15:09:24] [PASSED] sysctl_test_api_dointvec_write_range_check
[15:09:24] =================== [PASSED] sysctl_test ===================
[15:09:24] ============================================================
[15:09:24] Testing complete. Ran 11 tests: passed: 11
Suggested-by: Joel Granados <joel.granados@kernel.org>
Signed-off-by: Wen Yang <wen.yang@linux.dev>
---
include/linux/sysctl.h | 60 +++++++++++++++--
kernel/sysctl-test.c | 142 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 195 insertions(+), 7 deletions(-)
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 9690740885ab..19be4f3f700b 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -165,9 +165,14 @@ static inline void *proc_sys_poll_event(struct ctl_table_poll *poll)
struct ctl_table_poll name = __CTL_TABLE_POLL_INITIALIZER(name)
#define SYSCTL_IN_RANGE(tbl, val, type) \
- ((tbl) && \
- (!(tbl)->extra1 || (*(type *)(tbl)->extra1 <= (type)(val))) && \
- (!(tbl)->extra2 || (*(type *)(tbl)->extra2 >= (type)(val))))
+ ((tbl) && ({ \
+ type v = (type)(val); \
+ !((tbl)->min_is_value ? (tbl)->min > (unsigned long)v \
+ : (tbl)->extra1 && *(type*)(tbl)->extra1 > v) \
+ && !((tbl)->max_is_value ? (tbl)->max < (unsigned long)v \
+ : (tbl)->extra2 && *(type*)(tbl)->extra2 < v); \
+ }) \
+ )
#define SYSCTL_IN_RANGE_INT(tbl, val) SYSCTL_IN_RANGE(tbl, val, int)
#define SYSCTL_IN_RANGE_LONG(tbl, val) SYSCTL_IN_RANGE(tbl, val, long)
@@ -180,12 +185,52 @@ struct ctl_table {
void *data;
int maxlen;
umode_t mode;
+
+ /**
+ * Range bound type flags
+ * - min_is_value: 1 = min field is direct value, 0 = extra1 is pointer
+ * - max_is_value: 1 = max field is direct value, 0 = extra2 is pointer
+ */
+ union {
+ struct {
+ unsigned char min_is_value : 1; /* bit 0: min type */
+ unsigned char max_is_value : 1; /* bit 1: max type */
+ unsigned char reserved : 6; /* bits 2-7: reserved */
+ };
+ unsigned char flags;
+ };
+
proc_handler *proc_handler; /* Callback for text formatting */
struct ctl_table_poll *poll;
- void *extra1;
- void *extra2;
+
+ /* Range bounds: either pointers or direct values */
+ union {
+ struct {
+ void *extra1; /* min as pointer */
+ void *extra2; /* max as pointer */
+ };
+ struct {
+ unsigned long min; /* min as direct value */
+ unsigned long max; /* max as direct value */
+ };
+ };
} __randomize_layout;
+/* Pointer detection using _Generic */
+#define IS_PTR(x) _Generic((x), \
+ char*:1, short*:1, int*:1, long*:1, \
+ unsigned char*:1, unsigned short*:1, unsigned int*:1, unsigned long*:1, \
+ const char*:1, const int*:1, const long*:1, \
+ void*:1, const void*:1, default:0)
+
+/* Auto-detect range flags: 0=ptr_ptr, 1=val_ptr, 2=ptr_val, 3=val_val */
+#define RANGE_FLAGS(smin, smax) ((!IS_PTR(smin)) | ((!IS_PTR(smax)) << 1))
+
+/* Type-specific checks */
+#define CHECK_INT(tbl, val) CHECK(tbl, val, int)
+#define CHECK_UINT(tbl, val) CHECK(tbl, val, unsigned int)
+#define CHECK_LONG(tbl, val) CHECK(tbl, val, long)
+
#define __SYSCTL_ENTRY(NAME, DATA, TYPE, MODE, HANDLER, SMIN, SMAX)\
{ \
.procname = NAME, \
@@ -193,8 +238,9 @@ struct ctl_table {
.maxlen = sizeof(TYPE), \
.mode = MODE, \
.proc_handler = HANDLER, \
- .extra1 = SMIN, \
- .extra2 = SMAX, \
+ .flags = RANGE_FLAGS(SMIN, SMAX), \
+ .min = (unsigned long)(SMIN), \
+ .max = (unsigned long)(SMAX), \
}
#define SYSCTL_ENTRY(NAME, DATA, TYPE, MODE) \
diff --git a/kernel/sysctl-test.c b/kernel/sysctl-test.c
index 7fb0e7f1e62f..b55bc84e56c2 100644
--- a/kernel/sysctl-test.c
+++ b/kernel/sysctl-test.c
@@ -300,6 +300,147 @@ static void sysctl_test_api_dointvec_write_single_greater_int_max(
KUNIT_EXPECT_EQ(test, 0, *((int *)table.data));
}
+/*
+ * Test that writing values within the specified range succeeds,
+ * and ensures out-of-range writes are correctly rejected.
+ */
+static void sysctl_test_api_dointvec_write_range_check(struct kunit *test)
+{
+ int data = 0;
+ size_t len;
+ loff_t pos;
+ char *buffer;
+ char __user *user_buffer;
+
+ /* Prepare bound variables for pointer modes */
+ int min_bounds[] = {10, 0, 15, 0};
+ int max_bounds[] = {90, 75, 0, 0};
+
+ /* Initialize test tables using macro */
+ struct ctl_table test_cases[] = {
+ /* PTR_PTR: both pointers */
+ SYSCTL_RANGE_ENTRY("ptr_ptr", &data, int, 0644,
+ &min_bounds[0], &max_bounds[0]),
+ /* VAL_PTR: min is value, max is pointer */
+ SYSCTL_RANGE_ENTRY("val_ptr", &data, int, 0644,
+ 25, &max_bounds[1]),
+ /* PTR_VAL: min is pointer, max is value */
+ SYSCTL_RANGE_ENTRY("ptr_val", &data, int, 0644,
+ &min_bounds[2], 85),
+ /* VAL_VAL: both values */
+ SYSCTL_RANGE_ENTRY("val_val", &data, int, 0644,
+ 20, 80),
+ };
+
+ /* Test parameters for each mode */
+ const struct {
+ int min, max;
+ const char *valid;
+ const char *below_min;
+ const char *above_max;
+ } test_params[] = {
+ {10, 90, "50", "5", "95"}, /* PTR_PTR */
+ {25, 75, "50", "20", "80"}, /* VAL_PTR */
+ {15, 85, "50", "10", "90"}, /* PTR_VAL */
+ {20, 80, "50", "15", "85"}, /* VAL_VAL */
+ };
+
+ for (int i = 0; i < 4; i++) {
+ struct ctl_table *table = &test_cases[i];
+ const typeof(test_params[0]) *param = &test_params[i];
+
+ /* Verify flags auto-detection */
+ KUNIT_EXPECT_EQ(test, table->flags, i);
+ KUNIT_EXPECT_EQ(test, (int)table->min_is_value, (i & 1) != 0);
+ KUNIT_EXPECT_EQ(test, (int)table->max_is_value, (i & 2) != 0);
+
+ /* Verify union access */
+ if (table->min_is_value) {
+ KUNIT_EXPECT_EQ(test, table->min, (unsigned long)param->min);
+ } else {
+ KUNIT_EXPECT_PTR_EQ(test, table->extra1, &min_bounds[i]);
+ KUNIT_EXPECT_EQ(test, *(int *)table->extra1, param->min);
+ }
+
+ if (table->max_is_value) {
+ KUNIT_EXPECT_EQ(test, table->max, (unsigned long)param->max);
+ } else {
+ KUNIT_EXPECT_PTR_EQ(test, table->extra2, &max_bounds[i]);
+ KUNIT_EXPECT_EQ(test, *(int *)table->extra2, param->max);
+ }
+
+ /* Test valid value in range */
+ data = 0;
+ len = strlen(param->valid);
+ pos = 0;
+ buffer = kunit_kzalloc(test, len, GFP_USER);
+ user_buffer = (char __user *)buffer;
+ memcpy(buffer, param->valid, len);
+
+ KUNIT_EXPECT_EQ(test, 0, proc_dointvec_minmax(table, KUNIT_PROC_WRITE,
+ user_buffer, &len, &pos));
+ KUNIT_EXPECT_EQ(test, strlen(param->valid), len);
+ KUNIT_EXPECT_EQ(test, strlen(param->valid), pos);
+ KUNIT_EXPECT_EQ(test, 50, data);
+
+ /* Test min boundary */
+ data = 0;
+ char min_str[16];
+ snprintf(min_str, sizeof(min_str), "%d", param->min);
+ len = strlen(min_str);
+ pos = 0;
+ buffer = kunit_kzalloc(test, len, GFP_USER);
+ user_buffer = (char __user *)buffer;
+ memcpy(buffer, min_str, len);
+
+ KUNIT_EXPECT_EQ(test, 0, proc_dointvec_minmax(table, KUNIT_PROC_WRITE,
+ user_buffer, &len, &pos));
+ KUNIT_EXPECT_EQ(test, strlen(min_str), len);
+ KUNIT_EXPECT_EQ(test, strlen(min_str), pos);
+ KUNIT_EXPECT_EQ(test, param->min, data);
+
+ /* Test max boundary */
+ data = 0;
+ char max_str[16];
+ snprintf(max_str, sizeof(max_str), "%d", param->max);
+ len = strlen(max_str);
+ pos = 0;
+ buffer = kunit_kzalloc(test, len, GFP_USER);
+ user_buffer = (char __user *)buffer;
+ memcpy(buffer, max_str, len);
+
+ KUNIT_EXPECT_EQ(test, 0, proc_dointvec_minmax(table, KUNIT_PROC_WRITE,
+ user_buffer, &len, &pos));
+ KUNIT_EXPECT_EQ(test, strlen(max_str), len);
+ KUNIT_EXPECT_EQ(test, strlen(max_str), pos);
+ KUNIT_EXPECT_EQ(test, param->max, data);
+
+ /* Test below min - should fail */
+ data = 0;
+ len = strlen(param->below_min);
+ pos = 0;
+ buffer = kunit_kzalloc(test, len, GFP_USER);
+ user_buffer = (char __user *)buffer;
+ memcpy(buffer, param->below_min, len);
+
+ KUNIT_EXPECT_EQ(test, -EINVAL, proc_dointvec_minmax(table, KUNIT_PROC_WRITE,
+ user_buffer, &len, &pos));
+ KUNIT_EXPECT_EQ(test, 0, data);
+
+ /* Test above max - should fail */
+ data = 0;
+ len = strlen(param->above_max);
+ pos = 0;
+ buffer = kunit_kzalloc(test, len, GFP_USER);
+ user_buffer = (char __user *)buffer;
+ memcpy(buffer, param->above_max, len);
+
+ KUNIT_EXPECT_EQ(test, -EINVAL, proc_dointvec_minmax(table, KUNIT_PROC_WRITE,
+ user_buffer, &len, &pos));
+ KUNIT_EXPECT_EQ(test, 0, data);
+ }
+}
+
static struct kunit_case sysctl_test_cases[] = {
KUNIT_CASE(sysctl_test_api_dointvec_null_tbl_data),
KUNIT_CASE(sysctl_test_api_dointvec_table_maxlen_unset),
@@ -311,6 +452,7 @@ static struct kunit_case sysctl_test_cases[] = {
KUNIT_CASE(sysctl_test_dointvec_write_happy_single_negative),
KUNIT_CASE(sysctl_test_api_dointvec_write_single_less_int_min),
KUNIT_CASE(sysctl_test_api_dointvec_write_single_greater_int_max),
+ KUNIT_CASE(sysctl_test_api_dointvec_write_range_check),
{}
};
--
2.25.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [RFC PATCH 3/4] sysctl: support encoding values directly in the table entry
@ 2026-01-16 0:57 kernel test robot
0 siblings, 0 replies; 2+ messages in thread
From: kernel test robot @ 2026-01-16 0:57 UTC (permalink / raw)
To: oe-kbuild; +Cc: lkp, Dan Carpenter
BCC: lkp@intel.com
CC: oe-kbuild-all@lists.linux.dev
In-Reply-To: <907e4f14cedb2bfb2810dec255b930d59b821dc2.1768324215.git.wen.yang@linux.dev>
References: <907e4f14cedb2bfb2810dec255b930d59b821dc2.1768324215.git.wen.yang@linux.dev>
TO: wen.yang@linux.dev
Hi,
[This is a private test report for your RFC patch.]
kernel test robot noticed the following build warnings:
[auto build test WARNING on sysctl/sysctl-next]
[also build test WARNING on next-20260115]
[cannot apply to linus/master mcgrof/sysctl-next v6.19-rc5]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/wen-yang-linux-dev/sysctl-add-SYSCTL_ENTRY-SYSCTL_RANGE_ENTRY-helpers-for-ctl_table-init/20260114-014339
base: https://git.kernel.org/pub/scm/linux/kernel/git/sysctl/sysctl.git sysctl-next
patch link: https://lore.kernel.org/r/907e4f14cedb2bfb2810dec255b930d59b821dc2.1768324215.git.wen.yang%40linux.dev
patch subject: [RFC PATCH 3/4] sysctl: support encoding values directly in the table entry
:::::: branch date: 2 days ago
:::::: commit date: 2 days ago
config: m68k-randconfig-r071-20260116 (https://download.01.org/0day-ci/archive/20260116/202601160850.i6bVRfFi-lkp@intel.com/config)
compiler: m68k-linux-gcc (GCC) 15.2.0
smatch version: v0.5.0-8985-g2614ff1a
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <error27@gmail.com>
| Closes: https://lore.kernel.org/r/202601160850.i6bVRfFi-lkp@intel.com/
smatch warnings:
kernel/sysctl-test.c:320 sysctl_test_api_dointvec_write_range_check() warn: (struct ctl_table)->procname cannot be NULL. Expression : test_cases[0]->procname
kernel/sysctl-test.c:320 sysctl_test_api_dointvec_write_range_check() warn: (struct ctl_table)->proc_handler cannot be NULL. Expression : test_cases[0]->proc_handler
vim +320 kernel/sysctl-test.c
2cb80dbbbaba4f Iurii Zaikin 2019-09-23 302
ca5cba219ba481 Wen Yang 2026-01-14 303 /*
ca5cba219ba481 Wen Yang 2026-01-14 304 * Test that writing values within the specified range succeeds,
ca5cba219ba481 Wen Yang 2026-01-14 305 * and ensures out-of-range writes are correctly rejected.
ca5cba219ba481 Wen Yang 2026-01-14 306 */
ca5cba219ba481 Wen Yang 2026-01-14 307 static void sysctl_test_api_dointvec_write_range_check(struct kunit *test)
ca5cba219ba481 Wen Yang 2026-01-14 308 {
ca5cba219ba481 Wen Yang 2026-01-14 309 int data = 0;
ca5cba219ba481 Wen Yang 2026-01-14 310 size_t len;
ca5cba219ba481 Wen Yang 2026-01-14 311 loff_t pos;
ca5cba219ba481 Wen Yang 2026-01-14 312 char *buffer;
ca5cba219ba481 Wen Yang 2026-01-14 313 char __user *user_buffer;
ca5cba219ba481 Wen Yang 2026-01-14 314
ca5cba219ba481 Wen Yang 2026-01-14 315 /* Prepare bound variables for pointer modes */
ca5cba219ba481 Wen Yang 2026-01-14 316 int min_bounds[] = {10, 0, 15, 0};
ca5cba219ba481 Wen Yang 2026-01-14 317 int max_bounds[] = {90, 75, 0, 0};
ca5cba219ba481 Wen Yang 2026-01-14 318
ca5cba219ba481 Wen Yang 2026-01-14 319 /* Initialize test tables using macro */
ca5cba219ba481 Wen Yang 2026-01-14 @320 struct ctl_table test_cases[] = {
ca5cba219ba481 Wen Yang 2026-01-14 321 /* PTR_PTR: both pointers */
ca5cba219ba481 Wen Yang 2026-01-14 322 SYSCTL_RANGE_ENTRY("ptr_ptr", &data, int, 0644,
ca5cba219ba481 Wen Yang 2026-01-14 323 &min_bounds[0], &max_bounds[0]),
ca5cba219ba481 Wen Yang 2026-01-14 324 /* VAL_PTR: min is value, max is pointer */
ca5cba219ba481 Wen Yang 2026-01-14 325 SYSCTL_RANGE_ENTRY("val_ptr", &data, int, 0644,
ca5cba219ba481 Wen Yang 2026-01-14 326 25, &max_bounds[1]),
ca5cba219ba481 Wen Yang 2026-01-14 327 /* PTR_VAL: min is pointer, max is value */
ca5cba219ba481 Wen Yang 2026-01-14 328 SYSCTL_RANGE_ENTRY("ptr_val", &data, int, 0644,
ca5cba219ba481 Wen Yang 2026-01-14 329 &min_bounds[2], 85),
ca5cba219ba481 Wen Yang 2026-01-14 330 /* VAL_VAL: both values */
ca5cba219ba481 Wen Yang 2026-01-14 331 SYSCTL_RANGE_ENTRY("val_val", &data, int, 0644,
ca5cba219ba481 Wen Yang 2026-01-14 332 20, 80),
ca5cba219ba481 Wen Yang 2026-01-14 333 };
ca5cba219ba481 Wen Yang 2026-01-14 334
ca5cba219ba481 Wen Yang 2026-01-14 335 /* Test parameters for each mode */
ca5cba219ba481 Wen Yang 2026-01-14 336 const struct {
ca5cba219ba481 Wen Yang 2026-01-14 337 int min, max;
ca5cba219ba481 Wen Yang 2026-01-14 338 const char *valid;
ca5cba219ba481 Wen Yang 2026-01-14 339 const char *below_min;
ca5cba219ba481 Wen Yang 2026-01-14 340 const char *above_max;
ca5cba219ba481 Wen Yang 2026-01-14 341 } test_params[] = {
ca5cba219ba481 Wen Yang 2026-01-14 342 {10, 90, "50", "5", "95"}, /* PTR_PTR */
ca5cba219ba481 Wen Yang 2026-01-14 343 {25, 75, "50", "20", "80"}, /* VAL_PTR */
ca5cba219ba481 Wen Yang 2026-01-14 344 {15, 85, "50", "10", "90"}, /* PTR_VAL */
ca5cba219ba481 Wen Yang 2026-01-14 345 {20, 80, "50", "15", "85"}, /* VAL_VAL */
ca5cba219ba481 Wen Yang 2026-01-14 346 };
ca5cba219ba481 Wen Yang 2026-01-14 347
ca5cba219ba481 Wen Yang 2026-01-14 348 for (int i = 0; i < 4; i++) {
ca5cba219ba481 Wen Yang 2026-01-14 349 struct ctl_table *table = &test_cases[i];
ca5cba219ba481 Wen Yang 2026-01-14 350 const typeof(test_params[0]) *param = &test_params[i];
ca5cba219ba481 Wen Yang 2026-01-14 351
ca5cba219ba481 Wen Yang 2026-01-14 352 /* Verify flags auto-detection */
ca5cba219ba481 Wen Yang 2026-01-14 353 KUNIT_EXPECT_EQ(test, table->flags, i);
ca5cba219ba481 Wen Yang 2026-01-14 354 KUNIT_EXPECT_EQ(test, (int)table->min_is_value, (i & 1) != 0);
ca5cba219ba481 Wen Yang 2026-01-14 355 KUNIT_EXPECT_EQ(test, (int)table->max_is_value, (i & 2) != 0);
ca5cba219ba481 Wen Yang 2026-01-14 356
ca5cba219ba481 Wen Yang 2026-01-14 357 /* Verify union access */
ca5cba219ba481 Wen Yang 2026-01-14 358 if (table->min_is_value) {
ca5cba219ba481 Wen Yang 2026-01-14 359 KUNIT_EXPECT_EQ(test, table->min, (unsigned long)param->min);
ca5cba219ba481 Wen Yang 2026-01-14 360 } else {
ca5cba219ba481 Wen Yang 2026-01-14 361 KUNIT_EXPECT_PTR_EQ(test, table->extra1, &min_bounds[i]);
ca5cba219ba481 Wen Yang 2026-01-14 362 KUNIT_EXPECT_EQ(test, *(int *)table->extra1, param->min);
ca5cba219ba481 Wen Yang 2026-01-14 363 }
ca5cba219ba481 Wen Yang 2026-01-14 364
ca5cba219ba481 Wen Yang 2026-01-14 365 if (table->max_is_value) {
ca5cba219ba481 Wen Yang 2026-01-14 366 KUNIT_EXPECT_EQ(test, table->max, (unsigned long)param->max);
ca5cba219ba481 Wen Yang 2026-01-14 367 } else {
ca5cba219ba481 Wen Yang 2026-01-14 368 KUNIT_EXPECT_PTR_EQ(test, table->extra2, &max_bounds[i]);
ca5cba219ba481 Wen Yang 2026-01-14 369 KUNIT_EXPECT_EQ(test, *(int *)table->extra2, param->max);
ca5cba219ba481 Wen Yang 2026-01-14 370 }
ca5cba219ba481 Wen Yang 2026-01-14 371
ca5cba219ba481 Wen Yang 2026-01-14 372 /* Test valid value in range */
ca5cba219ba481 Wen Yang 2026-01-14 373 data = 0;
ca5cba219ba481 Wen Yang 2026-01-14 374 len = strlen(param->valid);
ca5cba219ba481 Wen Yang 2026-01-14 375 pos = 0;
ca5cba219ba481 Wen Yang 2026-01-14 376 buffer = kunit_kzalloc(test, len, GFP_USER);
ca5cba219ba481 Wen Yang 2026-01-14 377 user_buffer = (char __user *)buffer;
ca5cba219ba481 Wen Yang 2026-01-14 378 memcpy(buffer, param->valid, len);
ca5cba219ba481 Wen Yang 2026-01-14 379
ca5cba219ba481 Wen Yang 2026-01-14 380 KUNIT_EXPECT_EQ(test, 0, proc_dointvec_minmax(table, KUNIT_PROC_WRITE,
ca5cba219ba481 Wen Yang 2026-01-14 381 user_buffer, &len, &pos));
ca5cba219ba481 Wen Yang 2026-01-14 382 KUNIT_EXPECT_EQ(test, strlen(param->valid), len);
ca5cba219ba481 Wen Yang 2026-01-14 383 KUNIT_EXPECT_EQ(test, strlen(param->valid), pos);
ca5cba219ba481 Wen Yang 2026-01-14 384 KUNIT_EXPECT_EQ(test, 50, data);
ca5cba219ba481 Wen Yang 2026-01-14 385
ca5cba219ba481 Wen Yang 2026-01-14 386 /* Test min boundary */
ca5cba219ba481 Wen Yang 2026-01-14 387 data = 0;
ca5cba219ba481 Wen Yang 2026-01-14 388 char min_str[16];
ca5cba219ba481 Wen Yang 2026-01-14 389 snprintf(min_str, sizeof(min_str), "%d", param->min);
ca5cba219ba481 Wen Yang 2026-01-14 390 len = strlen(min_str);
ca5cba219ba481 Wen Yang 2026-01-14 391 pos = 0;
ca5cba219ba481 Wen Yang 2026-01-14 392 buffer = kunit_kzalloc(test, len, GFP_USER);
ca5cba219ba481 Wen Yang 2026-01-14 393 user_buffer = (char __user *)buffer;
ca5cba219ba481 Wen Yang 2026-01-14 394 memcpy(buffer, min_str, len);
ca5cba219ba481 Wen Yang 2026-01-14 395
ca5cba219ba481 Wen Yang 2026-01-14 396 KUNIT_EXPECT_EQ(test, 0, proc_dointvec_minmax(table, KUNIT_PROC_WRITE,
ca5cba219ba481 Wen Yang 2026-01-14 397 user_buffer, &len, &pos));
ca5cba219ba481 Wen Yang 2026-01-14 398 KUNIT_EXPECT_EQ(test, strlen(min_str), len);
ca5cba219ba481 Wen Yang 2026-01-14 399 KUNIT_EXPECT_EQ(test, strlen(min_str), pos);
ca5cba219ba481 Wen Yang 2026-01-14 400 KUNIT_EXPECT_EQ(test, param->min, data);
ca5cba219ba481 Wen Yang 2026-01-14 401
ca5cba219ba481 Wen Yang 2026-01-14 402 /* Test max boundary */
ca5cba219ba481 Wen Yang 2026-01-14 403 data = 0;
ca5cba219ba481 Wen Yang 2026-01-14 404 char max_str[16];
ca5cba219ba481 Wen Yang 2026-01-14 405 snprintf(max_str, sizeof(max_str), "%d", param->max);
ca5cba219ba481 Wen Yang 2026-01-14 406 len = strlen(max_str);
ca5cba219ba481 Wen Yang 2026-01-14 407 pos = 0;
ca5cba219ba481 Wen Yang 2026-01-14 408 buffer = kunit_kzalloc(test, len, GFP_USER);
ca5cba219ba481 Wen Yang 2026-01-14 409 user_buffer = (char __user *)buffer;
ca5cba219ba481 Wen Yang 2026-01-14 410 memcpy(buffer, max_str, len);
ca5cba219ba481 Wen Yang 2026-01-14 411
ca5cba219ba481 Wen Yang 2026-01-14 412 KUNIT_EXPECT_EQ(test, 0, proc_dointvec_minmax(table, KUNIT_PROC_WRITE,
ca5cba219ba481 Wen Yang 2026-01-14 413 user_buffer, &len, &pos));
ca5cba219ba481 Wen Yang 2026-01-14 414 KUNIT_EXPECT_EQ(test, strlen(max_str), len);
ca5cba219ba481 Wen Yang 2026-01-14 415 KUNIT_EXPECT_EQ(test, strlen(max_str), pos);
ca5cba219ba481 Wen Yang 2026-01-14 416 KUNIT_EXPECT_EQ(test, param->max, data);
ca5cba219ba481 Wen Yang 2026-01-14 417
ca5cba219ba481 Wen Yang 2026-01-14 418 /* Test below min - should fail */
ca5cba219ba481 Wen Yang 2026-01-14 419 data = 0;
ca5cba219ba481 Wen Yang 2026-01-14 420 len = strlen(param->below_min);
ca5cba219ba481 Wen Yang 2026-01-14 421 pos = 0;
ca5cba219ba481 Wen Yang 2026-01-14 422 buffer = kunit_kzalloc(test, len, GFP_USER);
ca5cba219ba481 Wen Yang 2026-01-14 423 user_buffer = (char __user *)buffer;
ca5cba219ba481 Wen Yang 2026-01-14 424 memcpy(buffer, param->below_min, len);
ca5cba219ba481 Wen Yang 2026-01-14 425
ca5cba219ba481 Wen Yang 2026-01-14 426 KUNIT_EXPECT_EQ(test, -EINVAL, proc_dointvec_minmax(table, KUNIT_PROC_WRITE,
ca5cba219ba481 Wen Yang 2026-01-14 427 user_buffer, &len, &pos));
ca5cba219ba481 Wen Yang 2026-01-14 428 KUNIT_EXPECT_EQ(test, 0, data);
ca5cba219ba481 Wen Yang 2026-01-14 429
ca5cba219ba481 Wen Yang 2026-01-14 430 /* Test above max - should fail */
ca5cba219ba481 Wen Yang 2026-01-14 431 data = 0;
ca5cba219ba481 Wen Yang 2026-01-14 432 len = strlen(param->above_max);
ca5cba219ba481 Wen Yang 2026-01-14 433 pos = 0;
ca5cba219ba481 Wen Yang 2026-01-14 434 buffer = kunit_kzalloc(test, len, GFP_USER);
ca5cba219ba481 Wen Yang 2026-01-14 435 user_buffer = (char __user *)buffer;
ca5cba219ba481 Wen Yang 2026-01-14 436 memcpy(buffer, param->above_max, len);
ca5cba219ba481 Wen Yang 2026-01-14 437
ca5cba219ba481 Wen Yang 2026-01-14 438 KUNIT_EXPECT_EQ(test, -EINVAL, proc_dointvec_minmax(table, KUNIT_PROC_WRITE,
ca5cba219ba481 Wen Yang 2026-01-14 439 user_buffer, &len, &pos));
ca5cba219ba481 Wen Yang 2026-01-14 440 KUNIT_EXPECT_EQ(test, 0, data);
ca5cba219ba481 Wen Yang 2026-01-14 441 }
ca5cba219ba481 Wen Yang 2026-01-14 442 }
ca5cba219ba481 Wen Yang 2026-01-14 443
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-01-16 0:58 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-16 0:57 [RFC PATCH 3/4] sysctl: support encoding values directly in the table entry kernel test robot
-- strict thread matches above, loose matches on Subject: below --
2026-01-13 17:40 [RFC PATCH 0/4] sysctl: refactor ctl_table creation and change extra{1,2} type wen.yang
2026-01-13 17:40 ` [RFC PATCH 3/4] sysctl: support encoding values directly in the table entry wen.yang
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.