All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.