lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <8996bbfd86079cff39e1bbf7f645e4c099c5081e.1770496163.git.wen.yang@linux.dev>
Date: Sun,  8 Feb 2026 04:35:17 +0800
From: wen.yang@...ux.dev
To: Joel Granados <joel.granados@...nel.org>
Cc: linux-kernel@...r.kernel.org,
	Wen Yang <wen.yang@...ux.dev>
Subject: [RFC PATCH v2 2/2] sysctl: convert kernel/sysctl-test.c to use SYSCTL_TBL_ENTRY()

From: Wen Yang <wen.yang@...ux.dev>

Convert sysctl test cases to use the new SYSCTL_TBL_ENTRY() macro,
demonstrating the macro's benefits in reducing boilerplate and
improving code readability.

This conversion shows typical usage patterns:

- Standard entries with range checking:
   Before (11 lines):
   struct ctl_table table = {
       .procname = "foo",
       .data = &data,
       .maxlen = sizeof(int),
       .mode = 0644,
       .proc_handler = proc_dointvec,
       .extra1 = SYSCTL_ZERO,
       .extra2 = SYSCTL_ONE_HUNDRED,
   };

   After (2 lines):
   struct ctl_table table = SYSCTL_TBL_ENTRY("foo", data, 0644,
                                             SYSCTL_ZERO, SYSCTL_ONE_HUNDRED);

- NULL data entries:
   Before (11 lines with explicit .data = NULL):
   struct ctl_table null_data_table = {
       .procname = "foo",
       .data = NULL,
       .maxlen = sizeof(int),
       ...
   };

   After (3 lines using SYSCTL_NULL marker):
   struct ctl_table null_data_table = SYSCTL_TBL_ENTRY("foo", SYSCTL_NULL, 0644,
                                                        proc_dointvec,
                                                        SYSCTL_ZERO, SYSCTL_ONE_HUNDRED);

- Explicit maxlen override:
   SYSCTL_TBL_ENTRY("foo", SYSCTL_NULL, 0644, proc_dointvec,
                    SYSCTL_ZERO, SYSCTL_ONE_HUNDRED, 0);

Benefits demonstrated:
- 60% reduction in lines of code (from ~110 to ~44 lines for table definitions)
- Automatic address-of operator (&data) - macro handles it
- Automatic maxlen calculation via sizeof() when appropriate
- Improved readability - focus on important parameters
- Consistent formatting across all test cases

The macro automatically:
- Takes the address of 'data' variable
- Computes maxlen as sizeof(int)
- Selects proc_dointvec based on type (though explicitly provided here)
- Validates all parameters at compile time

No functional change - all tests continue to pass.

[17:55:08] ================ sysctl_test (10 subtests) =================
[17:55:08] [PASSED] sysctl_test_api_dointvec_null_tbl_data
[17:55:08] [PASSED] sysctl_test_api_dointvec_table_maxlen_unset
[17:55:08] [PASSED] sysctl_test_api_dointvec_table_len_is_zero
[17:55:08] [PASSED] sysctl_test_api_dointvec_table_read_but_position_set
[17:55:08] [PASSED] sysctl_test_dointvec_read_happy_single_positive
[17:55:08] [PASSED] sysctl_test_dointvec_read_happy_single_negative
[17:55:08] [PASSED] sysctl_test_dointvec_write_happy_single_positive
[17:55:08] [PASSED] sysctl_test_dointvec_write_happy_single_negative
[17:55:08] [PASSED] sysctl_test_api_dointvec_write_single_less_int_min
[17:55:08] [PASSED] sysctl_test_api_dointvec_write_single_greater_int_max
[17:55:08] =================== [PASSED] sysctl_test ===================
[17:55:08] ============================================================
[17:55:08] Testing complete. Ran 10 tests: passed: 10

Suggested-by: Joel Granados <joel.granados@...nel.org>
Signed-off-by: Wen Yang <wen.yang@...ux.dev>
---
 kernel/sysctl-test.c | 139 +++++++++++++------------------------------
 1 file changed, 40 insertions(+), 99 deletions(-)

diff --git a/kernel/sysctl-test.c b/kernel/sysctl-test.c
index 92f94ea28957..bacd782d8cee 100644
--- a/kernel/sysctl-test.c
+++ b/kernel/sysctl-test.c
@@ -15,20 +15,15 @@
  */
 static void sysctl_test_api_dointvec_null_tbl_data(struct kunit *test)
 {
-	struct ctl_table null_data_table = {
-		.procname = "foo",
-		/*
-		 * Here we are testing that proc_dointvec behaves correctly when
-		 * we give it a NULL .data field. Normally this would point to a
-		 * piece of memory where the value would be stored.
-		 */
-		.data		= NULL,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
-		.extra1		= SYSCTL_ZERO,
-		.extra2         = SYSCTL_ONE_HUNDRED,
-	};
+	/*
+	 * Here we are testing that proc_dointvec behaves correctly when
+	 * we give it a NULL .data field. Normally this would point to a
+	 * piece of memory where the value would be stored.
+	 */
+	struct ctl_table null_data_table = SYSCTL_TBL_ENTRY("foo", SYSCTL_NULL, 0644,\
+							    proc_dointvec, \
+							    SYSCTL_ZERO,  \
+							    SYSCTL_ONE_HUNDRED);
 	/*
 	 * proc_dointvec expects a buffer in user space, so we allocate one. We
 	 * also need to cast it to __user so sparse doesn't get mad.
@@ -66,19 +61,14 @@ static void sysctl_test_api_dointvec_null_tbl_data(struct kunit *test)
 static void sysctl_test_api_dointvec_table_maxlen_unset(struct kunit *test)
 {
 	int data = 0;
-	struct ctl_table data_maxlen_unset_table = {
-		.procname = "foo",
-		.data		= &data,
-		/*
-		 * So .data is no longer NULL, but we tell proc_dointvec its
-		 * length is 0, so it still shouldn't try to use it.
-		 */
-		.maxlen		= 0,
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
-		.extra1		= SYSCTL_ZERO,
-		.extra2         = SYSCTL_ONE_HUNDRED,
-	};
+	/*
+	 * So .data is no longer NULL, but we tell proc_dointvec its
+	 * length is 0, so it still shouldn't try to use it.
+	 */
+	struct ctl_table data_maxlen_unset_table = SYSCTL_TBL_ENTRY("foo", \
+			data, 0644, proc_dointvec,  SYSCTL_ZERO,  \
+			SYSCTL_ONE_HUNDRED, 0);
+
 	void __user *buffer = (void __user *)kunit_kzalloc(test, sizeof(int),
 							   GFP_USER);
 	size_t len;
@@ -113,15 +103,8 @@ static void sysctl_test_api_dointvec_table_len_is_zero(struct kunit *test)
 {
 	int data = 0;
 	/* Good table. */
-	struct ctl_table table = {
-		.procname = "foo",
-		.data		= &data,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
-		.extra1		= SYSCTL_ZERO,
-		.extra2         = SYSCTL_ONE_HUNDRED,
-	};
+	struct ctl_table table = SYSCTL_TBL_ENTRY("foo", \
+			data, 0644, SYSCTL_ZERO, SYSCTL_ONE_HUNDRED);
 	void __user *buffer = (void __user *)kunit_kzalloc(test, sizeof(int),
 							   GFP_USER);
 	/*
@@ -147,15 +130,9 @@ static void sysctl_test_api_dointvec_table_read_but_position_set(
 {
 	int data = 0;
 	/* Good table. */
-	struct ctl_table table = {
-		.procname = "foo",
-		.data		= &data,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
-		.extra1		= SYSCTL_ZERO,
-		.extra2         = SYSCTL_ONE_HUNDRED,
-	};
+	struct ctl_table table = SYSCTL_TBL_ENTRY("foo", data, 0644, \
+						  SYSCTL_ZERO, \
+						  SYSCTL_ONE_HUNDRED);
 	void __user *buffer = (void __user *)kunit_kzalloc(test, sizeof(int),
 							   GFP_USER);
 	/*
@@ -182,15 +159,9 @@ static void sysctl_test_dointvec_read_happy_single_positive(struct kunit *test)
 {
 	int data = 0;
 	/* Good table. */
-	struct ctl_table table = {
-		.procname = "foo",
-		.data		= &data,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
-		.extra1		= SYSCTL_ZERO,
-		.extra2         = SYSCTL_ONE_HUNDRED,
-	};
+	struct ctl_table table = SYSCTL_TBL_ENTRY("foo", data, 0644, \
+						  SYSCTL_ZERO, \
+						  SYSCTL_ONE_HUNDRED);
 	size_t len = 4;
 	loff_t pos = 0;
 	char *buffer = kunit_kzalloc(test, len, GFP_USER);
@@ -213,15 +184,9 @@ static void sysctl_test_dointvec_read_happy_single_negative(struct kunit *test)
 {
 	int data = 0;
 	/* Good table. */
-	struct ctl_table table = {
-		.procname = "foo",
-		.data		= &data,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
-		.extra1		= SYSCTL_ZERO,
-		.extra2         = SYSCTL_ONE_HUNDRED,
-	};
+	struct ctl_table table = SYSCTL_TBL_ENTRY("foo", data, 0644, \
+						  SYSCTL_ZERO, \
+						  SYSCTL_ONE_HUNDRED);
 	size_t len = 5;
 	loff_t pos = 0;
 	char *buffer = kunit_kzalloc(test, len, GFP_USER);
@@ -242,15 +207,9 @@ static void sysctl_test_dointvec_write_happy_single_positive(struct kunit *test)
 {
 	int data = 0;
 	/* Good table. */
-	struct ctl_table table = {
-		.procname = "foo",
-		.data		= &data,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
-		.extra1		= SYSCTL_ZERO,
-		.extra2         = SYSCTL_ONE_HUNDRED,
-	};
+	struct ctl_table table = SYSCTL_TBL_ENTRY("foo", data, 0644, \
+						  SYSCTL_ZERO, \
+						  SYSCTL_ONE_HUNDRED);
 	char input[] = "9";
 	size_t len = sizeof(input) - 1;
 	loff_t pos = 0;
@@ -272,15 +231,9 @@ static void sysctl_test_dointvec_write_happy_single_positive(struct kunit *test)
 static void sysctl_test_dointvec_write_happy_single_negative(struct kunit *test)
 {
 	int data = 0;
-	struct ctl_table table = {
-		.procname = "foo",
-		.data		= &data,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
-		.extra1		= SYSCTL_ZERO,
-		.extra2         = SYSCTL_ONE_HUNDRED,
-	};
+	struct ctl_table table = SYSCTL_TBL_ENTRY("foo", data, 0644, \
+						  SYSCTL_ZERO, \
+						  SYSCTL_ONE_HUNDRED);
 	char input[] = "-9";
 	size_t len = sizeof(input) - 1;
 	loff_t pos = 0;
@@ -304,15 +257,9 @@ static void sysctl_test_api_dointvec_write_single_less_int_min(
 		struct kunit *test)
 {
 	int data = 0;
-	struct ctl_table table = {
-		.procname = "foo",
-		.data		= &data,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
-		.extra1		= SYSCTL_ZERO,
-		.extra2         = SYSCTL_ONE_HUNDRED,
-	};
+	struct ctl_table table = SYSCTL_TBL_ENTRY("foo", data, 0644, \
+						  SYSCTL_ZERO, \
+						  SYSCTL_ONE_HUNDRED);
 	size_t max_len = 32, len = max_len;
 	loff_t pos = 0;
 	char *buffer = kunit_kzalloc(test, max_len, GFP_USER);
@@ -342,15 +289,9 @@ static void sysctl_test_api_dointvec_write_single_greater_int_max(
 		struct kunit *test)
 {
 	int data = 0;
-	struct ctl_table table = {
-		.procname = "foo",
-		.data		= &data,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
-		.extra1		= SYSCTL_ZERO,
-		.extra2         = SYSCTL_ONE_HUNDRED,
-	};
+	struct ctl_table table = SYSCTL_TBL_ENTRY("foo", data, 0644, \
+						  SYSCTL_ZERO, \
+						  SYSCTL_ONE_HUNDRED);
 	size_t max_len = 32, len = max_len;
 	loff_t pos = 0;
 	char *buffer = kunit_kzalloc(test, max_len, GFP_USER);
-- 
2.25.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ