linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RFC 0/7] sysctl: constify sysctl ctl_tables
@ 2023-11-25 12:52 ` Thomas Weißschuh
  2023-11-25 12:52   ` [PATCH RFC 1/7] sysctl: add helper sysctl_run_handler Thomas Weißschuh
                     ` (7 more replies)
  0 siblings, 8 replies; 13+ messages in thread
From: Thomas Weißschuh @ 2023-11-25 12:52 UTC (permalink / raw)
  To: Kees Cook, Gustavo A. R. Silva, Luis Chamberlain, Iurii Zaikin,
	Greg Kroah-Hartman, Joel Granados
  Cc: linux-hardening, linux-kernel, linux-fsdevel,
	Thomas Weißschuh

Problem description:

The kernel contains a lot of struct ctl_table throught the tree.
These are very often 'static' definitions.
It would be good to mark these tables const to avoid accidental or
malicious modifications.
Unfortunately the tables can not be made const because the core
registration functions expect mutable tables.

This is for two reasons:

1) sysctl_{set,clear}_perm_empty_ctl_header in the sysctl core modify
   the table. This should be fixable by only modifying the header
   instead of the table itself.
2) The table is passed to the handler function as a non-const pointer.

This series is an aproach on fixing reason 2).

Full process:

* Introduce field proc_handler_new for const handlers (this series)
* Migrate all core handlers to proc_handler_new (this series, partial)
  This can hopefully be done in a big switch, as it only involves
  functions and structures owned by the core sysctl code.
* Migrate all other sysctl handlers to proc_handler_new.
* Drop the old proc_handler_field.
* Fix the sysctl core to not modify the tables anymore.
* Adapt public sysctl APIs to take "const struct ctl_table *".
* Teach checkpatch.pl to warn on non-const "struct ctl_table"
  definitions.
* Migrate definitions of "struct ctl_table" to "const" where applicable.
 

Notes:

Just casting the function pointers around would trigger
CFI (control flow integrity) warnings.

The name of the new handler "proc_handler_new" is a bit too long messing
up the alignment of the table definitions.
Maybe "proc_handler2" or "proc_handler_c" for (const) would be better.

---
Thomas Weißschuh (7):
      sysctl: add helper sysctl_run_handler
      bpf: cgroup: call proc handler through helper
      sysctl: add proc_handler_new to struct ctl_table
      net: sysctl: add new sysctl table handler to debug message
      treewide: sysctl: migrate proc_dostring to proc_handler_new
      treewide: sysctl: migrate proc_dobool to proc_handler_new
      treewide: sysctl: migrate proc_dointvec to proc_handler_new

 arch/arm/kernel/isa.c                   |  6 +--
 arch/csky/abiv1/alignment.c             |  8 ++--
 arch/powerpc/kernel/idle.c              |  2 +-
 arch/riscv/kernel/vector.c              |  2 +-
 arch/s390/kernel/debug.c                |  2 +-
 crypto/fips.c                           |  6 +--
 drivers/char/hpet.c                     |  2 +-
 drivers/char/random.c                   |  4 +-
 drivers/infiniband/core/iwcm.c          |  2 +-
 drivers/infiniband/core/ucma.c          |  2 +-
 drivers/macintosh/mac_hid.c             |  4 +-
 drivers/md/md.c                         |  4 +-
 drivers/scsi/sg.c                       |  2 +-
 drivers/tty/tty_io.c                    |  4 +-
 fs/coda/sysctl.c                        |  6 +--
 fs/coredump.c                           |  6 +--
 fs/devpts/inode.c                       |  2 +-
 fs/lockd/svc.c                          |  4 +-
 fs/locks.c                              |  4 +-
 fs/nfs/nfs4sysctl.c                     |  2 +-
 fs/nfs/sysctl.c                         |  2 +-
 fs/notify/dnotify/dnotify.c             |  2 +-
 fs/ntfs/sysctl.c                        |  2 +-
 fs/ocfs2/stackglue.c                    |  2 +-
 fs/proc/proc_sysctl.c                   | 16 ++++---
 fs/quota/dquot.c                        |  2 +-
 include/linux/sysctl.h                  | 29 +++++++++---
 init/do_mounts_initrd.c                 |  2 +-
 io_uring/io_uring.c                     |  2 +-
 ipc/mq_sysctl.c                         |  2 +-
 kernel/acct.c                           |  2 +-
 kernel/bpf/cgroup.c                     |  2 +-
 kernel/locking/lockdep.c                |  4 +-
 kernel/printk/sysctl.c                  |  4 +-
 kernel/reboot.c                         |  4 +-
 kernel/seccomp.c                        |  2 +-
 kernel/signal.c                         |  2 +-
 kernel/sysctl-test.c                    | 20 ++++-----
 kernel/sysctl.c                         | 80 ++++++++++++++++-----------------
 lib/test_sysctl.c                       | 10 ++---
 mm/hugetlb.c                            |  2 +-
 mm/hugetlb_vmemmap.c                    |  2 +-
 mm/oom_kill.c                           |  4 +-
 net/appletalk/sysctl_net_atalk.c        |  2 +-
 net/core/sysctl_net_core.c              | 12 ++---
 net/ipv4/route.c                        | 18 ++++----
 net/ipv4/sysctl_net_ipv4.c              | 38 ++++++++--------
 net/ipv4/xfrm4_policy.c                 |  2 +-
 net/ipv6/addrconf.c                     | 72 ++++++++++++++---------------
 net/ipv6/route.c                        |  8 ++--
 net/ipv6/sysctl_net_ipv6.c              | 18 ++++----
 net/ipv6/xfrm6_policy.c                 |  2 +-
 net/mptcp/ctrl.c                        |  2 +-
 net/netfilter/ipvs/ip_vs_ctl.c          | 36 +++++++--------
 net/netfilter/nf_conntrack_standalone.c |  8 ++--
 net/netfilter/nf_log.c                  |  2 +-
 net/rds/ib_sysctl.c                     |  2 +-
 net/rds/sysctl.c                        |  6 +--
 net/sctp/sysctl.c                       | 26 +++++------
 net/sunrpc/xprtrdma/transport.c         |  2 +-
 net/sysctl_net.c                        |  5 ++-
 net/unix/sysctl_net_unix.c              |  2 +-
 net/x25/sysctl_net_x25.c                |  2 +-
 net/xfrm/xfrm_sysctl.c                  |  4 +-
 64 files changed, 280 insertions(+), 262 deletions(-)
---
base-commit: 0f5cc96c367f2e780eb492cc9cab84e3b2ca88da
change-id: 20231116-const-sysctl-e14624f1295c

Best regards,
-- 
Thomas Weißschuh <linux@weissschuh.net>


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

* [PATCH RFC 1/7] sysctl: add helper sysctl_run_handler
  2023-11-25 12:52 ` [PATCH RFC 0/7] sysctl: constify sysctl ctl_tables Thomas Weißschuh
@ 2023-11-25 12:52   ` Thomas Weißschuh
  2023-11-25 12:52   ` [PATCH RFC 2/7] bpf: cgroup: call proc handler through helper Thomas Weißschuh
                     ` (6 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Thomas Weißschuh @ 2023-11-25 12:52 UTC (permalink / raw)
  To: Kees Cook, Gustavo A. R. Silva, Luis Chamberlain, Iurii Zaikin,
	Greg Kroah-Hartman, Joel Granados
  Cc: linux-hardening, linux-kernel, linux-fsdevel,
	Thomas Weißschuh

A future patch will introduce a second handler function.
To make the code future-proof add the sysctl_run_handler function that
automatically can call the correct handler function.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
 fs/proc/proc_sysctl.c  | 2 +-
 include/linux/sysctl.h | 6 ++++++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index 8064ea76f80b..1bb0aa2ff501 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -597,7 +597,7 @@ static ssize_t proc_sys_call_handler(struct kiocb *iocb, struct iov_iter *iter,
 		goto out_free_buf;
 
 	/* careful: calling conventions are nasty here */
-	error = table->proc_handler(table, write, kbuf, &count, &iocb->ki_pos);
+	error = sysctl_run_handler(table, write, kbuf, &count, &iocb->ki_pos);
 	if (error)
 		goto out_free_buf;
 
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 61b40ea81f4d..604aaaa1fce2 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -298,4 +298,10 @@ static inline bool sysctl_is_alias(char *param)
 int sysctl_max_threads(struct ctl_table *table, int write, void *buffer,
 		size_t *lenp, loff_t *ppos);
 
+static inline int sysctl_run_handler(struct ctl_table *ctl, int write,
+				     void *buffer, size_t *lenp, loff_t *ppos)
+{
+	return ctl->proc_handler(ctl, write, buffer, lenp, ppos);
+}
+
 #endif /* _LINUX_SYSCTL_H */

-- 
2.43.0


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

* [PATCH RFC 2/7] bpf: cgroup: call proc handler through helper
  2023-11-25 12:52 ` [PATCH RFC 0/7] sysctl: constify sysctl ctl_tables Thomas Weißschuh
  2023-11-25 12:52   ` [PATCH RFC 1/7] sysctl: add helper sysctl_run_handler Thomas Weißschuh
@ 2023-11-25 12:52   ` Thomas Weißschuh
  2023-11-25 12:52   ` [PATCH RFC 3/7] sysctl: add proc_handler_new to struct ctl_table Thomas Weißschuh
                     ` (5 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Thomas Weißschuh @ 2023-11-25 12:52 UTC (permalink / raw)
  To: Kees Cook, Gustavo A. R. Silva, Luis Chamberlain, Iurii Zaikin,
	Greg Kroah-Hartman, Joel Granados
  Cc: linux-hardening, linux-kernel, linux-fsdevel,
	Thomas Weißschuh

The sysctl core will introduce a second handler function.
To prepare for this use the provided helper function to call either
handler function.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
 kernel/bpf/cgroup.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
index 491d20038cbe..d537b1c80a36 100644
--- a/kernel/bpf/cgroup.c
+++ b/kernel/bpf/cgroup.c
@@ -1715,7 +1715,7 @@ int __cgroup_bpf_run_filter_sysctl(struct ctl_table_header *head,
 
 	ctx.cur_val = kmalloc_track_caller(ctx.cur_len, GFP_KERNEL);
 	if (!ctx.cur_val ||
-	    table->proc_handler(table, 0, ctx.cur_val, &ctx.cur_len, &pos)) {
+	    sysctl_run_handler(table, 0, ctx.cur_val, &ctx.cur_len, &pos)) {
 		/* Let BPF program decide how to proceed. */
 		ctx.cur_len = 0;
 	}

-- 
2.43.0


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

* [PATCH RFC 3/7] sysctl: add proc_handler_new to struct ctl_table
  2023-11-25 12:52 ` [PATCH RFC 0/7] sysctl: constify sysctl ctl_tables Thomas Weißschuh
  2023-11-25 12:52   ` [PATCH RFC 1/7] sysctl: add helper sysctl_run_handler Thomas Weißschuh
  2023-11-25 12:52   ` [PATCH RFC 2/7] bpf: cgroup: call proc handler through helper Thomas Weißschuh
@ 2023-11-25 12:52   ` Thomas Weißschuh
  2023-11-25 12:52   ` [PATCH RFC 4/7] net: sysctl: add new sysctl table handler to debug message Thomas Weißschuh
                     ` (4 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Thomas Weißschuh @ 2023-11-25 12:52 UTC (permalink / raw)
  To: Kees Cook, Gustavo A. R. Silva, Luis Chamberlain, Iurii Zaikin,
	Greg Kroah-Hartman, Joel Granados
  Cc: linux-hardening, linux-kernel, linux-fsdevel,
	Thomas Weißschuh

The existing handler function take the struct ctl_table as a mutable
parameter. This prevents the table definitions from being put into
.rodata where they would be protected from accidental or malicious
modification.

As many parts of the kernel define proc_handlers provide a gradual
transition mechanism through the introduction of a new field which takes
the table as a read-only parameter.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
 fs/proc/proc_sysctl.c  |  6 ++++--
 include/linux/sysctl.h | 17 +++++++++++++----
 2 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index 1bb0aa2ff501..810ecdd3b84c 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -573,7 +573,7 @@ static ssize_t proc_sys_call_handler(struct kiocb *iocb, struct iov_iter *iter,
 
 	/* if that can happen at all, it should be -EINVAL, not -EISDIR */
 	error = -EINVAL;
-	if (!table->proc_handler)
+	if (!table->proc_handler && !table->proc_handler_new)
 		goto out;
 
 	/* don't even try if the size is too large */
@@ -655,7 +655,7 @@ static __poll_t proc_sys_poll(struct file *filp, poll_table *wait)
 	if (IS_ERR(head))
 		return EPOLLERR | EPOLLHUP;
 
-	if (!table->proc_handler)
+	if (!table->proc_handler && !table->proc_handler_new)
 		goto out;
 
 	if (!table->poll)
@@ -1333,6 +1333,8 @@ static struct ctl_dir *sysctl_mkdir_p(struct ctl_dir *dir, const char *path)
  *
  * proc_handler - the text handler routine (described below)
  *
+ * proc_handler_new - const variant of the text handler routine (described below)
+ *
  * extra1, extra2 - extra pointers usable by the proc handler routines
  * XXX: we should eventually modify these to use long min / max [0]
  * [0] https://lkml.kernel.org/87zgpte9o4.fsf@email.froward.int.ebiederm.org
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 604aaaa1fce2..de1a5a714070 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -63,6 +63,8 @@ extern const unsigned long sysctl_long_vals[];
 
 typedef int proc_handler(struct ctl_table *ctl, int write, void *buffer,
 		size_t *lenp, loff_t *ppos);
+typedef int proc_handler_new(const struct ctl_table *ctl, int write,
+		void *buffer, size_t *lenp, loff_t *ppos);
 
 int proc_dostring(struct ctl_table *, int, void *, size_t *, loff_t *);
 int proc_dobool(struct ctl_table *table, int write, void *buffer,
@@ -107,10 +109,10 @@ int proc_do_static_key(struct ctl_table *table, int write, void *buffer,
  * struct enable minimal validation of the values being written to be
  * performed, and the mode field allows minimal authentication.
  * 
- * There must be a proc_handler routine for any terminal nodes
- * mirrored under /proc/sys (non-terminals are handled by a built-in
- * directory handler).  Several default handlers are available to
- * cover common cases.
+ * There must be one proc_handler/proc_handler_new routine for any terminal
+ * nodes mirrored under /proc/sys (non-terminals are handled by a built-in
+ * directory handler).
+ * Several default handlers are available to cover common cases.
  */
 
 /* Support for userspace poll() to watch for changes */
@@ -149,6 +151,7 @@ struct ctl_table {
 		SYSCTL_TABLE_TYPE_PERMANENTLY_EMPTY
 	} type;
 	proc_handler *proc_handler;	/* Callback for text formatting */
+	proc_handler_new *proc_handler_new;	/* Callback for text formatting */
 	struct ctl_table_poll *poll;
 	void *extra1;
 	void *extra2;
@@ -301,6 +304,12 @@ int sysctl_max_threads(struct ctl_table *table, int write, void *buffer,
 static inline int sysctl_run_handler(struct ctl_table *ctl, int write,
 				     void *buffer, size_t *lenp, loff_t *ppos)
 {
+	if (ctl->proc_handler_new && ctl->proc_handler)
+		pr_warn_ratelimited("sysctl table %s has both proc_handler and proc_handler_new, this is a but\n",
+				    ctl->procname);
+
+	if (ctl->proc_handler_new)
+		return ctl->proc_handler_new(ctl, write, buffer, lenp, ppos);
 	return ctl->proc_handler(ctl, write, buffer, lenp, ppos);
 }
 

-- 
2.43.0


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

* [PATCH RFC 4/7] net: sysctl: add new sysctl table handler to debug message
  2023-11-25 12:52 ` [PATCH RFC 0/7] sysctl: constify sysctl ctl_tables Thomas Weißschuh
                     ` (2 preceding siblings ...)
  2023-11-25 12:52   ` [PATCH RFC 3/7] sysctl: add proc_handler_new to struct ctl_table Thomas Weißschuh
@ 2023-11-25 12:52   ` Thomas Weißschuh
  2023-11-25 12:52   ` [PATCH RFC 5/7] treewide: sysctl: migrate proc_dostring to proc_handler_new Thomas Weißschuh
                     ` (3 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Thomas Weißschuh @ 2023-11-25 12:52 UTC (permalink / raw)
  To: Kees Cook, Gustavo A. R. Silva, Luis Chamberlain, Iurii Zaikin,
	Greg Kroah-Hartman, Joel Granados
  Cc: linux-hardening, linux-kernel, linux-fsdevel,
	Thomas Weißschuh

The sysctl core introduce an alternative handler function.
Log it in the debug message, too.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
 net/sysctl_net.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/net/sysctl_net.c b/net/sysctl_net.c
index 051ed5f6fc93..29d871097ddc 100644
--- a/net/sysctl_net.c
+++ b/net/sysctl_net.c
@@ -132,8 +132,9 @@ static void ensure_safe_net_sysctl(struct net *net, const char *path,
 		unsigned long addr;
 		const char *where;
 
-		pr_debug("  procname=%s mode=%o proc_handler=%ps data=%p\n",
-			 ent->procname, ent->mode, ent->proc_handler, ent->data);
+		pr_debug("  procname=%s mode=%o proc_handler=%ps/%ps data=%p\n",
+			 ent->procname, ent->mode, ent->proc_handler,
+			 ent->proc_handler_new, ent->data);
 
 		/* If it's not writable inside the netns, then it can't hurt. */
 		if ((ent->mode & 0222) == 0) {

-- 
2.43.0


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

* [PATCH RFC 5/7] treewide: sysctl: migrate proc_dostring to proc_handler_new
  2023-11-25 12:52 ` [PATCH RFC 0/7] sysctl: constify sysctl ctl_tables Thomas Weißschuh
                     ` (3 preceding siblings ...)
  2023-11-25 12:52   ` [PATCH RFC 4/7] net: sysctl: add new sysctl table handler to debug message Thomas Weißschuh
@ 2023-11-25 12:52   ` Thomas Weißschuh
  2023-11-25 12:52   ` [PATCH RFC 6/7] treewide: sysctl: migrate proc_dobool " Thomas Weißschuh
                     ` (2 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Thomas Weißschuh @ 2023-11-25 12:52 UTC (permalink / raw)
  To: Kees Cook, Gustavo A. R. Silva, Luis Chamberlain, Iurii Zaikin,
	Greg Kroah-Hartman, Joel Granados
  Cc: linux-hardening, linux-kernel, linux-fsdevel,
	Thomas Weißschuh

proc_handler_new() prevents the handler function from modifying the
ctl_table which then can be put into .rodata.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
 crypto/fips.c          |  4 ++--
 fs/coredump.c          |  2 +-
 fs/ocfs2/stackglue.c   |  2 +-
 fs/proc/proc_sysctl.c  |  2 +-
 include/linux/sysctl.h |  2 +-
 kernel/reboot.c        |  2 +-
 kernel/seccomp.c       |  2 +-
 kernel/sysctl.c        | 14 +++++++-------
 lib/test_sysctl.c      |  2 +-
 net/mptcp/ctrl.c       |  2 +-
 10 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/crypto/fips.c b/crypto/fips.c
index 92fd506abb21..d492f23bf53b 100644
--- a/crypto/fips.c
+++ b/crypto/fips.c
@@ -54,14 +54,14 @@ static struct ctl_table crypto_sysctl_table[] = {
 		.data		= &fips_name,
 		.maxlen		= 64,
 		.mode		= 0444,
-		.proc_handler	= proc_dostring
+		.proc_handler_new	= proc_dostring
 	},
 	{
 		.procname	= "fips_version",
 		.data		= &fips_version,
 		.maxlen		= 64,
 		.mode		= 0444,
-		.proc_handler	= proc_dostring
+		.proc_handler_new	= proc_dostring
 	},
 	{}
 };
diff --git a/fs/coredump.c b/fs/coredump.c
index 9d235fa14ab9..733cb795f678 100644
--- a/fs/coredump.c
+++ b/fs/coredump.c
@@ -972,7 +972,7 @@ static struct ctl_table coredump_sysctls[] = {
 		.data		= core_pattern,
 		.maxlen		= CORENAME_MAX_SIZE,
 		.mode		= 0644,
-		.proc_handler	= proc_dostring_coredump,
+		.proc_handler_new	= proc_dostring_coredump,
 	},
 	{
 		.procname	= "core_pipe_limit",
diff --git a/fs/ocfs2/stackglue.c b/fs/ocfs2/stackglue.c
index a8d5ca98fa57..e4eedd1d6b7d 100644
--- a/fs/ocfs2/stackglue.c
+++ b/fs/ocfs2/stackglue.c
@@ -656,7 +656,7 @@ static struct ctl_table ocfs2_nm_table[] = {
 		.data		= ocfs2_hb_ctl_path,
 		.maxlen		= OCFS2_MAX_HB_CTL_PATH,
 		.mode		= 0644,
-		.proc_handler	= proc_dostring,
+		.proc_handler_new	= proc_dostring,
 	},
 	{ }
 };
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index 810ecdd3b84c..0817d315fa36 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -1132,7 +1132,7 @@ static int sysctl_check_table(const char *path, struct ctl_table_header *header)
 	struct ctl_table *entry;
 	int err = 0;
 	list_for_each_table_entry(entry, header) {
-		if ((entry->proc_handler == proc_dostring) ||
+		if ((entry->proc_handler_new == proc_dostring) ||
 		    (entry->proc_handler == proc_dobool) ||
 		    (entry->proc_handler == proc_dointvec) ||
 		    (entry->proc_handler == proc_douintvec) ||
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index de1a5a714070..2699605c5da5 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -66,7 +66,7 @@ typedef int proc_handler(struct ctl_table *ctl, int write, void *buffer,
 typedef int proc_handler_new(const struct ctl_table *ctl, int write,
 		void *buffer, size_t *lenp, loff_t *ppos);
 
-int proc_dostring(struct ctl_table *, int, void *, size_t *, loff_t *);
+int proc_dostring(const struct ctl_table *, int, void *, size_t *, loff_t *);
 int proc_dobool(struct ctl_table *table, int write, void *buffer,
 		size_t *lenp, loff_t *ppos);
 int proc_dointvec(struct ctl_table *, int, void *, size_t *, loff_t *);
diff --git a/kernel/reboot.c b/kernel/reboot.c
index 395a0ea3c7a8..69681100d884 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -1267,7 +1267,7 @@ static struct ctl_table kern_reboot_table[] = {
 		.data           = &poweroff_cmd,
 		.maxlen         = POWEROFF_CMD_PATH_LEN,
 		.mode           = 0644,
-		.proc_handler   = proc_dostring,
+		.proc_handler_new   = proc_dostring,
 	},
 	{
 		.procname       = "ctrl-alt-del",
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 255999ba9190..29e9663cf220 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -2438,7 +2438,7 @@ static struct ctl_table seccomp_sysctl_table[] = {
 		.data		= (void *) &seccomp_actions_avail,
 		.maxlen		= sizeof(seccomp_actions_avail),
 		.mode		= 0444,
-		.proc_handler	= proc_dostring,
+		.proc_handler_new	= proc_dostring,
 	},
 	{
 		.procname	= "actions_logged",
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 157f7ce2942d..7acd1cde0a5c 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -205,7 +205,7 @@ static int _proc_do_string(char *data, int maxlen, int write,
 	return 0;
 }
 
-static void warn_sysctl_write(struct ctl_table *table)
+static void warn_sysctl_write(const struct ctl_table *table)
 {
 	pr_warn_once("%s wrote to %s when file position was not 0!\n"
 		"This will not be supported in the future. To silence this\n"
@@ -223,7 +223,7 @@ static void warn_sysctl_write(struct ctl_table *table)
  * handlers can ignore the return value.
  */
 static bool proc_first_pos_non_zero_ignore(loff_t *ppos,
-					   struct ctl_table *table)
+					   const struct ctl_table *table)
 {
 	if (!*ppos)
 		return false;
@@ -256,7 +256,7 @@ static bool proc_first_pos_non_zero_ignore(loff_t *ppos,
  *
  * Returns 0 on success.
  */
-int proc_dostring(struct ctl_table *table, int write,
+int proc_dostring(const struct ctl_table *table, int write,
 		  void *buffer, size_t *lenp, loff_t *ppos)
 {
 	if (write)
@@ -1498,7 +1498,7 @@ int proc_do_large_bitmap(struct ctl_table *table, int write,
 
 #else /* CONFIG_PROC_SYSCTL */
 
-int proc_dostring(struct ctl_table *table, int write,
+int proc_dostring(const struct ctl_table *table, int write,
 		  void *buffer, size_t *lenp, loff_t *ppos)
 {
 	return -ENOSYS;
@@ -1653,7 +1653,7 @@ static struct ctl_table kern_table[] = {
 		.data		= reboot_command,
 		.maxlen		= 256,
 		.mode		= 0644,
-		.proc_handler	= proc_dostring,
+		.proc_handler_new	= proc_dostring,
 	},
 	{
 		.procname	= "stop-a",
@@ -1735,7 +1735,7 @@ static struct ctl_table kern_table[] = {
 		.data		= &modprobe_path,
 		.maxlen		= KMOD_PATH_LEN,
 		.mode		= 0644,
-		.proc_handler	= proc_dostring,
+		.proc_handler_new	= proc_dostring,
 	},
 	{
 		.procname	= "modules_disabled",
@@ -1754,7 +1754,7 @@ static struct ctl_table kern_table[] = {
 		.data		= &uevent_helper,
 		.maxlen		= UEVENT_HELPER_PATH_LEN,
 		.mode		= 0644,
-		.proc_handler	= proc_dostring,
+		.proc_handler_new	= proc_dostring,
 	},
 #endif
 #ifdef CONFIG_MAGIC_SYSRQ
diff --git a/lib/test_sysctl.c b/lib/test_sysctl.c
index 8036aa91a1cb..de42e3d99912 100644
--- a/lib/test_sysctl.c
+++ b/lib/test_sysctl.c
@@ -121,7 +121,7 @@ static struct ctl_table test_table[] = {
 		.data		= &test_data.string_0001,
 		.maxlen		= sizeof(test_data.string_0001),
 		.mode		= 0644,
-		.proc_handler	= proc_dostring,
+		.proc_handler_new	= proc_dostring,
 	},
 	{
 		.procname	= "bitmap_0001",
diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c
index 13fe0748dde8..6de3178b81b4 100644
--- a/net/mptcp/ctrl.c
+++ b/net/mptcp/ctrl.c
@@ -148,7 +148,7 @@ static struct ctl_table mptcp_sysctl_table[] = {
 		.procname = "scheduler",
 		.maxlen	= MPTCP_SCHED_NAME_MAX,
 		.mode = 0644,
-		.proc_handler = proc_dostring,
+		.proc_handler_new = proc_dostring,
 	},
 	{
 		.procname = "close_timeout",

-- 
2.43.0


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

* [PATCH RFC 6/7] treewide: sysctl: migrate proc_dobool to proc_handler_new
  2023-11-25 12:52 ` [PATCH RFC 0/7] sysctl: constify sysctl ctl_tables Thomas Weißschuh
                     ` (4 preceding siblings ...)
  2023-11-25 12:52   ` [PATCH RFC 5/7] treewide: sysctl: migrate proc_dostring to proc_handler_new Thomas Weißschuh
@ 2023-11-25 12:52   ` Thomas Weißschuh
  2023-11-25 12:52   ` [PATCH RFC 7/7] treewide: sysctl: migrate proc_dointvec " Thomas Weißschuh
  2023-11-27 10:13   ` [PATCH RFC 0/7] sysctl: constify sysctl ctl_tables Joel Granados
  7 siblings, 0 replies; 13+ messages in thread
From: Thomas Weißschuh @ 2023-11-25 12:52 UTC (permalink / raw)
  To: Kees Cook, Gustavo A. R. Silva, Luis Chamberlain, Iurii Zaikin,
	Greg Kroah-Hartman, Joel Granados
  Cc: linux-hardening, linux-kernel, linux-fsdevel,
	Thomas Weißschuh

proc_handler_new() prevents the handler function from modifying the
ctl_table which then can be put into .rodata.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
 arch/riscv/kernel/vector.c | 2 +-
 drivers/tty/tty_io.c       | 2 +-
 fs/lockd/svc.c             | 2 +-
 fs/proc/proc_sysctl.c      | 4 ++--
 include/linux/sysctl.h     | 2 +-
 kernel/sysctl.c            | 4 ++--
 mm/hugetlb_vmemmap.c       | 2 +-
 7 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/riscv/kernel/vector.c b/arch/riscv/kernel/vector.c
index 578b6292487e..d2a37fe88174 100644
--- a/arch/riscv/kernel/vector.c
+++ b/arch/riscv/kernel/vector.c
@@ -253,7 +253,7 @@ static struct ctl_table riscv_v_default_vstate_table[] = {
 		.data		= &riscv_v_implicit_uacc,
 		.maxlen		= sizeof(riscv_v_implicit_uacc),
 		.mode		= 0644,
-		.proc_handler	= proc_dobool,
+		.proc_handler_new	= proc_dobool,
 	},
 };
 
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 06414e43e0b5..a7bcc22fdae9 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -3601,7 +3601,7 @@ static struct ctl_table tty_table[] = {
 		.data		= &tty_legacy_tiocsti,
 		.maxlen		= sizeof(tty_legacy_tiocsti),
 		.mode		= 0644,
-		.proc_handler	= proc_dobool,
+		.proc_handler_new	= proc_dobool,
 	},
 	{
 		.procname	= "ldisc_autoload",
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 81be07c1d3d1..90ea8cd382d3 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -466,7 +466,7 @@ static struct ctl_table nlm_sysctls[] = {
 		.data		= &nsm_use_hostnames,
 		.maxlen		= sizeof(bool),
 		.mode		= 0644,
-		.proc_handler	= proc_dobool,
+		.proc_handler_new	= proc_dobool,
 	},
 	{
 		.procname	= "nsm_local_state",
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index 0817d315fa36..742a99540f2b 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -1119,7 +1119,7 @@ static int sysctl_check_table_array(const char *path, struct ctl_table *table)
 			err |= sysctl_err(path, table, "array not allowed");
 	}
 
-	if (table->proc_handler == proc_dobool) {
+	if (table->proc_handler_new == proc_dobool) {
 		if (table->maxlen != sizeof(bool))
 			err |= sysctl_err(path, table, "array not allowed");
 	}
@@ -1133,7 +1133,7 @@ static int sysctl_check_table(const char *path, struct ctl_table_header *header)
 	int err = 0;
 	list_for_each_table_entry(entry, header) {
 		if ((entry->proc_handler_new == proc_dostring) ||
-		    (entry->proc_handler == proc_dobool) ||
+		    (entry->proc_handler_new == proc_dobool) ||
 		    (entry->proc_handler == proc_dointvec) ||
 		    (entry->proc_handler == proc_douintvec) ||
 		    (entry->proc_handler == proc_douintvec_minmax) ||
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 2699605c5da5..2dfaf718a21b 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -67,7 +67,7 @@ typedef int proc_handler_new(const struct ctl_table *ctl, int write,
 		void *buffer, size_t *lenp, loff_t *ppos);
 
 int proc_dostring(const struct ctl_table *, int, void *, size_t *, loff_t *);
-int proc_dobool(struct ctl_table *table, int write, void *buffer,
+int proc_dobool(const struct ctl_table *table, int write, void *buffer,
 		size_t *lenp, loff_t *ppos);
 int proc_dointvec(struct ctl_table *, int, void *, size_t *, loff_t *);
 int proc_douintvec(struct ctl_table *, int, void *, size_t *, loff_t *);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 7acd1cde0a5c..c76668f47bcc 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -702,7 +702,7 @@ int do_proc_douintvec(struct ctl_table *table, int write,
  *
  * Returns 0 on success.
  */
-int proc_dobool(struct ctl_table *table, int write, void *buffer,
+int proc_dobool(const struct ctl_table *table, int write, void *buffer,
 		size_t *lenp, loff_t *ppos)
 {
 	struct ctl_table tmp;
@@ -1504,7 +1504,7 @@ int proc_dostring(const struct ctl_table *table, int write,
 	return -ENOSYS;
 }
 
-int proc_dobool(struct ctl_table *table, int write,
+int proc_dobool(const struct ctl_table *table, int write,
 		void *buffer, size_t *lenp, loff_t *ppos)
 {
 	return -ENOSYS;
diff --git a/mm/hugetlb_vmemmap.c b/mm/hugetlb_vmemmap.c
index 87818ee7f01d..e61e9fbfd639 100644
--- a/mm/hugetlb_vmemmap.c
+++ b/mm/hugetlb_vmemmap.c
@@ -779,7 +779,7 @@ static struct ctl_table hugetlb_vmemmap_sysctls[] = {
 		.data		= &vmemmap_optimize_enabled,
 		.maxlen		= sizeof(vmemmap_optimize_enabled),
 		.mode		= 0644,
-		.proc_handler	= proc_dobool,
+		.proc_handler_new	= proc_dobool,
 	},
 	{ }
 };

-- 
2.43.0


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

* [PATCH RFC 7/7] treewide: sysctl: migrate proc_dointvec to proc_handler_new
  2023-11-25 12:52 ` [PATCH RFC 0/7] sysctl: constify sysctl ctl_tables Thomas Weißschuh
                     ` (5 preceding siblings ...)
  2023-11-25 12:52   ` [PATCH RFC 6/7] treewide: sysctl: migrate proc_dobool " Thomas Weißschuh
@ 2023-11-25 12:52   ` Thomas Weißschuh
  2023-11-27 10:13   ` [PATCH RFC 0/7] sysctl: constify sysctl ctl_tables Joel Granados
  7 siblings, 0 replies; 13+ messages in thread
From: Thomas Weißschuh @ 2023-11-25 12:52 UTC (permalink / raw)
  To: Kees Cook, Gustavo A. R. Silva, Luis Chamberlain, Iurii Zaikin,
	Greg Kroah-Hartman, Joel Granados
  Cc: linux-hardening, linux-kernel, linux-fsdevel,
	Thomas Weißschuh

proc_handler_new() prevents the handler function from modifying the
ctl_table which then can be put into .rodata.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
 arch/arm/kernel/isa.c                   |  6 +--
 arch/csky/abiv1/alignment.c             |  8 ++--
 arch/powerpc/kernel/idle.c              |  2 +-
 arch/s390/kernel/debug.c                |  2 +-
 crypto/fips.c                           |  2 +-
 drivers/char/hpet.c                     |  2 +-
 drivers/char/random.c                   |  4 +-
 drivers/infiniband/core/iwcm.c          |  2 +-
 drivers/infiniband/core/ucma.c          |  2 +-
 drivers/macintosh/mac_hid.c             |  4 +-
 drivers/md/md.c                         |  4 +-
 drivers/scsi/sg.c                       |  2 +-
 drivers/tty/tty_io.c                    |  2 +-
 fs/coda/sysctl.c                        |  6 +--
 fs/coredump.c                           |  4 +-
 fs/devpts/inode.c                       |  2 +-
 fs/lockd/svc.c                          |  2 +-
 fs/locks.c                              |  4 +-
 fs/nfs/nfs4sysctl.c                     |  2 +-
 fs/nfs/sysctl.c                         |  2 +-
 fs/notify/dnotify/dnotify.c             |  2 +-
 fs/ntfs/sysctl.c                        |  2 +-
 fs/proc/proc_sysctl.c                   |  2 +-
 fs/quota/dquot.c                        |  2 +-
 include/linux/sysctl.h                  |  2 +-
 init/do_mounts_initrd.c                 |  2 +-
 io_uring/io_uring.c                     |  2 +-
 ipc/mq_sysctl.c                         |  2 +-
 kernel/acct.c                           |  2 +-
 kernel/locking/lockdep.c                |  4 +-
 kernel/printk/sysctl.c                  |  4 +-
 kernel/reboot.c                         |  2 +-
 kernel/signal.c                         |  2 +-
 kernel/sysctl-test.c                    | 20 ++++-----
 kernel/sysctl.c                         | 62 ++++++++++++++--------------
 lib/test_sysctl.c                       |  8 ++--
 mm/hugetlb.c                            |  2 +-
 mm/oom_kill.c                           |  4 +-
 net/appletalk/sysctl_net_atalk.c        |  2 +-
 net/core/sysctl_net_core.c              | 12 +++---
 net/ipv4/route.c                        | 18 ++++-----
 net/ipv4/sysctl_net_ipv4.c              | 38 ++++++++---------
 net/ipv4/xfrm4_policy.c                 |  2 +-
 net/ipv6/addrconf.c                     | 72 ++++++++++++++++-----------------
 net/ipv6/route.c                        |  8 ++--
 net/ipv6/sysctl_net_ipv6.c              | 18 ++++-----
 net/ipv6/xfrm6_policy.c                 |  2 +-
 net/netfilter/ipvs/ip_vs_ctl.c          | 36 ++++++++---------
 net/netfilter/nf_conntrack_standalone.c |  8 ++--
 net/netfilter/nf_log.c                  |  2 +-
 net/rds/ib_sysctl.c                     |  2 +-
 net/rds/sysctl.c                        |  6 +--
 net/sctp/sysctl.c                       | 26 ++++++------
 net/sunrpc/xprtrdma/transport.c         |  2 +-
 net/unix/sysctl_net_unix.c              |  2 +-
 net/x25/sysctl_net_x25.c                |  2 +-
 net/xfrm/xfrm_sysctl.c                  |  4 +-
 57 files changed, 226 insertions(+), 226 deletions(-)

diff --git a/arch/arm/kernel/isa.c b/arch/arm/kernel/isa.c
index 905b1b191546..f2a089e487a2 100644
--- a/arch/arm/kernel/isa.c
+++ b/arch/arm/kernel/isa.c
@@ -22,19 +22,19 @@ static struct ctl_table ctl_isa_vars[] = {
 		.data		= &isa_membase, 
 		.maxlen		= sizeof(isa_membase),
 		.mode		= 0444,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	}, {
 		.procname	= "portbase",
 		.data		= &isa_portbase, 
 		.maxlen		= sizeof(isa_portbase),
 		.mode		= 0444,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	}, {
 		.procname	= "portshift",
 		.data		= &isa_portshift, 
 		.maxlen		= sizeof(isa_portshift),
 		.mode		= 0444,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 };
 
diff --git a/arch/csky/abiv1/alignment.c b/arch/csky/abiv1/alignment.c
index e5b8b4b2109a..e3ef2cad2713 100644
--- a/arch/csky/abiv1/alignment.c
+++ b/arch/csky/abiv1/alignment.c
@@ -306,28 +306,28 @@ static struct ctl_table alignment_tbl[5] = {
 		.data = &align_kern_enable,
 		.maxlen = sizeof(align_kern_enable),
 		.mode = 0666,
-		.proc_handler = &proc_dointvec
+		.proc_handler_new = &proc_dointvec
 	},
 	{
 		.procname = "user_enable",
 		.data = &align_usr_enable,
 		.maxlen = sizeof(align_usr_enable),
 		.mode = 0666,
-		.proc_handler = &proc_dointvec
+		.proc_handler_new = &proc_dointvec
 	},
 	{
 		.procname = "kernel_count",
 		.data = &align_kern_count,
 		.maxlen = sizeof(align_kern_count),
 		.mode = 0666,
-		.proc_handler = &proc_dointvec
+		.proc_handler_new = &proc_dointvec
 	},
 	{
 		.procname = "user_count",
 		.data = &align_usr_count,
 		.maxlen = sizeof(align_usr_count),
 		.mode = 0666,
-		.proc_handler = &proc_dointvec
+		.proc_handler_new = &proc_dointvec
 	},
 };
 
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c
index 30b56c67fa61..c2ebd558c9c0 100644
--- a/arch/powerpc/kernel/idle.c
+++ b/arch/powerpc/kernel/idle.c
@@ -103,7 +103,7 @@ static struct ctl_table powersave_nap_ctl_table[] = {
 		.data		= &powersave_nap,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 };
 
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index 85328a0ef3b6..eb5535710386 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -969,7 +969,7 @@ static struct ctl_table s390dbf_table[] = {
 		.data		= &debug_stoppable,
 		.maxlen		= sizeof(int),
 		.mode		= S_IRUGO | S_IWUSR,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "debug_active",
diff --git a/crypto/fips.c b/crypto/fips.c
index d492f23bf53b..d082685301aa 100644
--- a/crypto/fips.c
+++ b/crypto/fips.c
@@ -47,7 +47,7 @@ static struct ctl_table crypto_sysctl_table[] = {
 		.data		= &fips_enabled,
 		.maxlen		= sizeof(int),
 		.mode		= 0444,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "fips_name",
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 9c90b1d2c036..d2ba7dcbf8e8 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -707,7 +707,7 @@ static struct ctl_table hpet_table[] = {
 	 .data = &hpet_max_freq,
 	 .maxlen = sizeof(int),
 	 .mode = 0644,
-	 .proc_handler = proc_dointvec,
+	 .proc_handler_new = proc_dointvec,
 	 },
 };
 
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 4a9c79391dee..0b2f01f89478 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1649,14 +1649,14 @@ static struct ctl_table random_table[] = {
 		.data		= &sysctl_poolsize,
 		.maxlen		= sizeof(int),
 		.mode		= 0444,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "entropy_avail",
 		.data		= &input_pool.init_bits,
 		.maxlen		= sizeof(int),
 		.mode		= 0444,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "write_wakeup_threshold",
diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c
index 0301fcad4b48..b9257465f8a8 100644
--- a/drivers/infiniband/core/iwcm.c
+++ b/drivers/infiniband/core/iwcm.c
@@ -109,7 +109,7 @@ static struct ctl_table iwcm_ctl_table[] = {
 		.data		= &default_backlog,
 		.maxlen		= sizeof(default_backlog),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 };
 
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index 5f5ad8faf86e..2148fc1a04fa 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -69,7 +69,7 @@ static struct ctl_table ucma_ctl_table[] = {
 		.data		= &max_backlog,
 		.maxlen		= sizeof max_backlog,
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 };
 
diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c
index 1ae3539beff5..dc992d16067a 100644
--- a/drivers/macintosh/mac_hid.c
+++ b/drivers/macintosh/mac_hid.c
@@ -227,14 +227,14 @@ static struct ctl_table mac_hid_files[] = {
 		.data		= &mouse_button2_keycode,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "mouse_button3_keycode",
 		.data		= &mouse_button3_keycode,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 };
 
diff --git a/drivers/md/md.c b/drivers/md/md.c
index c94373d64f2c..df1ec9e16689 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -295,14 +295,14 @@ static struct ctl_table raid_table[] = {
 		.data		= &sysctl_speed_limit_min,
 		.maxlen		= sizeof(int),
 		.mode		= S_IRUGO|S_IWUSR,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "speed_limit_max",
 		.data		= &sysctl_speed_limit_max,
 		.maxlen		= sizeof(int),
 		.mode		= S_IRUGO|S_IWUSR,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 };
 
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 86210e4dd0d3..e85d25602d9e 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1648,7 +1648,7 @@ static struct ctl_table sg_sysctls[] = {
 		.data		= &sg_big_buff,
 		.maxlen		= sizeof(int),
 		.mode		= 0444,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 };
 
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index a7bcc22fdae9..ad929011a68d 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -3608,7 +3608,7 @@ static struct ctl_table tty_table[] = {
 		.data		= &tty_ldisc_autoload,
 		.maxlen		= sizeof(tty_ldisc_autoload),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 		.extra1		= SYSCTL_ZERO,
 		.extra2		= SYSCTL_ONE,
 	},
diff --git a/fs/coda/sysctl.c b/fs/coda/sysctl.c
index a247c14aaab7..f59959ee8dcc 100644
--- a/fs/coda/sysctl.c
+++ b/fs/coda/sysctl.c
@@ -20,21 +20,21 @@ static struct ctl_table coda_table[] = {
 		.data		= &coda_timeout,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "hard",
 		.data		= &coda_hard,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "fake_statfs",
 		.data		= &coda_fake_statfs,
 		.maxlen		= sizeof(int),
 		.mode		= 0600,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{}
 };
diff --git a/fs/coredump.c b/fs/coredump.c
index 733cb795f678..62747af9a417 100644
--- a/fs/coredump.c
+++ b/fs/coredump.c
@@ -965,7 +965,7 @@ static struct ctl_table coredump_sysctls[] = {
 		.data		= &core_uses_pid,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "core_pattern",
@@ -979,7 +979,7 @@ static struct ctl_table coredump_sysctls[] = {
 		.data		= &core_pipe_limit,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{ }
 };
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index c830261aa883..c786a3f2c1c2 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -67,7 +67,7 @@ static struct ctl_table pty_table[] = {
 		.maxlen		= sizeof(int),
 		.mode		= 0444,
 		.data		= &pty_count,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{}
 };
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 90ea8cd382d3..6b0fd89990dc 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -473,7 +473,7 @@ static struct ctl_table nlm_sysctls[] = {
 		.data		= &nsm_local_state,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{ }
 };
diff --git a/fs/locks.c b/fs/locks.c
index 46d88b9e222c..c99faee56d7d 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -100,7 +100,7 @@ static struct ctl_table locks_sysctls[] = {
 		.data		= &leases_enable,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #ifdef CONFIG_MMU
 	{
@@ -108,7 +108,7 @@ static struct ctl_table locks_sysctls[] = {
 		.data		= &lease_break_time,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #endif /* CONFIG_MMU */
 	{}
diff --git a/fs/nfs/nfs4sysctl.c b/fs/nfs/nfs4sysctl.c
index e776200e9a11..2270bbe81e07 100644
--- a/fs/nfs/nfs4sysctl.c
+++ b/fs/nfs/nfs4sysctl.c
@@ -32,7 +32,7 @@ static struct ctl_table nfs4_cb_sysctls[] = {
 		.data = &nfs_idmap_cache_timeout,
 		.maxlen = sizeof(int),
 		.mode = 0644,
-		.proc_handler = proc_dointvec,
+		.proc_handler_new = proc_dointvec,
 	},
 	{ }
 };
diff --git a/fs/nfs/sysctl.c b/fs/nfs/sysctl.c
index f39e2089bc4c..57cf00765062 100644
--- a/fs/nfs/sysctl.c
+++ b/fs/nfs/sysctl.c
@@ -27,7 +27,7 @@ static struct ctl_table nfs_cb_sysctls[] = {
 		.data		= &nfs_congestion_kb,
 		.maxlen		= sizeof(nfs_congestion_kb),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{ }
 };
diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c
index 1cb9ad7e884e..6d1662ce7998 100644
--- a/fs/notify/dnotify/dnotify.c
+++ b/fs/notify/dnotify/dnotify.c
@@ -27,7 +27,7 @@ static struct ctl_table dnotify_sysctls[] = {
 		.data		= &dir_notify_enable,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{}
 };
diff --git a/fs/ntfs/sysctl.c b/fs/ntfs/sysctl.c
index 174fe536a1c0..d1d308ef5479 100644
--- a/fs/ntfs/sysctl.c
+++ b/fs/ntfs/sysctl.c
@@ -26,7 +26,7 @@ static struct ctl_table ntfs_sysctls[] = {
 		.data		= &debug_msgs,		/* Data pointer and size. */
 		.maxlen		= sizeof(debug_msgs),
 		.mode		= 0644,			/* Mode, proc handler. */
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{}
 };
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index 742a99540f2b..b7e104b6f7ea 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -1134,7 +1134,7 @@ static int sysctl_check_table(const char *path, struct ctl_table_header *header)
 	list_for_each_table_entry(entry, header) {
 		if ((entry->proc_handler_new == proc_dostring) ||
 		    (entry->proc_handler_new == proc_dobool) ||
-		    (entry->proc_handler == proc_dointvec) ||
+		    (entry->proc_handler_new == proc_dointvec) ||
 		    (entry->proc_handler == proc_douintvec) ||
 		    (entry->proc_handler == proc_douintvec_minmax) ||
 		    (entry->proc_handler == proc_dointvec_minmax) ||
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 58b5de081b57..4f5d93ac9caa 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -2966,7 +2966,7 @@ static struct ctl_table fs_dqstats_table[] = {
 		.data		= &flag_print_warnings,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #endif
 	{ },
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 2dfaf718a21b..58e9ddbbe828 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -69,7 +69,7 @@ typedef int proc_handler_new(const struct ctl_table *ctl, int write,
 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(struct ctl_table *, int, void *, size_t *, loff_t *);
+int proc_dointvec(const struct ctl_table *, int, void *, size_t *, loff_t *);
 int proc_douintvec(struct ctl_table *, int, void *, size_t *, loff_t *);
 int proc_dointvec_minmax(struct ctl_table *, int, void *, size_t *, loff_t *);
 int proc_douintvec_minmax(struct ctl_table *table, int write, void *buffer,
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index 425f4bcf4b77..8504e84ffc78 100644
--- a/init/do_mounts_initrd.c
+++ b/init/do_mounts_initrd.c
@@ -27,7 +27,7 @@ static struct ctl_table kern_do_mounts_initrd_table[] = {
 		.data           = &real_root_dev,
 		.maxlen         = sizeof(int),
 		.mode           = 0644,
-		.proc_handler   = proc_dointvec,
+		.proc_handler_new   = proc_dointvec,
 	},
 	{ }
 };
diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
index ed254076c723..0b91e6eed0f3 100644
--- a/io_uring/io_uring.c
+++ b/io_uring/io_uring.c
@@ -171,7 +171,7 @@ static struct ctl_table kernel_io_uring_disabled_table[] = {
 		.data		= &sysctl_io_uring_group,
 		.maxlen		= sizeof(gid_t),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{},
 };
diff --git a/ipc/mq_sysctl.c b/ipc/mq_sysctl.c
index ebb5ed81c151..478306e997c6 100644
--- a/ipc/mq_sysctl.c
+++ b/ipc/mq_sysctl.c
@@ -25,7 +25,7 @@ static struct ctl_table mq_sysctls[] = {
 		.data		= &init_ipc_ns.mq_queues_max,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "msg_max",
diff --git a/kernel/acct.c b/kernel/acct.c
index 986c8214dabf..007b9c08b0a9 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -82,7 +82,7 @@ static struct ctl_table kern_acct_table[] = {
 		.data           = &acct_parm,
 		.maxlen         = 3*sizeof(int),
 		.mode           = 0644,
-		.proc_handler   = proc_dointvec,
+		.proc_handler_new   = proc_dointvec,
 	},
 	{ }
 };
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index e85b5ad3e206..ea14dd786d82 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -85,7 +85,7 @@ static struct ctl_table kern_lockdep_table[] = {
 		.data           = &prove_locking,
 		.maxlen         = sizeof(int),
 		.mode           = 0644,
-		.proc_handler   = proc_dointvec,
+		.proc_handler_new   = proc_dointvec,
 	},
 #endif /* CONFIG_PROVE_LOCKING */
 #ifdef CONFIG_LOCK_STAT
@@ -94,7 +94,7 @@ static struct ctl_table kern_lockdep_table[] = {
 		.data           = &lock_stat,
 		.maxlen         = sizeof(int),
 		.mode           = 0644,
-		.proc_handler   = proc_dointvec,
+		.proc_handler_new   = proc_dointvec,
 	},
 #endif /* CONFIG_LOCK_STAT */
 	{ }
diff --git a/kernel/printk/sysctl.c b/kernel/printk/sysctl.c
index c228343eeb97..009f5a9c7b75 100644
--- a/kernel/printk/sysctl.c
+++ b/kernel/printk/sysctl.c
@@ -26,7 +26,7 @@ static struct ctl_table printk_sysctls[] = {
 		.data		= &console_loglevel,
 		.maxlen		= 4*sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "printk_ratelimit",
@@ -40,7 +40,7 @@ static struct ctl_table printk_sysctls[] = {
 		.data		= &printk_ratelimit_state.burst,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "printk_delay",
diff --git a/kernel/reboot.c b/kernel/reboot.c
index 69681100d884..9881f2ef5a21 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -1274,7 +1274,7 @@ static struct ctl_table kern_reboot_table[] = {
 		.data           = &C_A_D,
 		.maxlen         = sizeof(int),
 		.mode           = 0644,
-		.proc_handler   = proc_dointvec,
+		.proc_handler_new   = proc_dointvec,
 	},
 	{ }
 };
diff --git a/kernel/signal.c b/kernel/signal.c
index 47a7602dfe8d..d3c8f1150005 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -4809,7 +4809,7 @@ static struct ctl_table signal_debug_table[] = {
 		.data		= &show_unhandled_signals,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 #endif
 	{ }
diff --git a/kernel/sysctl-test.c b/kernel/sysctl-test.c
index 6ef887c19c48..a79878ba7fc6 100644
--- a/kernel/sysctl-test.c
+++ b/kernel/sysctl-test.c
@@ -25,7 +25,7 @@ static void sysctl_test_api_dointvec_null_tbl_data(struct kunit *test)
 		.data		= NULL,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 		.extra1		= SYSCTL_ZERO,
 		.extra2         = SYSCTL_ONE_HUNDRED,
 	};
@@ -75,7 +75,7 @@ static void sysctl_test_api_dointvec_table_maxlen_unset(struct kunit *test)
 		 */
 		.maxlen		= 0,
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 		.extra1		= SYSCTL_ZERO,
 		.extra2         = SYSCTL_ONE_HUNDRED,
 	};
@@ -118,7 +118,7 @@ static void sysctl_test_api_dointvec_table_len_is_zero(struct kunit *test)
 		.data		= &data,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 		.extra1		= SYSCTL_ZERO,
 		.extra2         = SYSCTL_ONE_HUNDRED,
 	};
@@ -152,7 +152,7 @@ static void sysctl_test_api_dointvec_table_read_but_position_set(
 		.data		= &data,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 		.extra1		= SYSCTL_ZERO,
 		.extra2         = SYSCTL_ONE_HUNDRED,
 	};
@@ -187,7 +187,7 @@ static void sysctl_test_dointvec_read_happy_single_positive(struct kunit *test)
 		.data		= &data,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 		.extra1		= SYSCTL_ZERO,
 		.extra2         = SYSCTL_ONE_HUNDRED,
 	};
@@ -218,7 +218,7 @@ static void sysctl_test_dointvec_read_happy_single_negative(struct kunit *test)
 		.data		= &data,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 		.extra1		= SYSCTL_ZERO,
 		.extra2         = SYSCTL_ONE_HUNDRED,
 	};
@@ -247,7 +247,7 @@ static void sysctl_test_dointvec_write_happy_single_positive(struct kunit *test)
 		.data		= &data,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 		.extra1		= SYSCTL_ZERO,
 		.extra2         = SYSCTL_ONE_HUNDRED,
 	};
@@ -277,7 +277,7 @@ static void sysctl_test_dointvec_write_happy_single_negative(struct kunit *test)
 		.data		= &data,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 		.extra1		= SYSCTL_ZERO,
 		.extra2         = SYSCTL_ONE_HUNDRED,
 	};
@@ -309,7 +309,7 @@ static void sysctl_test_api_dointvec_write_single_less_int_min(
 		.data		= &data,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 		.extra1		= SYSCTL_ZERO,
 		.extra2         = SYSCTL_ONE_HUNDRED,
 	};
@@ -347,7 +347,7 @@ static void sysctl_test_api_dointvec_write_single_greater_int_max(
 		.data		= &data,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 		.extra1		= SYSCTL_ZERO,
 		.extra2         = SYSCTL_ONE_HUNDRED,
 	};
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index c76668f47bcc..c02c98246621 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -468,7 +468,7 @@ static int do_proc_douintvec_conv(unsigned long *lvalp,
 
 static const char proc_wspace_sep[] = { ' ', '\t', '\n' };
 
-static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
+static int __do_proc_dointvec(void *tbl_data, const struct ctl_table *table,
 		  int write, void *buffer,
 		  size_t *lenp, loff_t *ppos,
 		  int (*conv)(bool *negp, unsigned long *lvalp, int *valp,
@@ -541,7 +541,7 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
 	return err;
 }
 
-static int do_proc_dointvec(struct ctl_table *table, int write,
+static int do_proc_dointvec(const struct ctl_table *table, int write,
 		  void *buffer, size_t *lenp, loff_t *ppos,
 		  int (*conv)(bool *negp, unsigned long *lvalp, int *valp,
 			      int write, void *data),
@@ -739,7 +739,7 @@ int proc_dobool(const struct ctl_table *table, int write, void *buffer,
  *
  * Returns 0 on success.
  */
-int proc_dointvec(struct ctl_table *table, int write, void *buffer,
+int proc_dointvec(const struct ctl_table *table, int write, void *buffer,
 		  size_t *lenp, loff_t *ppos)
 {
 	return do_proc_dointvec(table, write, buffer, lenp, ppos, NULL, NULL);
@@ -1510,7 +1510,7 @@ int proc_dobool(const struct ctl_table *table, int write,
 	return -ENOSYS;
 }
 
-int proc_dointvec(struct ctl_table *table, int write,
+int proc_dointvec(const struct ctl_table *table, int write,
 		  void *buffer, size_t *lenp, loff_t *ppos)
 {
 	return -ENOSYS;
@@ -1621,7 +1621,7 @@ static struct ctl_table kern_table[] = {
 		.data		= &panic_timeout,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #ifdef CONFIG_PROC_SYSCTL
 	{
@@ -1645,7 +1645,7 @@ static struct ctl_table kern_table[] = {
 		.data		= &print_fatal_signals,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #ifdef CONFIG_SPARC
 	{
@@ -1660,14 +1660,14 @@ static struct ctl_table kern_table[] = {
 		.data		= &stop_a_enabled,
 		.maxlen		= sizeof (int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "scons-poweroff",
 		.data		= &scons_pwroff,
 		.maxlen		= sizeof (int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #endif
 #ifdef CONFIG_SPARC64
@@ -1676,7 +1676,7 @@ static struct ctl_table kern_table[] = {
 		.data		= &sysctl_tsb_ratio,
 		.maxlen		= sizeof (int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #endif
 #ifdef CONFIG_PARISC
@@ -1685,7 +1685,7 @@ static struct ctl_table kern_table[] = {
 		.data		= &pwrsw_enabled,
 		.maxlen		= sizeof (int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #endif
 #ifdef CONFIG_SYSCTL_ARCH_UNALIGN_ALLOW
@@ -1694,7 +1694,7 @@ static struct ctl_table kern_table[] = {
 		.data		= &unaligned_enabled,
 		.maxlen		= sizeof (int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #endif
 #ifdef CONFIG_STACK_TRACER
@@ -1712,14 +1712,14 @@ static struct ctl_table kern_table[] = {
 		.data		= &ftrace_dump_on_oops,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "traceoff_on_warning",
 		.data		= &__disable_trace_on_warning,
 		.maxlen		= sizeof(__disable_trace_on_warning),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "tracepoint_printk",
@@ -1806,7 +1806,7 @@ static struct ctl_table kern_table[] = {
 		.data		= &show_unhandled_signals,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #endif
 	{
@@ -1823,7 +1823,7 @@ static struct ctl_table kern_table[] = {
 		.data		= &panic_on_oops,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "panic_print",
@@ -1837,14 +1837,14 @@ static struct ctl_table kern_table[] = {
 		.data		= (void *)&ngroups_max,
 		.maxlen		= sizeof (int),
 		.mode		= 0444,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "cap_last_cap",
 		.data		= (void *)&cap_last_cap,
 		.maxlen		= sizeof(int),
 		.mode		= 0444,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86)
 	{
@@ -1852,7 +1852,7 @@ static struct ctl_table kern_table[] = {
 		.data           = &unknown_nmi_panic,
 		.maxlen         = sizeof (int),
 		.mode           = 0644,
-		.proc_handler   = proc_dointvec,
+		.proc_handler_new   = proc_dointvec,
 	},
 #endif
 
@@ -1863,7 +1863,7 @@ static struct ctl_table kern_table[] = {
 		.data		= &sysctl_panic_on_stackoverflow,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #endif
 #if defined(CONFIG_X86)
@@ -1872,35 +1872,35 @@ static struct ctl_table kern_table[] = {
 		.data		= &panic_on_unrecovered_nmi,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "panic_on_io_nmi",
 		.data		= &panic_on_io_nmi,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "bootloader_type",
 		.data		= &bootloader_type,
 		.maxlen		= sizeof (int),
 		.mode		= 0444,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "bootloader_version",
 		.data		= &bootloader_version,
 		.maxlen		= sizeof (int),
 		.mode		= 0444,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "io_delay_type",
 		.data		= &io_delay_type,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #endif
 #if defined(CONFIG_MMU)
@@ -1909,7 +1909,7 @@ static struct ctl_table kern_table[] = {
 		.data		= &randomize_va_space,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #endif
 #if defined(CONFIG_S390) && defined(CONFIG_SMP)
@@ -1918,7 +1918,7 @@ static struct ctl_table kern_table[] = {
 		.data		= &spin_retry,
 		.maxlen		= sizeof (int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #endif
 #if	defined(CONFIG_ACPI_SLEEP) && defined(CONFIG_X86)
@@ -1936,7 +1936,7 @@ static struct ctl_table kern_table[] = {
 		.data		= &no_unaligned_warning,
 		.maxlen		= sizeof (int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #endif
 #ifdef CONFIG_RT_MUTEXES
@@ -1945,7 +1945,7 @@ static struct ctl_table kern_table[] = {
 		.data		= &max_lock_depth,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #endif
 #ifdef CONFIG_PERF_EVENTS
@@ -1960,14 +1960,14 @@ static struct ctl_table kern_table[] = {
 		.data		= &sysctl_perf_event_paranoid,
 		.maxlen		= sizeof(sysctl_perf_event_paranoid),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "perf_event_mlock_kb",
 		.data		= &sysctl_perf_event_mlock,
 		.maxlen		= sizeof(sysctl_perf_event_mlock),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "perf_event_max_sample_rate",
@@ -2200,7 +2200,7 @@ static struct ctl_table vm_table[] = {
 		.maxlen		= sizeof(vdso_enabled),
 #endif
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 		.extra1		= SYSCTL_ZERO,
 	},
 #endif
diff --git a/lib/test_sysctl.c b/lib/test_sysctl.c
index de42e3d99912..cb8475f3b23e 100644
--- a/lib/test_sysctl.c
+++ b/lib/test_sysctl.c
@@ -84,28 +84,28 @@ static struct ctl_table test_table[] = {
 		.data		= &test_data.int_0002,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "int_0003",
 		.data		= &test_data.int_0003,
 		.maxlen		= sizeof(test_data.int_0003),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "match_int",
 		.data		= &match_int_ok,
 		.maxlen		= sizeof(match_int_ok),
 		.mode		= 0444,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "boot_int",
 		.data		= &test_data.boot_int,
 		.maxlen		= sizeof(test_data.boot_int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 		.extra1		= SYSCTL_ZERO,
 		.extra2         = SYSCTL_ONE,
 	},
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 1169ef2f2176..338a7afe28ee 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -4942,7 +4942,7 @@ static struct ctl_table hugetlb_table[] = {
 		.data		= &sysctl_hugetlb_shm_group,
 		.maxlen		= sizeof(gid_t),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "nr_overcommit_hugepages",
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 9e6071fde34a..9cb0d478df81 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -713,14 +713,14 @@ static struct ctl_table vm_oom_kill_table[] = {
 		.data		= &sysctl_oom_kill_allocating_task,
 		.maxlen		= sizeof(sysctl_oom_kill_allocating_task),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "oom_dump_tasks",
 		.data		= &sysctl_oom_dump_tasks,
 		.maxlen		= sizeof(sysctl_oom_dump_tasks),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{}
 };
diff --git a/net/appletalk/sysctl_net_atalk.c b/net/appletalk/sysctl_net_atalk.c
index d945b7c0176d..9a18254f8875 100644
--- a/net/appletalk/sysctl_net_atalk.c
+++ b/net/appletalk/sysctl_net_atalk.c
@@ -31,7 +31,7 @@ static struct ctl_table atalk_table[] = {
 		.data		= &sysctl_aarp_retransmit_limit,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "aarp-resolve-time",
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
index 03f1edb948d7..c596de00e553 100644
--- a/net/core/sysctl_net_core.c
+++ b/net/core/sysctl_net_core.c
@@ -433,7 +433,7 @@ static struct ctl_table net_core_table[] = {
 		.data		= &netdev_max_backlog,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "netdev_rss_key",
@@ -492,7 +492,7 @@ static struct ctl_table net_core_table[] = {
 		.data		= &netdev_tstamp_prequeue,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "message_cost",
@@ -506,14 +506,14 @@ static struct ctl_table net_core_table[] = {
 		.data		= &net_ratelimit_state.burst,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "optmem_max",
 		.data		= &sysctl_optmem_max,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "tstamp_allow_data",
@@ -577,14 +577,14 @@ static struct ctl_table net_core_table[] = {
 		.data		= &netdev_budget,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "warnings",
 		.data		= &net_msg_warn,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "max_skb_frags",
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 16615d107cf0..51958c4a3eef 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -3428,14 +3428,14 @@ static struct ctl_table ipv4_route_table[] = {
 		.data		= &ipv4_dst_ops.gc_thresh,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "max_size",
 		.data		= &ip_rt_max_size,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		/*  Deprecated. Use gc_min_interval_ms */
@@ -3472,42 +3472,42 @@ static struct ctl_table ipv4_route_table[] = {
 		.data		= &ip_rt_redirect_load,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "redirect_number",
 		.data		= &ip_rt_redirect_number,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "redirect_silence",
 		.data		= &ip_rt_redirect_silence,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "error_cost",
 		.data		= &ip_rt_error_cost,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "error_burst",
 		.data		= &ip_rt_error_burst,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "gc_elasticity",
 		.data		= &ip_rt_gc_elasticity,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{ }
 };
@@ -3541,7 +3541,7 @@ static struct ctl_table ipv4_route_netns_table[] = {
 		.data       = &init_net.ipv4.ip_rt_min_advmss,
 		.maxlen     = sizeof(int),
 		.mode       = 0644,
-		.proc_handler   = proc_dointvec,
+		.proc_handler_new   = proc_dointvec,
 	},
 	{ },
 };
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index f63a545a7374..726494d5a6d7 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -474,14 +474,14 @@ static struct ctl_table ipv4_table[] = {
 		.data		= &sysctl_tcp_max_orphans,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "inet_peer_threshold",
 		.data		= &inet_peer_threshold,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "inet_peer_minttl",
@@ -509,7 +509,7 @@ static struct ctl_table ipv4_table[] = {
 		.data		= &sysctl_tcp_low_latency,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 #ifdef CONFIG_NETLABEL
 	{
@@ -517,28 +517,28 @@ static struct ctl_table ipv4_table[] = {
 		.data		= &cipso_v4_cache_enabled,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "cipso_cache_bucket_size",
 		.data		= &cipso_v4_cache_bucketsize,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "cipso_rbm_optfmt",
 		.data		= &cipso_v4_rbm_optfmt,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "cipso_rbm_strictvalid",
 		.data		= &cipso_v4_rbm_strictvalid,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #endif /* CONFIG_NETLABEL */
 	{
@@ -588,7 +588,7 @@ static struct ctl_table ipv4_net_table[] = {
 		.data		= &init_net.ipv4.tcp_death_row.sysctl_max_tw_buckets,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "icmp_echo_ignore_all",
@@ -647,7 +647,7 @@ static struct ctl_table ipv4_net_table[] = {
 		.data		= &init_net.ipv4.sysctl_icmp_ratemask,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "ping_group_range",
@@ -821,7 +821,7 @@ static struct ctl_table ipv4_net_table[] = {
 		.data		= &init_net.ipv4.sysctl_tcp_base_mss,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "tcp_min_snd_mss",
@@ -846,7 +846,7 @@ static struct ctl_table ipv4_net_table[] = {
 		.data		= &init_net.ipv4.sysctl_tcp_probe_threshold,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "tcp_probe_interval",
@@ -868,14 +868,14 @@ static struct ctl_table ipv4_net_table[] = {
 		.data		= &init_net.ipv4.sysctl_igmp_max_memberships,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "igmp_max_msf",
 		.data		= &init_net.ipv4.sysctl_igmp_max_msf,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 #ifdef CONFIG_IP_MULTICAST
 	{
@@ -966,7 +966,7 @@ static struct ctl_table ipv4_net_table[] = {
 		.data		= &init_net.ipv4.sysctl_tcp_reordering,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "tcp_retries1",
@@ -1018,14 +1018,14 @@ static struct ctl_table ipv4_net_table[] = {
 		.data		= &init_net.ipv4.sysctl_max_syn_backlog,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "tcp_fastopen",
 		.data		= &init_net.ipv4.sysctl_tcp_fastopen,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "tcp_fastopen_key",
@@ -1185,7 +1185,7 @@ static struct ctl_table ipv4_net_table[] = {
 		.data		= &init_net.ipv4.sysctl_tcp_max_reordering,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "tcp_dsack",
@@ -1261,14 +1261,14 @@ static struct ctl_table ipv4_net_table[] = {
 		.data		= &init_net.ipv4.sysctl_tcp_limit_output_bytes,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "tcp_challenge_ack_limit",
 		.data		= &init_net.ipv4.sysctl_tcp_challenge_ack_limit,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "tcp_min_tso_segs",
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index c33bca2c3841..166528c3d768 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -150,7 +150,7 @@ static struct ctl_table xfrm4_policy_table[] = {
 		.data           = &init_net.xfrm.xfrm4_dst_ops.gc_thresh,
 		.maxlen         = sizeof(int),
 		.mode           = 0644,
-		.proc_handler   = proc_dointvec,
+		.proc_handler_new   = proc_dointvec,
 	},
 	{ }
 };
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 3aaea56b5166..b18facff1d31 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -6705,28 +6705,28 @@ static const struct ctl_table addrconf_sysctl[] = {
 		.data		= &ipv6_devconf.accept_ra,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "accept_redirects",
 		.data		= &ipv6_devconf.accept_redirects,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "autoconf",
 		.data		= &ipv6_devconf.autoconf,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "dad_transmits",
 		.data		= &ipv6_devconf.dad_transmits,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "router_solicitations",
@@ -6762,7 +6762,7 @@ static const struct ctl_table addrconf_sysctl[] = {
 		.data		= &ipv6_devconf.force_mld_version,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "mldv1_unsolicited_report_interval",
@@ -6785,49 +6785,49 @@ static const struct ctl_table addrconf_sysctl[] = {
 		.data		= &ipv6_devconf.use_tempaddr,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "temp_valid_lft",
 		.data		= &ipv6_devconf.temp_valid_lft,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "temp_prefered_lft",
 		.data		= &ipv6_devconf.temp_prefered_lft,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "regen_max_retry",
 		.data		= &ipv6_devconf.regen_max_retry,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "max_desync_factor",
 		.data		= &ipv6_devconf.max_desync_factor,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "max_addresses",
 		.data		= &ipv6_devconf.max_addresses,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "accept_ra_defrtr",
 		.data		= &ipv6_devconf.accept_ra_defrtr,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "ra_defrtr_metric",
@@ -6842,21 +6842,21 @@ static const struct ctl_table addrconf_sysctl[] = {
 		.data		= &ipv6_devconf.accept_ra_min_hop_limit,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "accept_ra_min_lft",
 		.data		= &ipv6_devconf.accept_ra_min_lft,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "accept_ra_pinfo",
 		.data		= &ipv6_devconf.accept_ra_pinfo,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "ra_honor_pio_life",
@@ -6873,7 +6873,7 @@ static const struct ctl_table addrconf_sysctl[] = {
 		.data		= &ipv6_devconf.accept_ra_rtr_pref,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "router_probe_interval",
@@ -6888,14 +6888,14 @@ static const struct ctl_table addrconf_sysctl[] = {
 		.data		= &ipv6_devconf.accept_ra_rt_info_min_plen,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "accept_ra_rt_info_max_plen",
 		.data		= &ipv6_devconf.accept_ra_rt_info_max_plen,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #endif
 #endif
@@ -6911,7 +6911,7 @@ static const struct ctl_table addrconf_sysctl[] = {
 		.data		= &ipv6_devconf.accept_source_route,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #ifdef CONFIG_IPV6_OPTIMISTIC_DAD
 	{
@@ -6919,14 +6919,14 @@ static const struct ctl_table addrconf_sysctl[] = {
 		.data		= &ipv6_devconf.optimistic_dad,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler   = proc_dointvec,
+		.proc_handler_new   = proc_dointvec,
 	},
 	{
 		.procname	= "use_optimistic",
 		.data		= &ipv6_devconf.use_optimistic,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #endif
 #ifdef CONFIG_IPV6_MROUTE
@@ -6935,7 +6935,7 @@ static const struct ctl_table addrconf_sysctl[] = {
 		.data		= &ipv6_devconf.mc_forwarding,
 		.maxlen		= sizeof(int),
 		.mode		= 0444,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #endif
 	{
@@ -6950,42 +6950,42 @@ static const struct ctl_table addrconf_sysctl[] = {
 		.data		= &ipv6_devconf.accept_dad,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "force_tllao",
 		.data		= &ipv6_devconf.force_tllao,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "ndisc_notify",
 		.data		= &ipv6_devconf.ndisc_notify,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "suppress_frag_ndisc",
 		.data		= &ipv6_devconf.suppress_frag_ndisc,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "accept_ra_from_local",
 		.data		= &ipv6_devconf.accept_ra_from_local,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "accept_ra_mtu",
 		.data		= &ipv6_devconf.accept_ra_mtu,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "stable_secret",
@@ -6999,7 +6999,7 @@ static const struct ctl_table addrconf_sysctl[] = {
 		.data		= &ipv6_devconf.use_oif_addrs_only,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "ignore_routes_with_linkdown",
@@ -7013,21 +7013,21 @@ static const struct ctl_table addrconf_sysctl[] = {
 		.data		= &ipv6_devconf.drop_unicast_in_l2_multicast,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "drop_unsolicited_na",
 		.data		= &ipv6_devconf.drop_unsolicited_na,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "keep_addr_on_down",
 		.data		= &ipv6_devconf.keep_addr_on_down,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 
 	},
 	{
@@ -7035,7 +7035,7 @@ static const struct ctl_table addrconf_sysctl[] = {
 		.data		= &ipv6_devconf.seg6_enabled,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #ifdef CONFIG_IPV6_SEG6_HMAC
 	{
@@ -7043,7 +7043,7 @@ static const struct ctl_table addrconf_sysctl[] = {
 		.data		= &ipv6_devconf.seg6_require_hmac,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #endif
 	{
@@ -7051,7 +7051,7 @@ static const struct ctl_table addrconf_sysctl[] = {
 		.data           = &ipv6_devconf.enhanced_dad,
 		.maxlen         = sizeof(int),
 		.mode           = 0644,
-		.proc_handler   = proc_dointvec,
+		.proc_handler_new   = proc_dointvec,
 	},
 	{
 		.procname	= "addr_gen_mode",
@@ -7081,7 +7081,7 @@ static const struct ctl_table addrconf_sysctl[] = {
 		.data		= &ipv6_devconf.rpl_seg_enabled,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "ioam6_enabled",
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index b132feae3393..62313c74d2fe 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -6350,14 +6350,14 @@ static struct ctl_table ipv6_route_table_template[] = {
 		.data		=	&init_net.ipv6.sysctl.ip6_rt_max_size,
 		.maxlen		=	sizeof(int),
 		.mode		=	0644,
-		.proc_handler	=	proc_dointvec,
+		.proc_handler_new	=	proc_dointvec,
 	},
 	{
 		.procname	=	"gc_thresh",
 		.data		=	&ip6_dst_ops_template.gc_thresh,
 		.maxlen		=	sizeof(int),
 		.mode		=	0644,
-		.proc_handler	=	proc_dointvec,
+		.proc_handler_new	=	proc_dointvec,
 	},
 	{
 		.procname	=	"flush",
@@ -6392,7 +6392,7 @@ static struct ctl_table ipv6_route_table_template[] = {
 		.data		=	&init_net.ipv6.sysctl.ip6_rt_gc_elasticity,
 		.maxlen		=	sizeof(int),
 		.mode		=	0644,
-		.proc_handler	=	proc_dointvec,
+		.proc_handler_new	=	proc_dointvec,
 	},
 	{
 		.procname	=	"mtu_expires",
@@ -6406,7 +6406,7 @@ static struct ctl_table ipv6_route_table_template[] = {
 		.data		=	&init_net.ipv6.sysctl.ip6_rt_min_advmss,
 		.maxlen		=	sizeof(int),
 		.mode		=	0644,
-		.proc_handler	=	proc_dointvec,
+		.proc_handler_new	=	proc_dointvec,
 	},
 	{
 		.procname	=	"gc_min_interval_ms",
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
index 888676163e90..f3ecdd13fdb4 100644
--- a/net/ipv6/sysctl_net_ipv6.c
+++ b/net/ipv6/sysctl_net_ipv6.c
@@ -103,7 +103,7 @@ static struct ctl_table ipv6_table_template[] = {
 		.data		= &init_net.ipv6.sysctl.idgen_retries,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "idgen_delay",
@@ -140,28 +140,28 @@ static struct ctl_table ipv6_table_template[] = {
 		.data		= &init_net.ipv6.sysctl.max_dst_opts_cnt,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "max_hbh_opts_number",
 		.data		= &init_net.ipv6.sysctl.max_hbh_opts_cnt,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "max_dst_opts_length",
 		.data		= &init_net.ipv6.sysctl.max_dst_opts_len,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "max_hbh_length",
 		.data		= &init_net.ipv6.sysctl.max_hbh_opts_len,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "fib_multipath_hash_policy",
@@ -186,7 +186,7 @@ static struct ctl_table ipv6_table_template[] = {
 		.data		= &init_net.ipv6.sysctl.seg6_flowlabel,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "fib_notify_on_flag_change",
@@ -222,7 +222,7 @@ static struct ctl_table ipv6_rotable[] = {
 		.data		= &sysctl_mld_max_msf,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "mld_qrv",
@@ -238,14 +238,14 @@ static struct ctl_table ipv6_rotable[] = {
 		.data		= &calipso_cache_enabled,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "calipso_cache_bucket_size",
 		.data		= &calipso_cache_bucketsize,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #endif /* CONFIG_NETLABEL */
 	{ }
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 42fb6996b077..3d29a12b5fc1 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -182,7 +182,7 @@ static struct ctl_table xfrm6_policy_table[] = {
 		.data		= &init_net.xfrm.xfrm6_dst_ops.gc_thresh,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler   = proc_dointvec,
+		.proc_handler_new   = proc_dointvec,
 	},
 	{ }
 };
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 143a341bbc0a..b832d55c7d0c 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -2077,13 +2077,13 @@ static struct ctl_table vs_vars[] = {
 		.procname	= "amemthresh",
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "am_droprate",
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "drop_entry",
@@ -2102,7 +2102,7 @@ static struct ctl_table vs_vars[] = {
 		.procname	= "conntrack",
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec,
+		.proc_handler_new	= &proc_dointvec,
 	},
 #endif
 	{
@@ -2115,7 +2115,7 @@ static struct ctl_table vs_vars[] = {
 		.procname	= "snat_reroute",
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec,
+		.proc_handler_new	= &proc_dointvec,
 	},
 	{
 		.procname	= "sync_version",
@@ -2135,7 +2135,7 @@ static struct ctl_table vs_vars[] = {
 		.procname	= "sync_persist_mode",
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "sync_qlen_max",
@@ -2147,37 +2147,37 @@ static struct ctl_table vs_vars[] = {
 		.procname	= "sync_sock_size",
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "cache_bypass",
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "expire_nodest_conn",
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "sloppy_tcp",
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "sloppy_sctp",
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "expire_quiescent_template",
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "sync_threshold",
@@ -2204,37 +2204,37 @@ static struct ctl_table vs_vars[] = {
 		.procname	= "nat_icmp_send",
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "pmtu_disc",
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "backup_only",
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "conn_reuse_mode",
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "schedule_icmp",
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "ignore_tunneled",
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "run_estimation",
@@ -2260,7 +2260,7 @@ static struct ctl_table vs_vars[] = {
 		.data		= &sysctl_ip_vs_debug_level,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 #endif
 	{ }
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 0ee98ce5b816..d6779acd2693 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -627,13 +627,13 @@ static struct ctl_table nf_ct_sysctl_table[] = {
 		.data		= &nf_conntrack_max,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	[NF_SYSCTL_CT_COUNT] = {
 		.procname	= "nf_conntrack_count",
 		.maxlen		= sizeof(int),
 		.mode		= 0444,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	[NF_SYSCTL_CT_BUCKETS] = {
 		.procname       = "nf_conntrack_buckets",
@@ -663,7 +663,7 @@ static struct ctl_table nf_ct_sysctl_table[] = {
 		.data		= &nf_ct_expect_max,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	[NF_SYSCTL_CT_ACCT] = {
 		.procname	= "nf_conntrack_acct",
@@ -966,7 +966,7 @@ static struct ctl_table nf_ct_netfilter_table[] = {
 		.data		= &nf_conntrack_max,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{ }
 };
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
index 8cc52d2bd31b..5c296f91a74d 100644
--- a/net/netfilter/nf_log.c
+++ b/net/netfilter/nf_log.c
@@ -398,7 +398,7 @@ static struct ctl_table nf_log_sysctl_ftable[] = {
 		.data		= &sysctl_nf_log_all_netns,
 		.maxlen		= sizeof(sysctl_nf_log_all_netns),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{ }
 };
diff --git a/net/rds/ib_sysctl.c b/net/rds/ib_sysctl.c
index e4e41b3afce7..e90a5ecabc7c 100644
--- a/net/rds/ib_sysctl.c
+++ b/net/rds/ib_sysctl.c
@@ -101,7 +101,7 @@ static struct ctl_table rds_ib_sysctl_table[] = {
 		.data		= &rds_ib_sysctl_flow_control,
 		.maxlen		= sizeof(rds_ib_sysctl_flow_control),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{ }
 };
diff --git a/net/rds/sysctl.c b/net/rds/sysctl.c
index e381bbcd9cc1..958b0465fed3 100644
--- a/net/rds/sysctl.c
+++ b/net/rds/sysctl.c
@@ -73,21 +73,21 @@ static struct ctl_table rds_sysctl_rds_table[] = {
 		.data		= &rds_sysctl_max_unacked_packets,
 		.maxlen         = sizeof(int),
 		.mode           = 0644,
-		.proc_handler   = proc_dointvec,
+		.proc_handler_new   = proc_dointvec,
 	},
 	{
 		.procname	= "max_unacked_bytes",
 		.data		= &rds_sysctl_max_unacked_bytes,
 		.maxlen         = sizeof(int),
 		.mode           = 0644,
-		.proc_handler   = proc_dointvec,
+		.proc_handler_new   = proc_dointvec,
 	},
 	{
 		.procname	= "ping_enable",
 		.data		= &rds_sysctl_ping_enable,
 		.maxlen         = sizeof(int),
 		.mode           = 0644,
-		.proc_handler   = proc_dointvec,
+		.proc_handler_new   = proc_dointvec,
 	},
 	{ }
 };
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index f65d6f92afcb..b94ef7a34bce 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -71,14 +71,14 @@ static struct ctl_table sctp_table[] = {
 		.data		= &sysctl_sctp_rmem,
 		.maxlen		= sizeof(sysctl_sctp_rmem),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "sctp_wmem",
 		.data		= &sysctl_sctp_wmem,
 		.maxlen		= sizeof(sysctl_sctp_wmem),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 
 	{ /* sentinel */ }
@@ -172,7 +172,7 @@ static struct ctl_table sctp_net_table[] = {
 		.data		= &init_net.sctp.cookie_preserve_enable,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "cookie_hmac_alg",
@@ -240,49 +240,49 @@ static struct ctl_table sctp_net_table[] = {
 		.data		= &init_net.sctp.sndbuf_policy,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "rcvbuf_policy",
 		.data		= &init_net.sctp.rcvbuf_policy,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "default_auto_asconf",
 		.data		= &init_net.sctp.default_auto_asconf,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "addip_enable",
 		.data		= &init_net.sctp.addip_enable,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "addip_noauth_enable",
 		.data		= &init_net.sctp.addip_noauth,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "prsctp_enable",
 		.data		= &init_net.sctp.prsctp_enable,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "reconf_enable",
 		.data		= &init_net.sctp.reconf_enable,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "auth_enable",
@@ -296,14 +296,14 @@ static struct ctl_table sctp_net_table[] = {
 		.data		= &init_net.sctp.intl_enable,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "ecn_enable",
 		.data		= &init_net.sctp.ecn_enable,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "plpmtud_probe_interval",
@@ -373,7 +373,7 @@ static struct ctl_table sctp_net_table[] = {
 		.data		= &init_net.sctp.pf_enable,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{
 		.procname	= "pf_expose",
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
index 29b0562d62e7..db7a9b2aa8ba 100644
--- a/net/sunrpc/xprtrdma/transport.c
+++ b/net/sunrpc/xprtrdma/transport.c
@@ -135,7 +135,7 @@ static struct ctl_table xr_tunables_table[] = {
 		.data		= &xprt_rdma_pad_optimize,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec,
+		.proc_handler_new	= proc_dointvec,
 	},
 	{ },
 };
diff --git a/net/unix/sysctl_net_unix.c b/net/unix/sysctl_net_unix.c
index 3e84b31c355a..4ddc9d9d2d30 100644
--- a/net/unix/sysctl_net_unix.c
+++ b/net/unix/sysctl_net_unix.c
@@ -17,7 +17,7 @@ static struct ctl_table unix_table[] = {
 		.data		= &init_net.unx.sysctl_max_dgram_qlen,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{ }
 };
diff --git a/net/x25/sysctl_net_x25.c b/net/x25/sysctl_net_x25.c
index e9802afa43d0..97a44b455221 100644
--- a/net/x25/sysctl_net_x25.c
+++ b/net/x25/sysctl_net_x25.c
@@ -69,7 +69,7 @@ static struct ctl_table x25_table[] = {
 		.data = 	&sysctl_x25_forward,
 		.maxlen = 	sizeof(int),
 		.mode = 	0644,
-		.proc_handler = proc_dointvec,
+		.proc_handler_new = proc_dointvec,
 	},
 	{ },
 };
diff --git a/net/xfrm/xfrm_sysctl.c b/net/xfrm/xfrm_sysctl.c
index 7fdeafc838a7..3190fb65e13d 100644
--- a/net/xfrm/xfrm_sysctl.c
+++ b/net/xfrm/xfrm_sysctl.c
@@ -30,13 +30,13 @@ static struct ctl_table xfrm_table[] = {
 		.procname	= "xfrm_larval_drop",
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{
 		.procname	= "xfrm_acq_expires",
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.proc_handler_new	= proc_dointvec
 	},
 	{}
 };

-- 
2.43.0


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

* Re: [PATCH RFC 0/7] sysctl: constify sysctl ctl_tables
  2023-11-25 12:52 ` [PATCH RFC 0/7] sysctl: constify sysctl ctl_tables Thomas Weißschuh
                     ` (6 preceding siblings ...)
  2023-11-25 12:52   ` [PATCH RFC 7/7] treewide: sysctl: migrate proc_dointvec " Thomas Weißschuh
@ 2023-11-27 10:13   ` Joel Granados
  2023-11-28  8:18     ` Thomas Weißschuh
  7 siblings, 1 reply; 13+ messages in thread
From: Joel Granados @ 2023-11-27 10:13 UTC (permalink / raw)
  To: Thomas Weißschuh
  Cc: Kees Cook, Gustavo A. R. Silva, Luis Chamberlain, Iurii Zaikin,
	Greg Kroah-Hartman, linux-hardening, linux-kernel, linux-fsdevel

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

Hey Thomas

In general I would like to see more clarity with the motivation and I
would also expect some system testing. My comments inline:

On Sat, Nov 25, 2023 at 01:52:49PM +0100, Thomas Weißschuh wrote:
> Problem description:
> 
> The kernel contains a lot of struct ctl_table throught the tree.
> These are very often 'static' definitions.
> It would be good to mark these tables const to avoid accidental or
> malicious modifications.
It is unclear to me what you mean here with accidental or malicious
modifications. Do you have a specific attack vector in mind? Do you
have an example of how this could happen maliciously? With
accidental, do you mean in proc/sysctl.c? Can you expand more on the
accidental part?

What happens with the code that modifies these outside the sysctl core?
Like for example in sysctl_route_net_init where the table is modified
depending on the net->user_ns? Would these non-const ctl_table pointers
be ok? would they be handled differently?

> Unfortunately the tables can not be made const because the core
> registration functions expect mutable tables.
> 
> This is for two reasons:
> 
> 1) sysctl_{set,clear}_perm_empty_ctl_header in the sysctl core modify
>    the table. This should be fixable by only modifying the header
>    instead of the table itself.
> 2) The table is passed to the handler function as a non-const pointer.
> 
> This series is an aproach on fixing reason 2).
So number 2 will be sent in another set?

> 
> Full process:
> 
> * Introduce field proc_handler_new for const handlers (this series)
> * Migrate all core handlers to proc_handler_new (this series, partial)
>   This can hopefully be done in a big switch, as it only involves
>   functions and structures owned by the core sysctl code.
> * Migrate all other sysctl handlers to proc_handler_new.
> * Drop the old proc_handler_field.
> * Fix the sysctl core to not modify the tables anymore.
> * Adapt public sysctl APIs to take "const struct ctl_table *".
> * Teach checkpatch.pl to warn on non-const "struct ctl_table"
>   definitions.
> * Migrate definitions of "struct ctl_table" to "const" where applicable.
>  
> 
> Notes:
> 
> Just casting the function pointers around would trigger
> CFI (control flow integrity) warnings.
> 
> The name of the new handler "proc_handler_new" is a bit too long messing
> up the alignment of the table definitions.
> Maybe "proc_handler2" or "proc_handler_c" for (const) would be better.
indeed the name does not say much. "_new" looses its meaning quite fast
:)

In my experience these tree wide modifications are quite tricky. Have you
run any tests to see that everything is as it was? sysctl selftests and
0-day come to mind.

Best
> 
> ---
> Thomas Weißschuh (7):
>       sysctl: add helper sysctl_run_handler
>       bpf: cgroup: call proc handler through helper
>       sysctl: add proc_handler_new to struct ctl_table
>       net: sysctl: add new sysctl table handler to debug message
>       treewide: sysctl: migrate proc_dostring to proc_handler_new
>       treewide: sysctl: migrate proc_dobool to proc_handler_new
>       treewide: sysctl: migrate proc_dointvec to proc_handler_new
> 
>  arch/arm/kernel/isa.c                   |  6 +--
>  arch/csky/abiv1/alignment.c             |  8 ++--
>  arch/powerpc/kernel/idle.c              |  2 +-
>  arch/riscv/kernel/vector.c              |  2 +-
>  arch/s390/kernel/debug.c                |  2 +-
>  crypto/fips.c                           |  6 +--
>  drivers/char/hpet.c                     |  2 +-
>  drivers/char/random.c                   |  4 +-
>  drivers/infiniband/core/iwcm.c          |  2 +-
>  drivers/infiniband/core/ucma.c          |  2 +-
>  drivers/macintosh/mac_hid.c             |  4 +-
>  drivers/md/md.c                         |  4 +-
>  drivers/scsi/sg.c                       |  2 +-
>  drivers/tty/tty_io.c                    |  4 +-
>  fs/coda/sysctl.c                        |  6 +--
>  fs/coredump.c                           |  6 +--
>  fs/devpts/inode.c                       |  2 +-
>  fs/lockd/svc.c                          |  4 +-
>  fs/locks.c                              |  4 +-
>  fs/nfs/nfs4sysctl.c                     |  2 +-
>  fs/nfs/sysctl.c                         |  2 +-
>  fs/notify/dnotify/dnotify.c             |  2 +-
>  fs/ntfs/sysctl.c                        |  2 +-
>  fs/ocfs2/stackglue.c                    |  2 +-
>  fs/proc/proc_sysctl.c                   | 16 ++++---
>  fs/quota/dquot.c                        |  2 +-
>  include/linux/sysctl.h                  | 29 +++++++++---
>  init/do_mounts_initrd.c                 |  2 +-
>  io_uring/io_uring.c                     |  2 +-
>  ipc/mq_sysctl.c                         |  2 +-
>  kernel/acct.c                           |  2 +-
>  kernel/bpf/cgroup.c                     |  2 +-
>  kernel/locking/lockdep.c                |  4 +-
>  kernel/printk/sysctl.c                  |  4 +-
>  kernel/reboot.c                         |  4 +-
>  kernel/seccomp.c                        |  2 +-
>  kernel/signal.c                         |  2 +-
>  kernel/sysctl-test.c                    | 20 ++++-----
>  kernel/sysctl.c                         | 80 ++++++++++++++++-----------------
>  lib/test_sysctl.c                       | 10 ++---
>  mm/hugetlb.c                            |  2 +-
>  mm/hugetlb_vmemmap.c                    |  2 +-
>  mm/oom_kill.c                           |  4 +-
>  net/appletalk/sysctl_net_atalk.c        |  2 +-
>  net/core/sysctl_net_core.c              | 12 ++---
>  net/ipv4/route.c                        | 18 ++++----
>  net/ipv4/sysctl_net_ipv4.c              | 38 ++++++++--------
>  net/ipv4/xfrm4_policy.c                 |  2 +-
>  net/ipv6/addrconf.c                     | 72 ++++++++++++++---------------
>  net/ipv6/route.c                        |  8 ++--
>  net/ipv6/sysctl_net_ipv6.c              | 18 ++++----
>  net/ipv6/xfrm6_policy.c                 |  2 +-
>  net/mptcp/ctrl.c                        |  2 +-
>  net/netfilter/ipvs/ip_vs_ctl.c          | 36 +++++++--------
>  net/netfilter/nf_conntrack_standalone.c |  8 ++--
>  net/netfilter/nf_log.c                  |  2 +-
>  net/rds/ib_sysctl.c                     |  2 +-
>  net/rds/sysctl.c                        |  6 +--
>  net/sctp/sysctl.c                       | 26 +++++------
>  net/sunrpc/xprtrdma/transport.c         |  2 +-
>  net/sysctl_net.c                        |  5 ++-
>  net/unix/sysctl_net_unix.c              |  2 +-
>  net/x25/sysctl_net_x25.c                |  2 +-
>  net/xfrm/xfrm_sysctl.c                  |  4 +-
>  64 files changed, 280 insertions(+), 262 deletions(-)
> ---
> base-commit: 0f5cc96c367f2e780eb492cc9cab84e3b2ca88da
> change-id: 20231116-const-sysctl-e14624f1295c
> 
> Best regards,
> -- 
> Thomas Weißschuh <linux@weissschuh.net>
> 

-- 

Joel Granados

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

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

* Re: [PATCH RFC 0/7] sysctl: constify sysctl ctl_tables
  2023-11-27 10:13   ` [PATCH RFC 0/7] sysctl: constify sysctl ctl_tables Joel Granados
@ 2023-11-28  8:18     ` Thomas Weißschuh
  2023-12-01 16:31       ` Joel Granados
  0 siblings, 1 reply; 13+ messages in thread
From: Thomas Weißschuh @ 2023-11-28  8:18 UTC (permalink / raw)
  To: Joel Granados
  Cc: Kees Cook, Gustavo A. R. Silva, Luis Chamberlain, Iurii Zaikin,
	Greg Kroah-Hartman, linux-hardening, linux-kernel, linux-fsdevel

Hi Joel,

On 2023-11-27 11:13:23+0100, Joel Granados wrote:
> In general I would like to see more clarity with the motivation and I
> would also expect some system testing. My comments inline:

Thanks for your feedback, response are below.

> On Sat, Nov 25, 2023 at 01:52:49PM +0100, Thomas Weißschuh wrote:
> > Problem description:
> > 
> > The kernel contains a lot of struct ctl_table throught the tree.
> > These are very often 'static' definitions.
> > It would be good to mark these tables const to avoid accidental or
> > malicious modifications.

> It is unclear to me what you mean here with accidental or malicious
> modifications. Do you have a specific attack vector in mind? Do you
> have an example of how this could happen maliciously? With
> accidental, do you mean in proc/sysctl.c? Can you expand more on the
> accidental part?

There is no specific attack vector I have in mind. The goal is to remove
mutable data, especially if it contains pointers, that could be used by
an attacker as a step in an exploit. See for example [0], [1].

Accidental can be any out-of-bounds write throughout the kernel.

> What happens with the code that modifies these outside the sysctl core?
> Like for example in sysctl_route_net_init where the table is modified
> depending on the net->user_ns? Would these non-const ctl_table pointers
> be ok? would they be handled differently?

It is still completely fine to modify the tables before registering,
like sysctl_route_net_init is doing. That code should not need any
changes.

Modifying the table inside the handler function would bypass the
validation done when registering so sounds like a bad idea in general.
It would still be possible however for a subsystem to do so by just not
making their sysctl table const and then modifying the table directly.
 
> > Unfortunately the tables can not be made const because the core
> > registration functions expect mutable tables.
> > 
> > This is for two reasons:
> > 
> > 1) sysctl_{set,clear}_perm_empty_ctl_header in the sysctl core modify
> >    the table. This should be fixable by only modifying the header
> >    instead of the table itself.
> > 2) The table is passed to the handler function as a non-const pointer.
> > 
> > This series is an aproach on fixing reason 2).

> So number 2 will be sent in another set?

If the initial feedback to the RFC and general process is positive, yes.

> > 
> > Full process:
> > 
> > * Introduce field proc_handler_new for const handlers (this series)
> > * Migrate all core handlers to proc_handler_new (this series, partial)
> >   This can hopefully be done in a big switch, as it only involves
> >   functions and structures owned by the core sysctl code.
> > * Migrate all other sysctl handlers to proc_handler_new.
> > * Drop the old proc_handler_field.
> > * Fix the sysctl core to not modify the tables anymore.
> > * Adapt public sysctl APIs to take "const struct ctl_table *".
> > * Teach checkpatch.pl to warn on non-const "struct ctl_table"
> >   definitions.
> > * Migrate definitions of "struct ctl_table" to "const" where applicable.
> >  
> > 
> > Notes:
> > 
> > Just casting the function pointers around would trigger
> > CFI (control flow integrity) warnings.
> > 
> > The name of the new handler "proc_handler_new" is a bit too long messing
> > up the alignment of the table definitions.
> > Maybe "proc_handler2" or "proc_handler_c" for (const) would be better.

> indeed the name does not say much. "_new" looses its meaning quite fast
> :)

Hopefully somebody comes up with a better name!

> In my experience these tree wide modifications are quite tricky. Have you
> run any tests to see that everything is as it was? sysctl selftests and
> 0-day come to mind.

I managed to miss one change in my initial submission:
With the hunk below selftests and typing emails work.

--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -1151,7 +1151,7 @@ static int sysctl_check_table(const char *path, struct ctl_table_header *header)
                        else
                                err |= sysctl_check_table_array(path, entry);
                }
-               if (!entry->proc_handler)
+               if (!entry->proc_handler && !entry->proc_handler_new)
                        err |= sysctl_err(path, entry, "No proc_handler");
 
                if ((entry->mode & (S_IRUGO|S_IWUGO)) != entry->mode)

> [..]

[0] 43a7206b0963 ("driver core: class: make class_register() take a const *")
[1] https://lore.kernel.org/lkml/20230930050033.41174-1-wedsonaf@gmail.com/


Thomas

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

* Re: [PATCH RFC 0/7] sysctl: constify sysctl ctl_tables
  2023-11-28  8:18     ` Thomas Weißschuh
@ 2023-12-01 16:31       ` Joel Granados
  2023-12-03 15:37         ` Thomas Weißschuh
  0 siblings, 1 reply; 13+ messages in thread
From: Joel Granados @ 2023-12-01 16:31 UTC (permalink / raw)
  To: Thomas Weißschuh
  Cc: Kees Cook, Gustavo A. R. Silva, Luis Chamberlain, Iurii Zaikin,
	Greg Kroah-Hartman, linux-hardening, linux-kernel, linux-fsdevel

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

Hey Thomas.

Thx for the clarifications. I did more of a deep dive into your set and
have additional comments (in line). I think const-ing all this is a good
approach. The way forward is to be able to see the entire patch set of
changes in a V1 or a shared repo somewhere to have a better picture of
what is going on. By the "entire patchset" I mean all the changes that
you described in the "full process".

On Tue, Nov 28, 2023 at 09:18:30AM +0100, Thomas Weißschuh wrote:
> Hi Joel,
> 
> On 2023-11-27 11:13:23+0100, Joel Granados wrote:
> > In general I would like to see more clarity with the motivation and I
> > would also expect some system testing. My comments inline:
> 
> Thanks for your feedback, response are below.
> 
> > On Sat, Nov 25, 2023 at 01:52:49PM +0100, Thomas Weißschuh wrote:
> > > Problem description:
> > > 
> > > The kernel contains a lot of struct ctl_table throught the tree.
> > > These are very often 'static' definitions.
> > > It would be good to mark these tables const to avoid accidental or
> > > malicious modifications.
> 
> > It is unclear to me what you mean here with accidental or malicious
> > modifications. Do you have a specific attack vector in mind? Do you
> > have an example of how this could happen maliciously? With
> > accidental, do you mean in proc/sysctl.c? Can you expand more on the
> > accidental part?
> 
> There is no specific attack vector I have in mind. The goal is to remove
> mutable data, especially if it contains pointers, that could be used by
> an attacker as a step in an exploit. See for example [0], [1].
I think you should work "remove mutable data" as part of you main
motivation when you send the non-RFC patch. I would also including [0]
and [1] (and any other previous work) to help contextualize.

> 
> Accidental can be any out-of-bounds write throughout the kernel.
> 
> > What happens with the code that modifies these outside the sysctl core?
> > Like for example in sysctl_route_net_init where the table is modified
> > depending on the net->user_ns? Would these non-const ctl_table pointers
> > be ok? would they be handled differently?
> 
> It is still completely fine to modify the tables before registering,
> like sysctl_route_net_init is doing. That code should not need any
> changes.
> 
> Modifying the table inside the handler function would bypass the
> validation done when registering so sounds like a bad idea in general.
This is done before registering. So the approach *is* sound.

> It would still be possible however for a subsystem to do so by just not
> making their sysctl table const and then modifying the table directly.
Indeed. Which might be intended or migth be someone that just forgets to
put const. I think you mentioned that there would be some sort of static
check for this (coccinelle or smach, or something else)? 

>  
> > > Unfortunately the tables can not be made const because the core
> > > registration functions expect mutable tables.
> > > 
> > > This is for two reasons:
> > > 
> > > 1) sysctl_{set,clear}_perm_empty_ctl_header in the sysctl core modify
> > >    the table. This should be fixable by only modifying the header
> > >    instead of the table itself.
> > > 2) The table is passed to the handler function as a non-const pointer.
> > > 
> > > This series is an aproach on fixing reason 2).
> 
> > So number 2 will be sent in another set?
Sorry, this was supposed to be "number 1", but you got my meaning :)

> 
> If the initial feedback to the RFC and general process is positive, yes.
Off the top of my head, putting  that type in the header instead of the
ctl_table seems ok. I would include it in non-RFC version together with
2.

> 
> > > 
> > > Full process:
> > > 
> > > * Introduce field proc_handler_new for const handlers (this series)
I don't understand why we need a new handler. Couldn't we just change
the existing handler to receive `const struct ctl_table` and change all
the `proc_do*` handlers?
I'm guessing its because you want to do this in steps? if that is the
case, it would be very helpfull to see (in some repo or V1) the steps
to change all the handlers in the non-RFC version 

> > > * Migrate all core handlers to proc_handler_new (this series, partial)
> > >   This can hopefully be done in a big switch, as it only involves
> > >   functions and structures owned by the core sysctl code.
It would be helpful to see what the "big switch" would look like. If it
is all sysctl code and cannot be chunked up because of dependencies,
then it should be ok to do it in one go.

> > > * Migrate all other sysctl handlers to proc_handler_new.
> > > * Drop the old proc_handler_field.
> > > * Fix the sysctl core to not modify the tables anymore.
> > > * Adapt public sysctl APIs to take "const struct ctl_table *".
> > > * Teach checkpatch.pl to warn on non-const "struct ctl_table"
> > >   definitions.
Have you considered how to ignore the cases where the ctl_tables are
supposed to be non-const when they are defined (like in the network
code that we were discussing earlier)

> > > * Migrate definitions of "struct ctl_table" to "const" where applicable.
These migrations are treewide and are usually reviewed by a wider
audience. You might need to chunk it up to make the review more palpable
for the other maintainers.

> > >  
> > > 
> > > Notes:
> > > 
> > > Just casting the function pointers around would trigger
> > > CFI (control flow integrity) warnings.
> > > 
> > > The name of the new handler "proc_handler_new" is a bit too long messing
> > > up the alignment of the table definitions.
> > > Maybe "proc_handler2" or "proc_handler_c" for (const) would be better.
> 
> > indeed the name does not say much. "_new" looses its meaning quite fast
> > :)
> 
> Hopefully somebody comes up with a better name!
I would like to avoid this all together and just do add the const to the
existing "proc_handler"

> 
> > In my experience these tree wide modifications are quite tricky. Have you
> > run any tests to see that everything is as it was? sysctl selftests and
> > 0-day come to mind.
> 
> I managed to miss one change in my initial submission:
> With the hunk below selftests and typing emails work.
> 
> --- a/fs/proc/proc_sysctl.c
> +++ b/fs/proc/proc_sysctl.c
> @@ -1151,7 +1151,7 @@ static int sysctl_check_table(const char *path, struct ctl_table_header *header)
>                         else
>                                 err |= sysctl_check_table_array(path, entry);
>                 }
> -               if (!entry->proc_handler)
> +               if (!entry->proc_handler && !entry->proc_handler_new)
>                         err |= sysctl_err(path, entry, "No proc_handler");
>  
>                 if ((entry->mode & (S_IRUGO|S_IWUGO)) != entry->mode)
> 
> > [..]
> 
> [0] 43a7206b0963 ("driver core: class: make class_register() take a const *")
> [1] https://lore.kernel.org/lkml/20230930050033.41174-1-wedsonaf@gmail.com/
> 
> 
> Thomas

-- 

Best
Joel Granados

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

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

* Re: [PATCH RFC 0/7] sysctl: constify sysctl ctl_tables
  2023-12-01 16:31       ` Joel Granados
@ 2023-12-03 15:37         ` Thomas Weißschuh
  2023-12-04  8:43           ` Joel Granados
  0 siblings, 1 reply; 13+ messages in thread
From: Thomas Weißschuh @ 2023-12-03 15:37 UTC (permalink / raw)
  To: Joel Granados
  Cc: Kees Cook, Gustavo A. R. Silva, Luis Chamberlain, Iurii Zaikin,
	Greg Kroah-Hartman, linux-hardening, linux-kernel, linux-fsdevel

Hi Joel,

On 2023-12-01 17:31:20+0100, Joel Granados wrote:
> Hey Thomas.
> 
> Thx for the clarifications. I did more of a deep dive into your set and
> have additional comments (in line). I think const-ing all this is a good
> approach. The way forward is to be able to see the entire patch set of
> changes in a V1 or a shared repo somewhere to have a better picture of
> what is going on. By the "entire patchset" I mean all the changes that
> you described in the "full process".

All the changes will be a lot. I don't think the incremental value to
migrate all proc_handlers versus the work is useful for the discussion.
I can however write up my proposed changes for the sysctl core properly
and submit them as part of the next revision.

> On Tue, Nov 28, 2023 at 09:18:30AM +0100, Thomas Weißschuh wrote:
> > Hi Joel,
> > 
> > On 2023-11-27 11:13:23+0100, Joel Granados wrote:
> > > In general I would like to see more clarity with the motivation and I
> > > would also expect some system testing. My comments inline:
> > 
> > Thanks for your feedback, response are below.
> > 
> > > On Sat, Nov 25, 2023 at 01:52:49PM +0100, Thomas Weißschuh wrote:
> > > > Problem description:
> > > > 
> > > > The kernel contains a lot of struct ctl_table throught the tree.
> > > > These are very often 'static' definitions.
> > > > It would be good to mark these tables const to avoid accidental or
> > > > malicious modifications.
> > 
> > > It is unclear to me what you mean here with accidental or malicious
> > > modifications. Do you have a specific attack vector in mind? Do you
> > > have an example of how this could happen maliciously? With
> > > accidental, do you mean in proc/sysctl.c? Can you expand more on the
> > > accidental part?
> > 
> > There is no specific attack vector I have in mind. The goal is to remove
> > mutable data, especially if it contains pointers, that could be used by
> > an attacker as a step in an exploit. See for example [0], [1].

> I think you should work "remove mutable data" as part of you main
> motivation when you send the non-RFC patch. I would also including [0]
> and [1] (and any other previous work) to help contextualize.

Ack.

> 
> > 
> > Accidental can be any out-of-bounds write throughout the kernel.
> > 
> > > What happens with the code that modifies these outside the sysctl core?
> > > Like for example in sysctl_route_net_init where the table is modified
> > > depending on the net->user_ns? Would these non-const ctl_table pointers
> > > be ok? would they be handled differently?
> > 
> > It is still completely fine to modify the tables before registering,
> > like sysctl_route_net_init is doing. That code should not need any
> > changes.
> > 
> > Modifying the table inside the handler function would bypass the
> > validation done when registering so sounds like a bad idea in general.

> This is done before registering. So the approach *is* sound.

Absolutely. Though, I wouldn't be surprised if some other subsystem is
doing this stuff in the handler.

> > It would still be possible however for a subsystem to do so by just not
> > making their sysctl table const and then modifying the table directly.

> Indeed. Which might be intended or migth be someone that just forgets to
> put const. I think you mentioned that there would be some sort of static
> check for this (coccinelle or smach, or something else)? 

My intention was to put the struct into scripts/const_structs.checkpatch
so checkpatch.pl warns about non-const instances.

> >  
> > > > Unfortunately the tables can not be made const because the core
> > > > registration functions expect mutable tables.
> > > > 
> > > > This is for two reasons:
> > > > 
> > > > 1) sysctl_{set,clear}_perm_empty_ctl_header in the sysctl core modify
> > > >    the table. This should be fixable by only modifying the header
> > > >    instead of the table itself.
> > > > 2) The table is passed to the handler function as a non-const pointer.
> > > > 
> > > > This series is an aproach on fixing reason 2).
> > 
> > > So number 2 will be sent in another set?

> Sorry, this was supposed to be "number 1", but you got my meaning :)

I was not entirely sure :-)
As mentioned above I do have a proposal for 1) and will submit this as
part of the next revision.
Or maybe as a standalone non-RFC patchset, because IMHO this is valuable
on its own.

> > 
> > If the initial feedback to the RFC and general process is positive, yes.

> Off the top of my head, putting  that type in the header instead of the
> ctl_table seems ok. I would include it in non-RFC version together with
> 2.
> 
> > 
> > > > 
> > > > Full process:
> > > > 
> > > > * Introduce field proc_handler_new for const handlers (this series)

> I don't understand why we need a new handler. Couldn't we just change
> the existing handler to receive `const struct ctl_table` and change all
> the `proc_do*` handlers?

The idea was that there are a lot of nonstandard proc handlers.
By doing it in steps we would avoid having to change all nonstandard
handlers in one go.
I looked a bit around and it seems that only 20% of sysctls use
nonstandard handlers.
Let's see if it's feasible to do those in one step.
It would indeed avoid a bunch of complexity all over the place.

> I'm guessing its because you want to do this in steps? if that is the
> case, it would be very helpfull to see (in some repo or V1) the steps
> to change all the handlers in the non-RFC version 
> 
> > > > * Migrate all core handlers to proc_handler_new (this series, partial)
> > > >   This can hopefully be done in a big switch, as it only involves
> > > >   functions and structures owned by the core sysctl code.
> It would be helpful to see what the "big switch" would look like. If it
> is all sysctl code and cannot be chunked up because of dependencies,
> then it should be ok to do it in one go.
> 
> > > > * Migrate all other sysctl handlers to proc_handler_new.
> > > > * Drop the old proc_handler_field.
> > > > * Fix the sysctl core to not modify the tables anymore.
> > > > * Adapt public sysctl APIs to take "const struct ctl_table *".
> > > > * Teach checkpatch.pl to warn on non-const "struct ctl_table"
> > > >   definitions.

> Have you considered how to ignore the cases where the ctl_tables are
> supposed to be non-const when they are defined (like in the network
> code that we were discussing earlier)

As it would be a checkpatch warning it can be ignore while writing the
patch and it won't trigger afterwards.

> > > > * Migrate definitions of "struct ctl_table" to "const" where applicable.
> These migrations are treewide and are usually reviewed by a wider
> audience. You might need to chunk it up to make the review more palpable
> for the other maintainers.

Ack.

> > > >  
> > > > 
> > > > Notes:
> > > > 
> > > > Just casting the function pointers around would trigger
> > > > CFI (control flow integrity) warnings.
> > > > 
> > > > The name of the new handler "proc_handler_new" is a bit too long messing
> > > > up the alignment of the table definitions.
> > > > Maybe "proc_handler2" or "proc_handler_c" for (const) would be better.
> > 
> > > indeed the name does not say much. "_new" looses its meaning quite fast
> > > :)
> > 
> > Hopefully somebody comes up with a better name!

> I would like to avoid this all together and just do add the const to the
> existing "proc_handler"

Ack.

> > 
> > > In my experience these tree wide modifications are quite tricky. Have you
> > > run any tests to see that everything is as it was? sysctl selftests and
> > > 0-day come to mind.
> > 
> > I managed to miss one change in my initial submission:
> > With the hunk below selftests and typing emails work.
> > 
> > --- a/fs/proc/proc_sysctl.c
> > +++ b/fs/proc/proc_sysctl.c
> > @@ -1151,7 +1151,7 @@ static int sysctl_check_table(const char *path, struct ctl_table_header *header)
> >                         else
> >                                 err |= sysctl_check_table_array(path, entry);
> >                 }
> > -               if (!entry->proc_handler)
> > +               if (!entry->proc_handler && !entry->proc_handler_new)
> >                         err |= sysctl_err(path, entry, "No proc_handler");
> >  
> >                 if ((entry->mode & (S_IRUGO|S_IWUGO)) != entry->mode)
> > 
> > > [..]
> > 
> > [0] 43a7206b0963 ("driver core: class: make class_register() take a const *")
> > [1] https://lore.kernel.org/lkml/20230930050033.41174-1-wedsonaf@gmail.com/

Thanks for the feedback!

Thomas

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

* Re: [PATCH RFC 0/7] sysctl: constify sysctl ctl_tables
  2023-12-03 15:37         ` Thomas Weißschuh
@ 2023-12-04  8:43           ` Joel Granados
  0 siblings, 0 replies; 13+ messages in thread
From: Joel Granados @ 2023-12-04  8:43 UTC (permalink / raw)
  To: Thomas Weißschuh
  Cc: Kees Cook, Gustavo A. R. Silva, Luis Chamberlain, Iurii Zaikin,
	Greg Kroah-Hartman, linux-hardening, linux-kernel, linux-fsdevel

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

Hey

I see that you sent a V2. I'll try to get to it at the end of the week.

On Sun, Dec 03, 2023 at 04:37:01PM +0100, Thomas Weißschuh wrote:
> Hi Joel,
> 
> On 2023-12-01 17:31:20+0100, Joel Granados wrote:
> > Hey Thomas.
> > 
> > Thx for the clarifications. I did more of a deep dive into your set and
> > have additional comments (in line). I think const-ing all this is a good
> > approach. The way forward is to be able to see the entire patch set of
> > changes in a V1 or a shared repo somewhere to have a better picture of
> > what is going on. By the "entire patchset" I mean all the changes that
> > you described in the "full process".
> 
> All the changes will be a lot. I don't think the incremental value to
> migrate all proc_handlers versus the work is useful for the discussion.
> I can however write up my proposed changes for the sysctl core properly
> and submit them as part of the next revision.
Looking forward to seeing them in V2

> 
> > On Tue, Nov 28, 2023 at 09:18:30AM +0100, Thomas Weißschuh wrote:
> > > Hi Joel,
> > > 
> > > On 2023-11-27 11:13:23+0100, Joel Granados wrote:
> > > > In general I would like to see more clarity with the motivation and I
> > > > would also expect some system testing. My comments inline:

<--- snip --->

> > is all sysctl code and cannot be chunked up because of dependencies,
> > then it should be ok to do it in one go.
> > 
> > > > > * Migrate all other sysctl handlers to proc_handler_new.
> > > > > * Drop the old proc_handler_field.
> > > > > * Fix the sysctl core to not modify the tables anymore.
> > > > > * Adapt public sysctl APIs to take "const struct ctl_table *".
> > > > > * Teach checkpatch.pl to warn on non-const "struct ctl_table"
> > > > >   definitions.
> 
> > Have you considered how to ignore the cases where the ctl_tables are
> > supposed to be non-const when they are defined (like in the network
> > code that we were discussing earlier)
> 
> As it would be a checkpatch warning it can be ignore while writing the
> patch and it won't trigger afterwards.
I mention coccinelle it is able to identify const vs non-const uses of
the ctl_table and only warn on the cases where it makes sense. This
would remove false negatives from pushing patches through.

> 
> > > > > * Migrate definitions of "struct ctl_table" to "const" where applicable.
> > These migrations are treewide and are usually reviewed by a wider
> > audience. You might need to chunk it up to make the review more palpable
> > for the other maintainers.
> 
> Ack.
> 
> > > > >  
> > > > > 
> > > > > Notes:
> > > > > 
> > > > > Just casting the function pointers around would trigger
> > > > > CFI (control flow integrity) warnings.
> > > > > 
> > > > > The name of the new handler "proc_handler_new" is a bit too long messing
> > > > > up the alignment of the table definitions.
> > > > > Maybe "proc_handler2" or "proc_handler_c" for (const) would be better.
> > > 
> > > > indeed the name does not say much. "_new" looses its meaning quite fast
> > > > :)
> > > 
> > > Hopefully somebody comes up with a better name!
> 
> > I would like to avoid this all together and just do add the const to the
> > existing "proc_handler"
> 
> Ack.
> 
> > > 
> > > > In my experience these tree wide modifications are quite tricky. Have you
> > > > run any tests to see that everything is as it was? sysctl selftests and
> > > > 0-day come to mind.
> > > 
> > > I managed to miss one change in my initial submission:
> > > With the hunk below selftests and typing emails work.
> > > 
> > > --- a/fs/proc/proc_sysctl.c
> > > +++ b/fs/proc/proc_sysctl.c
> > > @@ -1151,7 +1151,7 @@ static int sysctl_check_table(const char *path, struct ctl_table_header *header)
> > >                         else
> > >                                 err |= sysctl_check_table_array(path, entry);
> > >                 }
> > > -               if (!entry->proc_handler)
> > > +               if (!entry->proc_handler && !entry->proc_handler_new)
> > >                         err |= sysctl_err(path, entry, "No proc_handler");
> > >  
> > >                 if ((entry->mode & (S_IRUGO|S_IWUGO)) != entry->mode)
> > > 
> > > > [..]
> > > 
> > > [0] 43a7206b0963 ("driver core: class: make class_register() take a const *")
> > > [1] https://lore.kernel.org/lkml/20230930050033.41174-1-wedsonaf@gmail.com/
> 
> Thanks for the feedback!
> 
> Thomas

-- 

Joel Granados

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

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

end of thread, other threads:[~2023-12-04  8:43 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <CGME20231125125305eucas1p2ebdf870dd8ef46ea9d346f727b832439@eucas1p2.samsung.com>
2023-11-25 12:52 ` [PATCH RFC 0/7] sysctl: constify sysctl ctl_tables Thomas Weißschuh
2023-11-25 12:52   ` [PATCH RFC 1/7] sysctl: add helper sysctl_run_handler Thomas Weißschuh
2023-11-25 12:52   ` [PATCH RFC 2/7] bpf: cgroup: call proc handler through helper Thomas Weißschuh
2023-11-25 12:52   ` [PATCH RFC 3/7] sysctl: add proc_handler_new to struct ctl_table Thomas Weißschuh
2023-11-25 12:52   ` [PATCH RFC 4/7] net: sysctl: add new sysctl table handler to debug message Thomas Weißschuh
2023-11-25 12:52   ` [PATCH RFC 5/7] treewide: sysctl: migrate proc_dostring to proc_handler_new Thomas Weißschuh
2023-11-25 12:52   ` [PATCH RFC 6/7] treewide: sysctl: migrate proc_dobool " Thomas Weißschuh
2023-11-25 12:52   ` [PATCH RFC 7/7] treewide: sysctl: migrate proc_dointvec " Thomas Weißschuh
2023-11-27 10:13   ` [PATCH RFC 0/7] sysctl: constify sysctl ctl_tables Joel Granados
2023-11-28  8:18     ` Thomas Weißschuh
2023-12-01 16:31       ` Joel Granados
2023-12-03 15:37         ` Thomas Weißschuh
2023-12-04  8:43           ` 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).