linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] sysctl: Move jiffies converters out of kernel/sysctl.c
@ 2025-10-17  8:32 Joel Granados
  2025-10-17  8:32 ` [PATCH 1/7] sysctl: Allow custom converters from outside sysctl Joel Granados
                   ` (6 more replies)
  0 siblings, 7 replies; 10+ messages in thread
From: Joel Granados @ 2025-10-17  8:32 UTC (permalink / raw)
  To: Kees Cook, Alexander Viro, Christian Brauner, Jan Kara
  Cc: linux-kernel, linux-fsdevel, Joel Granados

Move the jiffies converters into kernel/time/jiffies.c and replace the
pipe-max-size proc_handler converter with a macro based version. This is
all part of the effort to relocate non-sysctl logic out of
kernel/sysctl.c into more relevant subsystems. And is based on the
preparation series in [1].

What was done?
==============

* Moved converter macros (SYSCTL_USER_TO_KERN{,_INT_CONV,UINT_CONV},
  SYSCTL_KERN_TO_USER{,INT_CONV} & SYSCTL_{,U}INT_CONV_CUSTOM) to
  sysctl.h so they can be used in jiffies.c and pipe.c.

* Moved jiffie converters (proc_dointvec_ms_jiffies{,_minmax},
  proc_dointvec{_,_userhz_}jiffies & proc_doulongvec_ms_jiffies_minmax)
  to kernel/time/jiffies.c.

* Replaced do_proc_dopipe_max_size_conv in fs/pipe.c with a macro
  version; no functional changes intended.

Why it is done?
===============

Motivation is to move non-sysctl logic out of kernel/sysctl.c which had
become a dumping ground for ctl_tables until this trend was changed by
the commits leading to (and including) 73184c8e4ff4 ("sysctl: rename
kern_table -> sysctl_subsys_table"). Same motivation as in [1].

Testing
=======

Tested by running sysctl kunit tests and selftests on x86_64 architecture
to ensure no functional regressions.

Comments are greatly appreciated

Best

[1] https://lore.kernel.org/20251016-jag-sysctl_conv-v2-0-a2f16529acc4@kernel.org

Signed-off-by: Joel Granados <joel.granados@kernel.org>
---
Joel Granados (7):
      sysctl: Allow custom converters from outside sysctl
      sysctl: Move INT converter macros to sysctl header
      sysctl: Move UINT converter macros to sysctl header
      sysctl: Move jiffies converters to kernel/time/jiffies.c
      sysctl: Move proc_doulongvec_ms_jiffies_minmax to kernel/time/jiffies.c
      sysctl: Create pipe-max-size converter using sysctl UINT macros
      sysctl: Wrap do_proc_douintvec with the public function proc_douintvec_conv

 fs/pipe.c               |  28 ++---
 include/linux/jiffies.h |  11 ++
 include/linux/sysctl.h  | 145 +++++++++++++++++++---
 kernel/sysctl.c         | 312 +++++++-----------------------------------------
 kernel/time/jiffies.c   | 125 +++++++++++++++++++
 5 files changed, 314 insertions(+), 307 deletions(-)
---
base-commit: 130e5390ba572bffa687f32ed212dac1105b654a
change-id: 20251014-jag-sysctl_jiffies-7f0145ef9b56

Best regards,
-- 
Joel Granados <joel.granados@kernel.org>



^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/7] sysctl: Allow custom converters from outside sysctl
  2025-10-17  8:32 [PATCH 0/7] sysctl: Move jiffies converters out of kernel/sysctl.c Joel Granados
@ 2025-10-17  8:32 ` Joel Granados
  2025-10-17  8:32 ` [PATCH 2/7] sysctl: Move INT converter macros to sysctl header Joel Granados
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Joel Granados @ 2025-10-17  8:32 UTC (permalink / raw)
  To: Kees Cook, Alexander Viro, Christian Brauner, Jan Kara
  Cc: linux-kernel, linux-fsdevel, Joel Granados

The new non-static proc_dointvec_conv forwards a custom converter
function to do_proc_dointvec from outside the sysctl scope. Rename the
do_proc_dointvec call points so any future changes to proc_dointvec_conv
are propagated in sysctl.c This is a preparation commit that allows the
integer jiffie converter functions to move out of kernel/sysctl.c.

Signed-off-by: Joel Granados <joel.granados@kernel.org>
---
 include/linux/sysctl.h |  4 ++++
 kernel/sysctl.c        | 32 ++++++++++++++++++++++++--------
 2 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 2d3d6c141b0b0aee21f2708450b7b41d8041a8cb..ecc8d2345006ab12520f2f6ec37379419e9295d4 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -68,6 +68,10 @@ int proc_dostring(const struct ctl_table *, int, void *, size_t *, loff_t *);
 int proc_dobool(const struct ctl_table *table, int write, void *buffer,
 		size_t *lenp, loff_t *ppos);
 int proc_dointvec(const struct ctl_table *, int, void *, size_t *, loff_t *);
+int proc_dointvec_conv(const struct ctl_table *table, int dir, void *buffer,
+		       size_t *lenp, loff_t *ppos,
+		       int (*conv)(bool *negp, unsigned long *u_ptr, int *k_ptr,
+				   int dir, const struct ctl_table *table));
 int proc_douintvec(const struct ctl_table *, int, void *, size_t *, loff_t *);
 int proc_dointvec_minmax(const struct ctl_table *, int, void *, size_t *, loff_t *);
 int proc_douintvec_minmax(const struct ctl_table *table, int write, void *buffer,
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 55d12d22a3cc476c6595b50100eef53251dac80a..6a6a2a6421f8debf75089548c82374619af32d61 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1005,6 +1005,14 @@ int proc_doulongvec_ms_jiffies_minmax(const struct ctl_table *table, int dir,
 					 lenp, ppos, HZ, 1000l);
 }
 
+int proc_dointvec_conv(const struct ctl_table *table, int dir, void *buffer,
+		       size_t *lenp, loff_t *ppos,
+		       int (*conv)(bool *negp, unsigned long *u_ptr, int *k_ptr,
+				   int dir, const struct ctl_table *table))
+{
+	return do_proc_dointvec(table, dir, buffer, lenp, ppos, conv);
+}
+
 /**
  * proc_dointvec_jiffies - read a vector of integers as seconds
  * @table: the sysctl table
@@ -1023,15 +1031,15 @@ int proc_doulongvec_ms_jiffies_minmax(const struct ctl_table *table, int dir,
 int proc_dointvec_jiffies(const struct ctl_table *table, int dir,
 			  void *buffer, size_t *lenp, loff_t *ppos)
 {
-	return do_proc_dointvec(table, dir, buffer, lenp, ppos,
-				do_proc_int_conv_jiffies);
+	return proc_dointvec_conv(table, dir, buffer, lenp, ppos,
+				  do_proc_int_conv_jiffies);
 }
 
 int proc_dointvec_ms_jiffies_minmax(const struct ctl_table *table, int dir,
 			  void *buffer, size_t *lenp, loff_t *ppos)
 {
-	return do_proc_dointvec(table, dir, buffer, lenp, ppos,
-			do_proc_int_conv_ms_jiffies_minmax);
+	return proc_dointvec_conv(table, dir, buffer, lenp, ppos,
+				  do_proc_int_conv_ms_jiffies_minmax);
 }
 
 /**
@@ -1054,8 +1062,8 @@ int proc_dointvec_userhz_jiffies(const struct ctl_table *table, int dir,
 {
 	if (USER_HZ < HZ)
 		return -EINVAL;
-	return do_proc_dointvec(table, dir, buffer, lenp, ppos,
-				do_proc_int_conv_userhz_jiffies);
+	return proc_dointvec_conv(table, dir, buffer, lenp, ppos,
+				  do_proc_int_conv_userhz_jiffies);
 }
 
 /**
@@ -1076,8 +1084,8 @@ int proc_dointvec_userhz_jiffies(const struct ctl_table *table, int dir,
 int proc_dointvec_ms_jiffies(const struct ctl_table *table, int dir, void *buffer,
 		size_t *lenp, loff_t *ppos)
 {
-	return do_proc_dointvec(table, dir, buffer, lenp, ppos,
-				do_proc_int_conv_ms_jiffies);
+	return proc_dointvec_conv(table, dir, buffer, lenp, ppos,
+				  do_proc_int_conv_ms_jiffies);
 }
 
 /**
@@ -1307,6 +1315,14 @@ int proc_doulongvec_ms_jiffies_minmax(const struct ctl_table *table, int dir,
 	return -ENOSYS;
 }
 
+int proc_dointvec_conv(const struct ctl_table *table, int dir, void *buffer,
+		       size_t *lenp, loff_t *ppos,
+		       int (*conv)(bool *negp, unsigned long *u_ptr, int *k_ptr,
+				   int dir, const struct ctl_table *table))
+{
+	return -ENOSYS;
+}
+
 int proc_do_large_bitmap(const struct ctl_table *table, int dir,
 			 void *buffer, size_t *lenp, loff_t *ppos)
 {

-- 
2.50.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/7] sysctl: Move INT converter macros to sysctl header
  2025-10-17  8:32 [PATCH 0/7] sysctl: Move jiffies converters out of kernel/sysctl.c Joel Granados
  2025-10-17  8:32 ` [PATCH 1/7] sysctl: Allow custom converters from outside sysctl Joel Granados
@ 2025-10-17  8:32 ` Joel Granados
  2025-10-17  8:32 ` [PATCH 3/7] sysctl: Move UINT " Joel Granados
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Joel Granados @ 2025-10-17  8:32 UTC (permalink / raw)
  To: Kees Cook, Alexander Viro, Christian Brauner, Jan Kara
  Cc: linux-kernel, linux-fsdevel, Joel Granados

Move direction macros (SYSCTL_{USER_TO_KERN,KERN_TO_USER}) and the
integer converter macros (SYSCTL_{USER_TO_KERN,KERN_TO_USER}_INT_CONV,
SYSCTL_INT_CONV_CUSTOM) into include/linux/sysctl.h. This is a
preparation commit to enable jiffies converter creation outside
kernel/sysctl.c.

Signed-off-by: Joel Granados <joel.granados@kernel.org>
---
 include/linux/sysctl.h | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++
 kernel/sysctl.c        | 75 --------------------------------------------------
 2 files changed, 75 insertions(+), 75 deletions(-)

diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index ecc8d2345006ab12520f2f6ec37379419e9295d4..967a9ad6b4200266e2d9c6cfa9ee58fb8bf51090 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -59,6 +59,81 @@ extern const int sysctl_vals[];
 #define SYSCTL_LONG_ONE		((void *)&sysctl_long_vals[1])
 #define SYSCTL_LONG_MAX		((void *)&sysctl_long_vals[2])
 
+/**
+ *
+ * "dir" originates from read_iter (dir = 0) or write_iter (dir = 1)
+ * in the file_operations struct at proc/proc_sysctl.c. Its value means
+ * one of two things for sysctl:
+ * 1. SYSCTL_USER_TO_KERN(dir) Writing to an internal kernel variable from user
+ *                             space (dir > 0)
+ * 2. SYSCTL_KERN_TO_USER(dir) Writing to a user space buffer from a kernel
+ *                             variable (dir == 0).
+ */
+#define SYSCTL_USER_TO_KERN(dir) (!!(dir))
+#define SYSCTL_KERN_TO_USER(dir) (!dir)
+
+#define SYSCTL_USER_TO_KERN_INT_CONV(name, u_ptr_op)		\
+int sysctl_user_to_kern_int_conv##name(const bool *negp,	\
+				       const unsigned long *u_ptr,\
+				       int *k_ptr)		\
+{								\
+	unsigned long u = u_ptr_op(*u_ptr);			\
+	if (*negp) {						\
+		if (u > (unsigned long) INT_MAX + 1)		\
+			return -EINVAL;				\
+		WRITE_ONCE(*k_ptr, -u);				\
+	} else {						\
+		if (u > (unsigned long) INT_MAX)		\
+			return -EINVAL;				\
+		WRITE_ONCE(*k_ptr, u);				\
+	}							\
+	return 0;						\
+}
+
+#define SYSCTL_KERN_TO_USER_INT_CONV(name, k_ptr_op)		\
+int sysctl_kern_to_user_int_conv##name(bool *negp,		\
+				       unsigned long *u_ptr,	\
+				       const int *k_ptr)	\
+{								\
+	int val = READ_ONCE(*k_ptr);				\
+	if (val < 0) {						\
+		*negp = true;					\
+		*u_ptr = -k_ptr_op((unsigned long)val);		\
+	} else {						\
+		*negp = false;					\
+		*u_ptr = k_ptr_op((unsigned long)val);		\
+	}							\
+	return 0;						\
+}
+
+/**
+ * To range check on a converted value, use a temp k_ptr
+ * When checking range, value should be within (tbl->extra1, tbl->extra2)
+ */
+#define SYSCTL_INT_CONV_CUSTOM(name, user_to_kern, kern_to_user,	\
+			       k_ptr_range_check)			\
+int do_proc_int_conv##name(bool *negp, unsigned long *u_ptr, int *k_ptr,\
+			   int dir, const struct ctl_table *tbl)	\
+{									\
+	if (SYSCTL_KERN_TO_USER(dir))					\
+		return kern_to_user(negp, u_ptr, k_ptr);		\
+									\
+	if (k_ptr_range_check) {					\
+		int tmp_k, ret;						\
+		if (!tbl)						\
+			return -EINVAL;					\
+		ret = user_to_kern(negp, u_ptr, &tmp_k);		\
+		if (ret)						\
+			return ret;					\
+		if ((tbl->extra1 && *(int *)tbl->extra1 > tmp_k) ||	\
+		    (tbl->extra2 && *(int *)tbl->extra2 < tmp_k))	\
+			return -EINVAL;					\
+		WRITE_ONCE(*k_ptr, tmp_k);				\
+	} else								\
+		return user_to_kern(negp, u_ptr, k_ptr);		\
+	return 0;							\
+}
+
 extern const unsigned long sysctl_long_vals[];
 
 typedef int proc_handler(const struct ctl_table *ctl, int write, void *buffer,
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 6a6a2a6421f8debf75089548c82374619af32d61..70cf23d9834ef4e6b95ab80a3dc7a06237742793 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -30,19 +30,6 @@ EXPORT_SYMBOL(sysctl_vals);
 const unsigned long sysctl_long_vals[] = { 0, 1, LONG_MAX };
 EXPORT_SYMBOL_GPL(sysctl_long_vals);
 
-/**
- *
- * "dir" originates from read_iter (dir = 0) or write_iter (dir = 1)
- * in the file_operations struct at proc/proc_sysctl.c. Its value means
- * one of two things for sysctl:
- * 1. SYSCTL_USER_TO_KERN(dir) Writing to an internal kernel variable from user
- *                             space (dir > 0)
- * 2. SYSCTL_KERN_TO_USER(dir) Writing to a user space buffer from a kernel
- *                             variable (dir == 0).
- */
-#define SYSCTL_USER_TO_KERN(dir) (!!(dir))
-#define SYSCTL_KERN_TO_USER(dir) (!dir)
-
 #if defined(CONFIG_SYSCTL)
 
 /* Constants used for minimum and maximum */
@@ -368,68 +355,6 @@ static void proc_put_char(void **buf, size_t *size, char c)
 	}
 }
 
-#define SYSCTL_USER_TO_KERN_INT_CONV(name, u_ptr_op)		\
-int sysctl_user_to_kern_int_conv##name(const bool *negp,	\
-				       const unsigned long *u_ptr,\
-				       int *k_ptr)		\
-{								\
-	unsigned long u = u_ptr_op(*u_ptr);			\
-	if (*negp) {						\
-		if (u > (unsigned long) INT_MAX + 1)		\
-			return -EINVAL;				\
-		WRITE_ONCE(*k_ptr, -u);				\
-	} else {						\
-		if (u > (unsigned long) INT_MAX)		\
-			return -EINVAL;				\
-		WRITE_ONCE(*k_ptr, u);				\
-	}							\
-	return 0;						\
-}
-
-#define SYSCTL_KERN_TO_USER_INT_CONV(name, k_ptr_op)		\
-int sysctl_kern_to_user_int_conv##name(bool *negp,		\
-				       unsigned long *u_ptr,	\
-				       const int *k_ptr)	\
-{								\
-	int val = READ_ONCE(*k_ptr);				\
-	if (val < 0) {						\
-		*negp = true;					\
-		*u_ptr = -k_ptr_op((unsigned long)val);		\
-	} else {						\
-		*negp = false;					\
-		*u_ptr = k_ptr_op((unsigned long)val);		\
-	}							\
-	return 0;						\
-}
-
-/**
- * To range check on a converted value, use a temp k_ptr
- * When checking range, value should be within (tbl->extra1, tbl->extra2)
- */
-#define SYSCTL_INT_CONV_CUSTOM(name, user_to_kern, kern_to_user,	\
-			       k_ptr_range_check)			\
-int do_proc_int_conv##name(bool *negp, unsigned long *u_ptr, int *k_ptr,\
-			   int dir, const struct ctl_table *tbl)	\
-{									\
-	if (SYSCTL_KERN_TO_USER(dir))					\
-		return kern_to_user(negp, u_ptr, k_ptr);		\
-									\
-	if (k_ptr_range_check) {					\
-		int tmp_k, ret;						\
-		if (!tbl)						\
-			return -EINVAL;					\
-		ret = user_to_kern(negp, u_ptr, &tmp_k);		\
-		if (ret)						\
-			return ret;					\
-		if ((tbl->extra1 && *(int *)tbl->extra1 > tmp_k) ||	\
-		    (tbl->extra2 && *(int *)tbl->extra2 < tmp_k))	\
-			return -EINVAL;					\
-		WRITE_ONCE(*k_ptr, tmp_k);				\
-	} else								\
-		return user_to_kern(negp, u_ptr, k_ptr);		\
-	return 0;							\
-}
-
 #define SYSCTL_CONV_IDENTITY(val) val
 #define SYSCTL_CONV_MULT_HZ(val) ((val) * HZ)
 #define SYSCTL_CONV_DIV_HZ(val) ((val) / HZ)

-- 
2.50.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/7] sysctl: Move UINT converter macros to sysctl header
  2025-10-17  8:32 [PATCH 0/7] sysctl: Move jiffies converters out of kernel/sysctl.c Joel Granados
  2025-10-17  8:32 ` [PATCH 1/7] sysctl: Allow custom converters from outside sysctl Joel Granados
  2025-10-17  8:32 ` [PATCH 2/7] sysctl: Move INT converter macros to sysctl header Joel Granados
@ 2025-10-17  8:32 ` Joel Granados
  2025-10-17  8:32 ` [PATCH 4/7] sysctl: Move jiffies converters to kernel/time/jiffies.c Joel Granados
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Joel Granados @ 2025-10-17  8:32 UTC (permalink / raw)
  To: Kees Cook, Alexander Viro, Christian Brauner, Jan Kara
  Cc: linux-kernel, linux-fsdevel, Joel Granados

Move SYSCTL_USER_TO_KERN_UINT_CONV and SYSCTL_UINT_CONV_CUSTOM macros to
include/linux/sysctl.h. No need to embed sysctl_kern_to_user_uint_conv
in a macro as it will not need a custom kernel pointer operation. This
is a preparation commit to enable jiffies converter creation outside
kernel/sysctl.c.

Signed-off-by: Joel Granados <joel.granados@kernel.org>
---
 include/linux/sysctl.h | 40 ++++++++++++++++++++++++++++++++++++++++
 kernel/sysctl.c        | 42 ++----------------------------------------
 2 files changed, 42 insertions(+), 40 deletions(-)

diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 967a9ad6b4200266e2d9c6cfa9ee58fb8bf51090..faeeb2feefb83d5b57e67f5cbf2eadf79dd03fb2 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -134,6 +134,45 @@ int do_proc_int_conv##name(bool *negp, unsigned long *u_ptr, int *k_ptr,\
 	return 0;							\
 }
 
+#define SYSCTL_USER_TO_KERN_UINT_CONV(name, u_ptr_op)		\
+int sysctl_user_to_kern_uint_conv##name(const unsigned long *u_ptr,\
+					unsigned int *k_ptr)	\
+{								\
+	unsigned long u = u_ptr_op(*u_ptr);			\
+	if (u > UINT_MAX)					\
+		return -EINVAL;					\
+	WRITE_ONCE(*k_ptr, u);					\
+	return 0;						\
+}
+
+#define SYSCTL_UINT_CONV_CUSTOM(name, user_to_kern, kern_to_user,	\
+				k_ptr_range_check)			\
+int do_proc_uint_conv##name(unsigned long *u_ptr, unsigned int *k_ptr,	\
+			   int dir, const struct ctl_table *tbl)	\
+{									\
+	if (SYSCTL_KERN_TO_USER(dir))					\
+		return kern_to_user(u_ptr, k_ptr);			\
+									\
+	if (k_ptr_range_check) {					\
+		unsigned int tmp_k;					\
+		int ret;						\
+		if (!tbl)						\
+			return -EINVAL;					\
+		ret = user_to_kern(u_ptr, &tmp_k);			\
+		if (ret)						\
+			return ret;					\
+		if ((tbl->extra1 &&					\
+		     *(unsigned int *)tbl->extra1 > tmp_k) ||		\
+		    (tbl->extra2 &&					\
+		     *(unsigned int *)tbl->extra2 < tmp_k))		\
+			return -ERANGE;					\
+		WRITE_ONCE(*k_ptr, tmp_k);				\
+	} else								\
+		return user_to_kern(u_ptr, k_ptr);			\
+	return 0;							\
+}
+
+
 extern const unsigned long sysctl_long_vals[];
 
 typedef int proc_handler(const struct ctl_table *ctl, int write, void *buffer,
@@ -166,6 +205,7 @@ int proc_doulongvec_ms_jiffies_minmax(const struct ctl_table *table, int, void *
 int proc_do_large_bitmap(const struct ctl_table *, int, void *, size_t *, loff_t *);
 int proc_do_static_key(const struct ctl_table *table, int write, void *buffer,
 		size_t *lenp, loff_t *ppos);
+int sysctl_kern_to_user_uint_conv(unsigned long *u_ptr, const unsigned int *k_ptr);
 
 /*
  * Register a set of sysctl names by calling register_sysctl
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 70cf23d9834ef4e6b95ab80a3dc7a06237742793..f3d2385f88494da1e5ba7ee1fbb575d2545d7d84 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -387,54 +387,16 @@ static SYSCTL_INT_CONV_CUSTOM(_ms_jiffies_minmax,
 			      sysctl_user_to_kern_int_conv_ms,
 			      sysctl_kern_to_user_int_conv_ms, true)
 
-#define SYSCTL_USER_TO_KERN_UINT_CONV(name, u_ptr_op)		\
-int sysctl_user_to_kern_uint_conv##name(const unsigned long *u_ptr,\
-					unsigned int *k_ptr)	\
-{								\
-	unsigned long u = u_ptr_op(*u_ptr);			\
-	if (u > UINT_MAX)					\
-		return -EINVAL;					\
-	WRITE_ONCE(*k_ptr, u);					\
-	return 0;						\
-}
-
 static SYSCTL_USER_TO_KERN_UINT_CONV(,SYSCTL_CONV_IDENTITY)
 
-static int sysctl_kern_to_user_uint_conv(unsigned long *u_ptr,
-					 const unsigned int *k_ptr)
+int sysctl_kern_to_user_uint_conv(unsigned long *u_ptr,
+				  const unsigned int *k_ptr)
 {
 	unsigned int val = READ_ONCE(*k_ptr);
 	*u_ptr = (unsigned long)val;
 	return 0;
 }
 
-#define SYSCTL_UINT_CONV_CUSTOM(name, user_to_kern, kern_to_user,	\
-				k_ptr_range_check)			\
-int do_proc_uint_conv##name(unsigned long *u_ptr, unsigned int *k_ptr,	\
-			   int dir, const struct ctl_table *tbl)	\
-{									\
-	if (SYSCTL_KERN_TO_USER(dir))					\
-		return kern_to_user(u_ptr, k_ptr);			\
-									\
-	if (k_ptr_range_check) {					\
-		unsigned int tmp_k;					\
-		int ret;						\
-		if (!tbl)						\
-			return -EINVAL;					\
-		ret = user_to_kern(u_ptr, &tmp_k);			\
-		if (ret)						\
-			return ret;					\
-		if ((tbl->extra1 &&					\
-		     *(unsigned int *)tbl->extra1 > tmp_k) ||		\
-		    (tbl->extra2 &&					\
-		     *(unsigned int *)tbl->extra2 < tmp_k))		\
-			return -ERANGE;					\
-		WRITE_ONCE(*k_ptr, tmp_k);				\
-	} else								\
-		return user_to_kern(u_ptr, k_ptr);			\
-	return 0;							\
-}
-
 static SYSCTL_UINT_CONV_CUSTOM(, sysctl_user_to_kern_uint_conv,
 			       sysctl_kern_to_user_uint_conv, false)
 static SYSCTL_UINT_CONV_CUSTOM(_minmax, sysctl_user_to_kern_uint_conv,

-- 
2.50.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/7] sysctl: Move jiffies converters to kernel/time/jiffies.c
  2025-10-17  8:32 [PATCH 0/7] sysctl: Move jiffies converters out of kernel/sysctl.c Joel Granados
                   ` (2 preceding siblings ...)
  2025-10-17  8:32 ` [PATCH 3/7] sysctl: Move UINT " Joel Granados
@ 2025-10-17  8:32 ` Joel Granados
  2025-10-17  8:32 ` [PATCH 5/7] sysctl: Move proc_doulongvec_ms_jiffies_minmax " Joel Granados
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Joel Granados @ 2025-10-17  8:32 UTC (permalink / raw)
  To: Kees Cook, Alexander Viro, Christian Brauner, Jan Kara
  Cc: linux-kernel, linux-fsdevel, Joel Granados

Move integer jiffies converters (proc_dointvec{_,_ms_,_userhz_}jiffies
and proc_dointvec_ms_jiffies_minmax) to kernel/time/jiffies.c. Error
stubs for when CONFIG_PRCO_SYSCTL is not defined are not reproduced
because all the jiffies converters go through proc_dointvec_conv which
is already stubbed. This is part of the greater effort to move sysctl
logic out of kernel/sysctl.c thereby reducing merge conflicts in
kernel/sysctl.c.

Signed-off-by: Joel Granados <joel.granados@kernel.org>
---
 include/linux/jiffies.h |   9 ++++
 include/linux/sysctl.h  |   7 ---
 kernel/sysctl.c         | 124 ------------------------------------------------
 kernel/time/jiffies.c   | 100 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 109 insertions(+), 131 deletions(-)

diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
index 91b20788273dfa224d68fbc84388c297b335af47..09886dcbf718873adf3c24d7eb565f1849fcac04 100644
--- a/include/linux/jiffies.h
+++ b/include/linux/jiffies.h
@@ -611,4 +611,13 @@ extern unsigned long nsecs_to_jiffies(u64 n);
 
 #define TIMESTAMP_SIZE	30
 
+int proc_dointvec_jiffies(const struct ctl_table *table, int dir, void *buffer,
+			  size_t *lenp, loff_t *ppos);
+int proc_dointvec_ms_jiffies_minmax(const struct ctl_table *table, int dir,
+				    void *buffer, size_t *lenp, loff_t *ppos);
+int proc_dointvec_userhz_jiffies(const struct ctl_table *table, int dir,
+				 void *buffer, size_t *lenp, loff_t *ppos);
+int proc_dointvec_ms_jiffies(const struct ctl_table *table, int dir, void *buffer,
+			     size_t *lenp, loff_t *ppos);
+
 #endif
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index faeeb2feefb83d5b57e67f5cbf2eadf79dd03fb2..4894244ade479a84d736e239e33e0a8d3a0f803d 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -192,13 +192,6 @@ int proc_douintvec_minmax(const struct ctl_table *table, int write, void *buffer
 		size_t *lenp, loff_t *ppos);
 int proc_dou8vec_minmax(const struct ctl_table *table, int write, void *buffer,
 			size_t *lenp, loff_t *ppos);
-int proc_dointvec_jiffies(const struct ctl_table *, int, void *, size_t *, loff_t *);
-int proc_dointvec_ms_jiffies_minmax(const struct ctl_table *table, int write,
-		void *buffer, size_t *lenp, loff_t *ppos);
-int proc_dointvec_userhz_jiffies(const struct ctl_table *, int, void *, size_t *,
-		loff_t *);
-int proc_dointvec_ms_jiffies(const struct ctl_table *, int, void *, size_t *,
-		loff_t *);
 int proc_doulongvec_minmax(const struct ctl_table *, int, void *, size_t *, loff_t *);
 int proc_doulongvec_ms_jiffies_minmax(const struct ctl_table *table, int, void *,
 		size_t *, loff_t *);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index f3d2385f88494da1e5ba7ee1fbb575d2545d7d84..e00dd55487025fa159eac2f656104c0c843b0519 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -356,36 +356,14 @@ static void proc_put_char(void **buf, size_t *size, char c)
 }
 
 #define SYSCTL_CONV_IDENTITY(val) val
-#define SYSCTL_CONV_MULT_HZ(val) ((val) * HZ)
-#define SYSCTL_CONV_DIV_HZ(val) ((val) / HZ)
 
 static SYSCTL_USER_TO_KERN_INT_CONV(, SYSCTL_CONV_IDENTITY)
 static SYSCTL_KERN_TO_USER_INT_CONV(, SYSCTL_CONV_IDENTITY)
 
-static SYSCTL_USER_TO_KERN_INT_CONV(_hz, SYSCTL_CONV_MULT_HZ)
-static SYSCTL_KERN_TO_USER_INT_CONV(_hz, SYSCTL_CONV_DIV_HZ)
-
-static SYSCTL_USER_TO_KERN_INT_CONV(_userhz, clock_t_to_jiffies)
-static SYSCTL_KERN_TO_USER_INT_CONV(_userhz, jiffies_to_clock_t)
-
-static SYSCTL_USER_TO_KERN_INT_CONV(_ms, msecs_to_jiffies)
-static SYSCTL_KERN_TO_USER_INT_CONV(_ms, jiffies_to_msecs)
-
 static SYSCTL_INT_CONV_CUSTOM(, sysctl_user_to_kern_int_conv,
 			      sysctl_kern_to_user_int_conv, false)
-static SYSCTL_INT_CONV_CUSTOM(_jiffies, sysctl_user_to_kern_int_conv_hz,
-			      sysctl_kern_to_user_int_conv_hz, false)
-static SYSCTL_INT_CONV_CUSTOM(_userhz_jiffies,
-			      sysctl_user_to_kern_int_conv_userhz,
-			      sysctl_kern_to_user_int_conv_userhz, false)
-static SYSCTL_INT_CONV_CUSTOM(_ms_jiffies, sysctl_user_to_kern_int_conv_ms,
-			      sysctl_kern_to_user_int_conv_ms, false)
-
 static SYSCTL_INT_CONV_CUSTOM(_minmax, sysctl_user_to_kern_int_conv,
 			      sysctl_kern_to_user_int_conv, true)
-static SYSCTL_INT_CONV_CUSTOM(_ms_jiffies_minmax,
-			      sysctl_user_to_kern_int_conv_ms,
-			      sysctl_kern_to_user_int_conv_ms, true)
 
 static SYSCTL_USER_TO_KERN_UINT_CONV(,SYSCTL_CONV_IDENTITY)
 
@@ -900,81 +878,6 @@ int proc_dointvec_conv(const struct ctl_table *table, int dir, void *buffer,
 	return do_proc_dointvec(table, dir, buffer, lenp, ppos, conv);
 }
 
-/**
- * proc_dointvec_jiffies - read a vector of integers as seconds
- * @table: the sysctl table
- * @dir: %TRUE if this is a write to the sysctl file
- * @buffer: the user buffer
- * @lenp: the size of the user buffer
- * @ppos: file position
- *
- * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
- * values from/to the user buffer, treated as an ASCII string.
- * The values read are assumed to be in seconds, and are converted into
- * jiffies.
- *
- * Returns 0 on success.
- */
-int proc_dointvec_jiffies(const struct ctl_table *table, int dir,
-			  void *buffer, size_t *lenp, loff_t *ppos)
-{
-	return proc_dointvec_conv(table, dir, buffer, lenp, ppos,
-				  do_proc_int_conv_jiffies);
-}
-
-int proc_dointvec_ms_jiffies_minmax(const struct ctl_table *table, int dir,
-			  void *buffer, size_t *lenp, loff_t *ppos)
-{
-	return proc_dointvec_conv(table, dir, buffer, lenp, ppos,
-				  do_proc_int_conv_ms_jiffies_minmax);
-}
-
-/**
- * proc_dointvec_userhz_jiffies - read a vector of integers as 1/USER_HZ seconds
- * @table: the sysctl table
- * @dir: %TRUE if this is a write to the sysctl file
- * @buffer: the user buffer
- * @lenp: the size of the user buffer
- * @ppos: pointer to the file position
- *
- * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
- * values from/to the user buffer, treated as an ASCII string.
- * The values read are assumed to be in 1/USER_HZ seconds, and
- * are converted into jiffies.
- *
- * Returns 0 on success.
- */
-int proc_dointvec_userhz_jiffies(const struct ctl_table *table, int dir,
-				 void *buffer, size_t *lenp, loff_t *ppos)
-{
-	if (USER_HZ < HZ)
-		return -EINVAL;
-	return proc_dointvec_conv(table, dir, buffer, lenp, ppos,
-				  do_proc_int_conv_userhz_jiffies);
-}
-
-/**
- * proc_dointvec_ms_jiffies - read a vector of integers as 1 milliseconds
- * @table: the sysctl table
- * @dir: %TRUE if this is a write to the sysctl file
- * @buffer: the user buffer
- * @lenp: the size of the user buffer
- * @ppos: the current position in the file
- *
- * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
- * values from/to the user buffer, treated as an ASCII string.
- * The values read are assumed to be in 1/1000 seconds, and
- * are converted into jiffies.
- *
- * Returns 0 on success.
- */
-int proc_dointvec_ms_jiffies(const struct ctl_table *table, int dir, void *buffer,
-		size_t *lenp, loff_t *ppos)
-{
-	return proc_dointvec_conv(table, dir, buffer, lenp, ppos,
-				  do_proc_int_conv_ms_jiffies);
-}
-
 /**
  * proc_do_large_bitmap - read/write from/to a large bitmap
  * @table: the sysctl table
@@ -1166,30 +1069,6 @@ int proc_dou8vec_minmax(const struct ctl_table *table, int dir,
 	return -ENOSYS;
 }
 
-int proc_dointvec_jiffies(const struct ctl_table *table, int dir,
-		    void *buffer, size_t *lenp, loff_t *ppos)
-{
-	return -ENOSYS;
-}
-
-int proc_dointvec_ms_jiffies_minmax(const struct ctl_table *table, int dir,
-				    void *buffer, size_t *lenp, loff_t *ppos)
-{
-	return -ENOSYS;
-}
-
-int proc_dointvec_userhz_jiffies(const struct ctl_table *table, int dir,
-		    void *buffer, size_t *lenp, loff_t *ppos)
-{
-	return -ENOSYS;
-}
-
-int proc_dointvec_ms_jiffies(const struct ctl_table *table, int dir,
-			     void *buffer, size_t *lenp, loff_t *ppos)
-{
-	return -ENOSYS;
-}
-
 int proc_doulongvec_minmax(const struct ctl_table *table, int dir,
 		    void *buffer, size_t *lenp, loff_t *ppos)
 {
@@ -1309,11 +1188,8 @@ int __init sysctl_init_bases(void)
 EXPORT_SYMBOL(proc_dobool);
 EXPORT_SYMBOL(proc_dointvec);
 EXPORT_SYMBOL(proc_douintvec);
-EXPORT_SYMBOL(proc_dointvec_jiffies);
 EXPORT_SYMBOL(proc_dointvec_minmax);
 EXPORT_SYMBOL_GPL(proc_douintvec_minmax);
-EXPORT_SYMBOL(proc_dointvec_userhz_jiffies);
-EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
 EXPORT_SYMBOL(proc_dostring);
 EXPORT_SYMBOL(proc_doulongvec_minmax);
 EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
diff --git a/kernel/time/jiffies.c b/kernel/time/jiffies.c
index 34eeacac225391667e168ec4e1d7261175388d51..2289c11c8bfc218304a620a3541109e281b4e581 100644
--- a/kernel/time/jiffies.c
+++ b/kernel/time/jiffies.c
@@ -99,3 +99,103 @@ void __init register_refined_jiffies(long cycles_per_second)
 
 	__clocksource_register(&refined_jiffies);
 }
+
+#define SYSCTL_CONV_MULT_HZ(val) ((val) * HZ)
+#define SYSCTL_CONV_DIV_HZ(val) ((val) / HZ)
+
+static SYSCTL_USER_TO_KERN_INT_CONV(_hz, SYSCTL_CONV_MULT_HZ)
+static SYSCTL_KERN_TO_USER_INT_CONV(_hz, SYSCTL_CONV_DIV_HZ)
+static SYSCTL_USER_TO_KERN_INT_CONV(_userhz, clock_t_to_jiffies)
+static SYSCTL_KERN_TO_USER_INT_CONV(_userhz, jiffies_to_clock_t)
+static SYSCTL_USER_TO_KERN_INT_CONV(_ms, msecs_to_jiffies)
+static SYSCTL_KERN_TO_USER_INT_CONV(_ms, jiffies_to_msecs)
+
+static SYSCTL_INT_CONV_CUSTOM(_jiffies, sysctl_user_to_kern_int_conv_hz,
+			      sysctl_kern_to_user_int_conv_hz, false)
+static SYSCTL_INT_CONV_CUSTOM(_userhz_jiffies,
+			      sysctl_user_to_kern_int_conv_userhz,
+			      sysctl_kern_to_user_int_conv_userhz, false)
+static SYSCTL_INT_CONV_CUSTOM(_ms_jiffies, sysctl_user_to_kern_int_conv_ms,
+			      sysctl_kern_to_user_int_conv_ms, false)
+static SYSCTL_INT_CONV_CUSTOM(_ms_jiffies_minmax,
+			      sysctl_user_to_kern_int_conv_ms,
+			      sysctl_kern_to_user_int_conv_ms, true)
+
+/**
+ * proc_dointvec_jiffies - read a vector of integers as seconds
+ * @table: the sysctl table
+ * @dir: %TRUE if this is a write to the sysctl file
+ * @buffer: the user buffer
+ * @lenp: the size of the user buffer
+ * @ppos: file position
+ *
+ * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
+ * values from/to the user buffer, treated as an ASCII string.
+ * The values read are assumed to be in seconds, and are converted into
+ * jiffies.
+ *
+ * Returns 0 on success.
+ */
+int proc_dointvec_jiffies(const struct ctl_table *table, int dir,
+			  void *buffer, size_t *lenp, loff_t *ppos)
+{
+	return proc_dointvec_conv(table, dir, buffer, lenp, ppos,
+				  do_proc_int_conv_jiffies);
+}
+EXPORT_SYMBOL(proc_dointvec_jiffies);
+
+/**
+ * proc_dointvec_userhz_jiffies - read a vector of integers as 1/USER_HZ seconds
+ * @table: the sysctl table
+ * @dir: %TRUE if this is a write to the sysctl file
+ * @buffer: the user buffer
+ * @lenp: the size of the user buffer
+ * @ppos: pointer to the file position
+ *
+ * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
+ * values from/to the user buffer, treated as an ASCII string.
+ * The values read are assumed to be in 1/USER_HZ seconds, and
+ * are converted into jiffies.
+ *
+ * Returns 0 on success.
+ */
+int proc_dointvec_userhz_jiffies(const struct ctl_table *table, int dir,
+				 void *buffer, size_t *lenp, loff_t *ppos)
+{
+	if (USER_HZ < HZ)
+		return -EINVAL;
+	return proc_dointvec_conv(table, dir, buffer, lenp, ppos,
+				  do_proc_int_conv_userhz_jiffies);
+}
+EXPORT_SYMBOL(proc_dointvec_userhz_jiffies);
+
+/**
+ * proc_dointvec_ms_jiffies - read a vector of integers as 1 milliseconds
+ * @table: the sysctl table
+ * @dir: %TRUE if this is a write to the sysctl file
+ * @buffer: the user buffer
+ * @lenp: the size of the user buffer
+ * @ppos: the current position in the file
+ *
+ * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
+ * values from/to the user buffer, treated as an ASCII string.
+ * The values read are assumed to be in 1/1000 seconds, and
+ * are converted into jiffies.
+ *
+ * Returns 0 on success.
+ */
+int proc_dointvec_ms_jiffies(const struct ctl_table *table, int dir, void *buffer,
+		size_t *lenp, loff_t *ppos)
+{
+	return proc_dointvec_conv(table, dir, buffer, lenp, ppos,
+				  do_proc_int_conv_ms_jiffies);
+}
+
+int proc_dointvec_ms_jiffies_minmax(const struct ctl_table *table, int dir,
+			  void *buffer, size_t *lenp, loff_t *ppos)
+{
+	return proc_dointvec_conv(table, dir, buffer, lenp, ppos,
+				  do_proc_int_conv_ms_jiffies_minmax);
+}
+EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
+

-- 
2.50.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5/7] sysctl: Move proc_doulongvec_ms_jiffies_minmax to kernel/time/jiffies.c
  2025-10-17  8:32 [PATCH 0/7] sysctl: Move jiffies converters out of kernel/sysctl.c Joel Granados
                   ` (3 preceding siblings ...)
  2025-10-17  8:32 ` [PATCH 4/7] sysctl: Move jiffies converters to kernel/time/jiffies.c Joel Granados
@ 2025-10-17  8:32 ` Joel Granados
  2025-10-17  8:32 ` [PATCH 6/7] sysctl: Create pipe-max-size converter using sysctl UINT macros Joel Granados
  2025-10-17  8:32 ` [PATCH 7/7] sysctl: Wrap do_proc_douintvec with the public function proc_douintvec_conv Joel Granados
  6 siblings, 0 replies; 10+ messages in thread
From: Joel Granados @ 2025-10-17  8:32 UTC (permalink / raw)
  To: Kees Cook, Alexander Viro, Christian Brauner, Jan Kara
  Cc: linux-kernel, linux-fsdevel, Joel Granados

Move proc_doulongvec_ms_jiffies_minmax to kernel/time/jiffies.c. Create
a non static wrapper function proc_doulongvec_minmax_conv that
forwards the custom convmul and convdiv argument values to the internal
do_proc_doulongvec_minmax. Remove unused linux/times.h include from
kernel/sysctl.c.

Signed-off-by: Joel Granados <joel.granados@kernel.org>
---
 include/linux/jiffies.h |  2 ++
 include/linux/sysctl.h  |  5 +++--
 kernel/sysctl.c         | 41 ++++++++++++-----------------------------
 kernel/time/jiffies.c   | 27 ++++++++++++++++++++++++++-
 4 files changed, 43 insertions(+), 32 deletions(-)

diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
index 09886dcbf718873adf3c24d7eb565f1849fcac04..2687263c31d9b0d575996228d9aa63071bea60b5 100644
--- a/include/linux/jiffies.h
+++ b/include/linux/jiffies.h
@@ -619,5 +619,7 @@ int proc_dointvec_userhz_jiffies(const struct ctl_table *table, int dir,
 				 void *buffer, size_t *lenp, loff_t *ppos);
 int proc_dointvec_ms_jiffies(const struct ctl_table *table, int dir, void *buffer,
 			     size_t *lenp, loff_t *ppos);
+int proc_doulongvec_ms_jiffies_minmax(const struct ctl_table *table, int dir,
+				      void *buffer, size_t *lenp, loff_t *ppos);
 
 #endif
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 4894244ade479a84d736e239e33e0a8d3a0f803d..9396bb421cd5e1e9076de0c77c45a870c453aee1 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -193,8 +193,9 @@ int proc_douintvec_minmax(const struct ctl_table *table, int write, void *buffer
 int proc_dou8vec_minmax(const struct ctl_table *table, int write, void *buffer,
 			size_t *lenp, loff_t *ppos);
 int proc_doulongvec_minmax(const struct ctl_table *, int, void *, size_t *, loff_t *);
-int proc_doulongvec_ms_jiffies_minmax(const struct ctl_table *table, int, void *,
-		size_t *, loff_t *);
+int proc_doulongvec_minmax_conv(const struct ctl_table *table, int dir,
+				void *buffer, size_t *lenp, loff_t *ppos,
+				unsigned long convmul, unsigned long convdiv);
 int proc_do_large_bitmap(const struct ctl_table *, int, void *, size_t *, loff_t *);
 int proc_do_static_key(const struct ctl_table *table, int write, void *buffer,
 		size_t *lenp, loff_t *ppos);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index e00dd55487025fa159eac2f656104c0c843b0519..6750ddbc15b2bb9ee9de0d48ac999a4c3a2ec5d6 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -13,7 +13,6 @@
 #include <linux/highuid.h>
 #include <linux/writeback.h>
 #include <linux/initrd.h>
-#include <linux/times.h>
 #include <linux/limits.h>
 #include <linux/syscalls.h>
 #include <linux/capability.h>
@@ -824,6 +823,14 @@ static int do_proc_doulongvec_minmax(const struct ctl_table *table, int dir,
 	return err;
 }
 
+int proc_doulongvec_minmax_conv(const struct ctl_table *table, int dir,
+				void *buffer, size_t *lenp, loff_t *ppos,
+				unsigned long convmul, unsigned long convdiv)
+{
+	return do_proc_doulongvec_minmax(table, dir, buffer, lenp, ppos,
+					 convmul, convdiv);
+}
+
 /**
  * proc_doulongvec_minmax - read a vector of long integers with min/max values
  * @table: the sysctl table
@@ -843,31 +850,7 @@ static int do_proc_doulongvec_minmax(const struct ctl_table *table, int dir,
 int proc_doulongvec_minmax(const struct ctl_table *table, int dir,
 			   void *buffer, size_t *lenp, loff_t *ppos)
 {
-	return do_proc_doulongvec_minmax(table, dir, buffer, lenp, ppos, 1l, 1l);
-}
-
-/**
- * proc_doulongvec_ms_jiffies_minmax - read a vector of millisecond values with min/max values
- * @table: the sysctl table
- * @dir: %TRUE if this is a write to the sysctl file
- * @buffer: the user buffer
- * @lenp: the size of the user buffer
- * @ppos: file position
- *
- * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
- * values from/to the user buffer, treated as an ASCII string. The values
- * are treated as milliseconds, and converted to jiffies when they are stored.
- *
- * This routine will ensure the values are within the range specified by
- * table->extra1 (min) and table->extra2 (max).
- *
- * Returns 0 on success.
- */
-int proc_doulongvec_ms_jiffies_minmax(const struct ctl_table *table, int dir,
-				      void *buffer, size_t *lenp, loff_t *ppos)
-{
-	return do_proc_doulongvec_minmax(table, dir, buffer,
-					 lenp, ppos, HZ, 1000l);
+	return proc_doulongvec_minmax_conv(table, dir, buffer, lenp, ppos, 1l, 1l);
 }
 
 int proc_dointvec_conv(const struct ctl_table *table, int dir, void *buffer,
@@ -1075,8 +1058,9 @@ int proc_doulongvec_minmax(const struct ctl_table *table, int dir,
 	return -ENOSYS;
 }
 
-int proc_doulongvec_ms_jiffies_minmax(const struct ctl_table *table, int dir,
-				      void *buffer, size_t *lenp, loff_t *ppos)
+int proc_doulongvec_minmax_conv(const struct ctl_table *table, int dir,
+				void *buffer, size_t *lenp, loff_t *ppos,
+				unsigned long convmul, unsigned long convdiv)
 {
 	return -ENOSYS;
 }
@@ -1192,5 +1176,4 @@ EXPORT_SYMBOL(proc_dointvec_minmax);
 EXPORT_SYMBOL_GPL(proc_douintvec_minmax);
 EXPORT_SYMBOL(proc_dostring);
 EXPORT_SYMBOL(proc_doulongvec_minmax);
-EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
 EXPORT_SYMBOL(proc_do_large_bitmap);
diff --git a/kernel/time/jiffies.c b/kernel/time/jiffies.c
index 2289c11c8bfc218304a620a3541109e281b4e581..5fa02fa8d3f45051d8fbbade783e999e9b29a399 100644
--- a/kernel/time/jiffies.c
+++ b/kernel/time/jiffies.c
@@ -190,6 +190,7 @@ int proc_dointvec_ms_jiffies(const struct ctl_table *table, int dir, void *buffe
 	return proc_dointvec_conv(table, dir, buffer, lenp, ppos,
 				  do_proc_int_conv_ms_jiffies);
 }
+EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
 
 int proc_dointvec_ms_jiffies_minmax(const struct ctl_table *table, int dir,
 			  void *buffer, size_t *lenp, loff_t *ppos)
@@ -197,5 +198,29 @@ int proc_dointvec_ms_jiffies_minmax(const struct ctl_table *table, int dir,
 	return proc_dointvec_conv(table, dir, buffer, lenp, ppos,
 				  do_proc_int_conv_ms_jiffies_minmax);
 }
-EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
+
+/**
+ * proc_doulongvec_ms_jiffies_minmax - read a vector of millisecond values with min/max values
+ * @table: the sysctl table
+ * @dir: %TRUE if this is a write to the sysctl file
+ * @buffer: the user buffer
+ * @lenp: the size of the user buffer
+ * @ppos: file position
+ *
+ * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
+ * values from/to the user buffer, treated as an ASCII string. The values
+ * are treated as milliseconds, and converted to jiffies when they are stored.
+ *
+ * This routine will ensure the values are within the range specified by
+ * table->extra1 (min) and table->extra2 (max).
+ *
+ * Returns 0 on success.
+ */
+int proc_doulongvec_ms_jiffies_minmax(const struct ctl_table *table, int dir,
+				      void *buffer, size_t *lenp, loff_t *ppos)
+{
+	return proc_doulongvec_minmax_conv(table, dir, buffer, lenp, ppos,
+					   HZ, 1000l);
+}
+EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
 

-- 
2.50.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 6/7] sysctl: Create pipe-max-size converter using sysctl UINT macros
  2025-10-17  8:32 [PATCH 0/7] sysctl: Move jiffies converters out of kernel/sysctl.c Joel Granados
                   ` (4 preceding siblings ...)
  2025-10-17  8:32 ` [PATCH 5/7] sysctl: Move proc_doulongvec_ms_jiffies_minmax " Joel Granados
@ 2025-10-17  8:32 ` Joel Granados
  2025-10-17  8:32 ` [PATCH 7/7] sysctl: Wrap do_proc_douintvec with the public function proc_douintvec_conv Joel Granados
  6 siblings, 0 replies; 10+ messages in thread
From: Joel Granados @ 2025-10-17  8:32 UTC (permalink / raw)
  To: Kees Cook, Alexander Viro, Christian Brauner, Jan Kara
  Cc: linux-kernel, linux-fsdevel, Joel Granados

Create a converter for the pipe-max-size proc_handler using the
SYSCTL_UINT_CONV_CUSTOM. Move SYSCTL_CONV_IDENTITY macro to the sysctl
header to make it available for pipe size validation. Keep returning
-EINVAL when (val == 0) by using a range checking converter and setting
the minimal valid value (extern1) to SYSCTL_ONE. Keep round_pipe_size by
passing it as the operation for SYSCTL_USER_TO_KERN_INT_CONV.

Signed-off-by: Joel Granados <joel.granados@kernel.org>
---
 fs/pipe.c              | 26 ++++++--------------------
 include/linux/sysctl.h |  1 +
 kernel/sysctl.c        |  2 --
 3 files changed, 7 insertions(+), 22 deletions(-)

diff --git a/fs/pipe.c b/fs/pipe.c
index 2431f05cb788f5bd89660f0fc6f4c4696e17d5dd..974faf06a3136fff7a382e575514d84fcf86183c 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -1479,31 +1479,16 @@ static struct file_system_type pipe_fs_type = {
 };
 
 #ifdef CONFIG_SYSCTL
-static int do_proc_dopipe_max_size_conv(unsigned long *lvalp,
-					unsigned int *valp, int write,
-					const struct ctl_table *table)
-{
-	if (write) {
-		unsigned int val;
-
-		val = round_pipe_size(*lvalp);
-		if (val == 0)
-			return -EINVAL;
-
-		*valp = val;
-	} else {
-		unsigned int val = *valp;
-		*lvalp = (unsigned long) val;
-	}
-
-	return 0;
-}
+static SYSCTL_USER_TO_KERN_UINT_CONV(_pipe_maxsz, round_pipe_size)
+static SYSCTL_UINT_CONV_CUSTOM(_pipe_maxsz,
+			       sysctl_user_to_kern_uint_conv_pipe_maxsz,
+			       sysctl_kern_to_user_uint_conv, true)
 
 static int proc_dopipe_max_size(const struct ctl_table *table, int write,
 				void *buffer, size_t *lenp, loff_t *ppos)
 {
 	return do_proc_douintvec(table, write, buffer, lenp, ppos,
-				 do_proc_dopipe_max_size_conv);
+				 do_proc_uint_conv_pipe_maxsz);
 }
 
 static const struct ctl_table fs_pipe_sysctls[] = {
@@ -1513,6 +1498,7 @@ static const struct ctl_table fs_pipe_sysctls[] = {
 		.maxlen		= sizeof(pipe_max_size),
 		.mode		= 0644,
 		.proc_handler	= proc_dopipe_max_size,
+		.extra1		= SYSCTL_ONE,
 	},
 	{
 		.procname	= "pipe-user-pages-hard",
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 9396bb421cd5e1e9076de0c77c45a870c453aee1..ee5e2b3f47db834b084ac0fc4108bf28177b6949 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -59,6 +59,7 @@ extern const int sysctl_vals[];
 #define SYSCTL_LONG_ONE		((void *)&sysctl_long_vals[1])
 #define SYSCTL_LONG_MAX		((void *)&sysctl_long_vals[2])
 
+#define SYSCTL_CONV_IDENTITY(val) (val)
 /**
  *
  * "dir" originates from read_iter (dir = 0) or write_iter (dir = 1)
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 6750ddbc15b2bb9ee9de0d48ac999a4c3a2ec5d6..d2e756ee3717b07fd848871267656ee0ed7d9268 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -354,8 +354,6 @@ static void proc_put_char(void **buf, size_t *size, char c)
 	}
 }
 
-#define SYSCTL_CONV_IDENTITY(val) val
-
 static SYSCTL_USER_TO_KERN_INT_CONV(, SYSCTL_CONV_IDENTITY)
 static SYSCTL_KERN_TO_USER_INT_CONV(, SYSCTL_CONV_IDENTITY)
 

-- 
2.50.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 7/7] sysctl: Wrap do_proc_douintvec with the public function proc_douintvec_conv
  2025-10-17  8:32 [PATCH 0/7] sysctl: Move jiffies converters out of kernel/sysctl.c Joel Granados
                   ` (5 preceding siblings ...)
  2025-10-17  8:32 ` [PATCH 6/7] sysctl: Create pipe-max-size converter using sysctl UINT macros Joel Granados
@ 2025-10-17  8:32 ` Joel Granados
  2025-10-22  9:18   ` kernel test robot
  6 siblings, 1 reply; 10+ messages in thread
From: Joel Granados @ 2025-10-17  8:32 UTC (permalink / raw)
  To: Kees Cook, Alexander Viro, Christian Brauner, Jan Kara
  Cc: linux-kernel, linux-fsdevel, Joel Granados

Make do_proc_douintvec static and export proc_douintvec_conv wrapper
function for external use. This is to keep with the design in sysctl.c.
Update fs/pipe.c to use the new public API.

Signed-off-by: Joel Granados <joel.granados@kernel.org>
---
 fs/pipe.c              |  4 ++--
 include/linux/sysctl.h | 13 +++++++------
 kernel/sysctl.c        | 18 ++++++++++++++----
 3 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/fs/pipe.c b/fs/pipe.c
index 974faf06a3136fff7a382e575514d84fcf86183c..59b60a9374e671f7e129f5ebfde066c1756c00b3 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -1487,8 +1487,8 @@ static SYSCTL_UINT_CONV_CUSTOM(_pipe_maxsz,
 static int proc_dopipe_max_size(const struct ctl_table *table, int write,
 				void *buffer, size_t *lenp, loff_t *ppos)
 {
-	return do_proc_douintvec(table, write, buffer, lenp, ppos,
-				 do_proc_uint_conv_pipe_maxsz);
+	return proc_douintvec_conv(table, write, buffer, lenp, ppos,
+				   do_proc_uint_conv_pipe_maxsz);
 }
 
 static const struct ctl_table fs_pipe_sysctls[] = {
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index ee5e2b3f47db834b084ac0fc4108bf28177b6949..727dfc7771de1b7a562e9b930f6851873574b532 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -183,14 +183,20 @@ int proc_dostring(const struct ctl_table *, int, void *, size_t *, loff_t *);
 int proc_dobool(const struct ctl_table *table, int write, void *buffer,
 		size_t *lenp, loff_t *ppos);
 int proc_dointvec(const struct ctl_table *, int, void *, size_t *, loff_t *);
+int proc_dointvec_minmax(const struct ctl_table *table, int dir, void *buffer,
+			 size_t *lenp, loff_t *ppos);
 int proc_dointvec_conv(const struct ctl_table *table, int dir, void *buffer,
 		       size_t *lenp, loff_t *ppos,
 		       int (*conv)(bool *negp, unsigned long *u_ptr, int *k_ptr,
 				   int dir, const struct ctl_table *table));
 int proc_douintvec(const struct ctl_table *, int, void *, size_t *, loff_t *);
-int proc_dointvec_minmax(const struct ctl_table *, int, void *, size_t *, loff_t *);
 int proc_douintvec_minmax(const struct ctl_table *table, int write, void *buffer,
 		size_t *lenp, loff_t *ppos);
+int proc_douintvec_conv(const struct ctl_table *table, int write, void *buffer,
+			size_t *lenp, loff_t *ppos,
+			int (*conv)(unsigned long *lvalp, unsigned int *valp,
+				    int write, const struct ctl_table *table));
+
 int proc_dou8vec_minmax(const struct ctl_table *table, int write, void *buffer,
 			size_t *lenp, loff_t *ppos);
 int proc_doulongvec_minmax(const struct ctl_table *, int, void *, size_t *, loff_t *);
@@ -349,11 +355,6 @@ extern struct ctl_table_header *register_sysctl_mount_point(const char *path);
 
 void do_sysctl_args(void);
 bool sysctl_is_alias(char *param);
-int do_proc_douintvec(const struct ctl_table *table, int write,
-		      void *buffer, size_t *lenp, loff_t *ppos,
-		      int (*conv)(unsigned long *lvalp,
-				  unsigned int *valp, int write,
-				  const struct ctl_table *table));
 
 extern int unaligned_enabled;
 extern int no_unaligned_warning;
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index d2e756ee3717b07fd848871267656ee0ed7d9268..b7c0c78417020d9c7525d4e542be79e8e61bb88a 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -534,10 +534,11 @@ static int do_proc_douintvec_r(const struct ctl_table *table, void *buffer,
 	return err;
 }
 
-int do_proc_douintvec(const struct ctl_table *table, int dir, void *buffer,
-		      size_t *lenp, loff_t *ppos,
-		      int (*conv)(unsigned long *u_ptr, unsigned int *k_ptr,
-				  int dir, const struct ctl_table *table))
+static int do_proc_douintvec(const struct ctl_table *table, int dir,
+			     void *buffer, size_t *lenp, loff_t *ppos,
+			      int (*conv)(unsigned long *u_ptr,
+					  unsigned int *k_ptr, int dir,
+					  const struct ctl_table *table))
 {
 	unsigned int vleft;
 
@@ -566,6 +567,15 @@ int do_proc_douintvec(const struct ctl_table *table, int dir, void *buffer,
 	return do_proc_douintvec_r(table, buffer, lenp, ppos, conv);
 }
 
+int proc_douintvec_conv(const struct ctl_table *table, int dir, void *buffer,
+			size_t *lenp, loff_t *ppos,
+			int (*conv)(unsigned long *u_ptr, unsigned int *k_ptr,
+				    int dir, const struct ctl_table *table))
+{
+	return do_proc_douintvec(table, dir, buffer, lenp, ppos, conv);
+}
+
+
 /**
  * proc_dobool - read/write a bool
  * @table: the sysctl table

-- 
2.50.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 7/7] sysctl: Wrap do_proc_douintvec with the public function proc_douintvec_conv
  2025-10-17  8:32 ` [PATCH 7/7] sysctl: Wrap do_proc_douintvec with the public function proc_douintvec_conv Joel Granados
@ 2025-10-22  9:18   ` kernel test robot
  2025-10-27 10:14     ` Joel Granados
  0 siblings, 1 reply; 10+ messages in thread
From: kernel test robot @ 2025-10-22  9:18 UTC (permalink / raw)
  To: Joel Granados, Kees Cook, Alexander Viro, Christian Brauner,
	Jan Kara
  Cc: oe-kbuild-all, linux-kernel, linux-fsdevel, Joel Granados

Hi Joel,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 130e5390ba572bffa687f32ed212dac1105b654a]

url:    https://github.com/intel-lab-lkp/linux/commits/Joel-Granados/sysctl-Allow-custom-converters-from-outside-sysctl/20251017-163832
base:   130e5390ba572bffa687f32ed212dac1105b654a
patch link:    https://lore.kernel.org/r/20251017-jag-sysctl_jiffies-v1-7-175d81dfdf82%40kernel.org
patch subject: [PATCH 7/7] sysctl: Wrap do_proc_douintvec with the public function proc_douintvec_conv
config: i386-randconfig-063-20251022 (https://download.01.org/0day-ci/archive/20251022/202510221719.3ggn070M-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251022/202510221719.3ggn070M-lkp@intel.com/reproduce)

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>
| Closes: https://lore.kernel.org/oe-kbuild-all/202510221719.3ggn070M-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
>> kernel/kstack_erase.c:34:56: sparse: sparse: incorrect type in argument 3 (different address spaces) @@     expected void *buffer @@     got void [noderef] __user *buffer @@
   kernel/kstack_erase.c:34:56: sparse:     expected void *buffer
   kernel/kstack_erase.c:34:56: sparse:     got void [noderef] __user *buffer
   kernel/kstack_erase.c:54:35: sparse: sparse: incorrect type in initializer (incompatible argument 3 (different address spaces)) @@     expected int ( [usertype] *proc_handler )( ... ) @@     got int ( * )( ... ) @@
   kernel/kstack_erase.c:54:35: sparse:     expected int ( [usertype] *proc_handler )( ... )
   kernel/kstack_erase.c:54:35: sparse:     got int ( * )( ... )

vim +34 kernel/kstack_erase.c

964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  23  
0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  24  #ifdef CONFIG_SYSCTL
78eb4ea25cd5fd kernel/stackleak.c Joel Granados    2024-07-24  25  static int stack_erasing_sysctl(const struct ctl_table *table, int write,
0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  26  			void __user *buffer, size_t *lenp, loff_t *ppos)
964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  27  {
964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  28  	int ret = 0;
964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  29  	int state = !static_branch_unlikely(&stack_erasing_bypass);
964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  30  	int prev_state = state;
0e148d3cca0dc1 kernel/stackleak.c Thomas Weißschuh 2024-05-03  31  	struct ctl_table table_copy = *table;
964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  32  
0e148d3cca0dc1 kernel/stackleak.c Thomas Weißschuh 2024-05-03  33  	table_copy.data = &state;
0e148d3cca0dc1 kernel/stackleak.c Thomas Weißschuh 2024-05-03 @34  	ret = proc_dointvec_minmax(&table_copy, write, buffer, lenp, ppos);
964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  35  	state = !!state;
964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  36  	if (ret || !write || state == prev_state)
964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  37  		return ret;
964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  38  
964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  39  	if (state)
964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  40  		static_branch_disable(&stack_erasing_bypass);
964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  41  	else
964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  42  		static_branch_enable(&stack_erasing_bypass);
964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  43  
964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  44  	pr_warn("stackleak: kernel stack erasing is %s\n",
62e9c1e8ecee87 kernel/stackleak.c Thorsten Blum    2024-12-22  45  					str_enabled_disabled(state));
964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  46  	return ret;
964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  47  }
1751f872cc97f9 kernel/stackleak.c Joel Granados    2025-01-28  48  static const struct ctl_table stackleak_sysctls[] = {
0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  49  	{
0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  50  		.procname	= "stack_erasing",
0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  51  		.data		= NULL,
0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  52  		.maxlen		= sizeof(int),
0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  53  		.mode		= 0600,
0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  54  		.proc_handler	= stack_erasing_sysctl,
0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  55  		.extra1		= SYSCTL_ZERO,
0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  56  		.extra2		= SYSCTL_ONE,
0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  57  	},
0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  58  };
0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  59  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 7/7] sysctl: Wrap do_proc_douintvec with the public function proc_douintvec_conv
  2025-10-22  9:18   ` kernel test robot
@ 2025-10-27 10:14     ` Joel Granados
  0 siblings, 0 replies; 10+ messages in thread
From: Joel Granados @ 2025-10-27 10:14 UTC (permalink / raw)
  To: kernel test robot
  Cc: Kees Cook, Alexander Viro, Christian Brauner, Jan Kara,
	oe-kbuild-all, linux-kernel, linux-fsdevel

[-- Attachment #1: Type: text/plain, Size: 6239 bytes --]

On Wed, Oct 22, 2025 at 05:18:51PM +0800, kernel test robot wrote:
> Hi Joel,
> 
> kernel test robot noticed the following build warnings:
> 
> [auto build test WARNING on 130e5390ba572bffa687f32ed212dac1105b654a]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/Joel-Granados/sysctl-Allow-custom-converters-from-outside-sysctl/20251017-163832
> base:   130e5390ba572bffa687f32ed212dac1105b654a
> patch link:    https://lore.kernel.org/r/20251017-jag-sysctl_jiffies-v1-7-175d81dfdf82%40kernel.org
> patch subject: [PATCH 7/7] sysctl: Wrap do_proc_douintvec with the public function proc_douintvec_conv
> config: i386-randconfig-063-20251022 (https://download.01.org/0day-ci/archive/20251022/202510221719.3ggn070M-lkp@intel.com/config)
> compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251022/202510221719.3ggn070M-lkp@intel.com/reproduce)
> 
> 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>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202510221719.3ggn070M-lkp@intel.com/
> 
> sparse warnings: (new ones prefixed by >>)
> >> kernel/kstack_erase.c:34:56: sparse: sparse: incorrect type in argument 3 (different address spaces) @@     expected void *buffer @@     got void [noderef] __user *buffer @@
>    kernel/kstack_erase.c:34:56: sparse:     expected void *buffer
>    kernel/kstack_erase.c:34:56: sparse:     got void [noderef] __user *buffer
This is probably a false positive where the warning was already there
but it moved up in the output (probably due to the function moving up in
the header?)

This made me look a bit more into the issue and I believe that it does
show an issue. Not with the current series, but with commit 0df8bdd5e3b3
("stackleak: move stack_erasing sysctl to stackleak.c"). In this commit
the buffer argument was changed frim void* to void __user*
but in 32927393dc1c ("sysctl: pass kernel pointers to ->proc_handler")
the "__user" was removed. I'll post another patch to fix this up.


Best

>    kernel/kstack_erase.c:54:35: sparse: sparse: incorrect type in initializer (incompatible argument 3 (different address spaces)) @@     expected int ( [usertype] *proc_handler )( ... ) @@     got int ( * )( ... ) @@
>    kernel/kstack_erase.c:54:35: sparse:     expected int ( [usertype] *proc_handler )( ... )
>    kernel/kstack_erase.c:54:35: sparse:     got int ( * )( ... )
> 
> vim +34 kernel/kstack_erase.c
> 
> 964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  23  
> 0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  24  #ifdef CONFIG_SYSCTL
> 78eb4ea25cd5fd kernel/stackleak.c Joel Granados    2024-07-24  25  static int stack_erasing_sysctl(const struct ctl_table *table, int write,
> 0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  26  			void __user *buffer, size_t *lenp, loff_t *ppos)
> 964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  27  {
> 964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  28  	int ret = 0;
> 964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  29  	int state = !static_branch_unlikely(&stack_erasing_bypass);
> 964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  30  	int prev_state = state;
> 0e148d3cca0dc1 kernel/stackleak.c Thomas Weißschuh 2024-05-03  31  	struct ctl_table table_copy = *table;
> 964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  32  
> 0e148d3cca0dc1 kernel/stackleak.c Thomas Weißschuh 2024-05-03  33  	table_copy.data = &state;
> 0e148d3cca0dc1 kernel/stackleak.c Thomas Weißschuh 2024-05-03 @34  	ret = proc_dointvec_minmax(&table_copy, write, buffer, lenp, ppos);
> 964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  35  	state = !!state;
> 964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  36  	if (ret || !write || state == prev_state)
> 964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  37  		return ret;
> 964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  38  
> 964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  39  	if (state)
> 964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  40  		static_branch_disable(&stack_erasing_bypass);
> 964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  41  	else
> 964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  42  		static_branch_enable(&stack_erasing_bypass);
> 964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  43  
> 964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  44  	pr_warn("stackleak: kernel stack erasing is %s\n",
> 62e9c1e8ecee87 kernel/stackleak.c Thorsten Blum    2024-12-22  45  					str_enabled_disabled(state));
> 964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  46  	return ret;
> 964c9dff009189 kernel/stackleak.c Alexander Popov  2018-08-17  47  }
> 1751f872cc97f9 kernel/stackleak.c Joel Granados    2025-01-28  48  static const struct ctl_table stackleak_sysctls[] = {
> 0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  49  	{
> 0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  50  		.procname	= "stack_erasing",
> 0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  51  		.data		= NULL,
> 0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  52  		.maxlen		= sizeof(int),
> 0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  53  		.mode		= 0600,
> 0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  54  		.proc_handler	= stack_erasing_sysctl,
> 0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  55  		.extra1		= SYSCTL_ZERO,
> 0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  56  		.extra2		= SYSCTL_ONE,
> 0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  57  	},
> 0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  58  };
> 0df8bdd5e3b3e5 kernel/stackleak.c Xiaoming Ni      2022-01-21  59  
> 
> -- 
> 0-DAY CI Kernel Test Service
> https://github.com/intel/lkp-tests/wiki

-- 

Joel Granados

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2025-10-27 10:15 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-17  8:32 [PATCH 0/7] sysctl: Move jiffies converters out of kernel/sysctl.c Joel Granados
2025-10-17  8:32 ` [PATCH 1/7] sysctl: Allow custom converters from outside sysctl Joel Granados
2025-10-17  8:32 ` [PATCH 2/7] sysctl: Move INT converter macros to sysctl header Joel Granados
2025-10-17  8:32 ` [PATCH 3/7] sysctl: Move UINT " Joel Granados
2025-10-17  8:32 ` [PATCH 4/7] sysctl: Move jiffies converters to kernel/time/jiffies.c Joel Granados
2025-10-17  8:32 ` [PATCH 5/7] sysctl: Move proc_doulongvec_ms_jiffies_minmax " Joel Granados
2025-10-17  8:32 ` [PATCH 6/7] sysctl: Create pipe-max-size converter using sysctl UINT macros Joel Granados
2025-10-17  8:32 ` [PATCH 7/7] sysctl: Wrap do_proc_douintvec with the public function proc_douintvec_conv Joel Granados
2025-10-22  9:18   ` kernel test robot
2025-10-27 10:14     ` Joel Granados

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).