Linux kernel -stable discussions
 help / color / mirror / Atom feed
From: Christian Brauner <brauner@kernel.org>
To: linux-fsdevel@vger.kernel.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
	Jann Horn <jannh@google.com>, Josef Bacik <josef@toxicpanda.com>,
	Chris Mason <mason@kernel.org>, Jeff Layton <jlayton@kernel.org>,
	NeilBrown <neil@brown.name>, Eric Dumazet <edumazet@kernel.org>,
	Thomas Gleixner <tglx@kernel.org>,
	Al Viro <viro@zeniv.linux.org.uk>,
	Jonathan Corbet <corbet@lwn.net>, Christoph Hellwig <hch@lst.de>,
	Greg Kroah-Hartman <gregkh@suse.de>,
	Joel Granados <joel.granados@kernel.org>,
	Kees Cook <kees@kernel.org>, Jan Kara <jack@suse.cz>,
	Jan Kara <jack@suse.com>,
	linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org,
	linux-acpi@vger.kernel.org, linux-kselftest@vger.kernel.org,
	linux-s390@vger.kernel.org, linux-scsi@vger.kernel.org,
	linux-um@lists.infradead.org, linux-wireless@vger.kernel.org,
	linuxppc-dev@lists.ozlabs.org, netdev@vger.kernel.org,
	ntfs3@lists.linux.dev, platform-driver-x86@vger.kernel.org,
	coreteam@netfilter.org, kexec@lists.infradead.org,
	linux-pci@vger.kernel.org, linux-sound@vger.kernel.org,
	netfilter-devel@vger.kernel.org, dri-devel@lists.freedesktop.org,
	ibm-acpi-devel@lists.sourceforge.net,
	jfs-discussion@lists.sourceforge.net,
	linux-alpha@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, linux-cifs@vger.kernel.org,
	linux-fbdev@vger.kernel.org, linux-hwmon@vger.kernel.org,
	linux-mm@kvack.org, linux-sh@vger.kernel.org,
	linux-usb@vger.kernel.org, samba-technical@lists.samba.org,
	sparclinux@vger.kernel.org, linux-m68k@lists.linux-m68k.org,
	linux-doc@vger.kernel.org, linux-serial@vger.kernel.org,
	linux-atm-general@lists.sourceforge.net,
	Takashi Iwai <tiwai@suse.de>,
	linux-input@vger.kernel.org, linux-raid@vger.kernel.org,
	linux-ext4@vger.kernel.org, linux-modules@vger.kernel.org,
	linux-debuggers@vger.kernel.org,
	"Christian Brauner (Amutable)" <brauner@kernel.org>,
	Chuck Lever <cel@kernel.org>,
	stable@vger.kernel.org
Subject: [PATCH RESEND v2 46/51] proc: sysctl: copy to and from userspace without holding the table
Date: Wed,  4 Nov 2026 20:27:15 +0100	[thread overview]
Message-ID: <20261104-work-procfs-bugfixes-v2-46-021c84d852e0@kernel.org> (raw)
In-Reply-To: <20261104-work-procfs-bugfixes-v2-0-021c84d852e0@kernel.org>

proc_sys_call_handler() grabs the table, copies in what is written,
calls the handler and copies what it produced out to userspace before
it lets go of the table again. Unregistering a table waits until nobody
uses it anymore. So a reader or writer whose copy faults for as long as
it wants, with userfaultfd or a stalled FUSE mapping, keeps
unregister_sysctl_table() waiting, and its callers like to hold locks
while they do that. addrconf unregisters the ipv6 sysctls of a device
with RTNL held, so a stalled read of /proc/sys/net/ipv6/conf/<dev>/mtu
holds up every RTNL user until the reader gives up.

Copy in before grabbing the table and copy out after letting go of it,
like procfs and kernfs do for their files. The buffer is ours, nothing
needs the table for the copies.

That moves the allocation and the copy in before the permission check.
A write that can't be copied in, or a request that is too large, now
fails with -EFAULT or -ENOMEM where it used to fail with -EPERM.

Fixes: 330d57fb98a9 ("[PATCH] Fix sysctl unregistration oops (CVE-2005-2709)")
Cc: stable@vger.kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
---
 fs/proc/proc_sysctl.c | 50 ++++++++++++++++++++++++++++----------------------
 1 file changed, 28 insertions(+), 22 deletions(-)

diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index ba52f13eb8f3..f5c9f04e8509 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -602,14 +602,36 @@ static ssize_t proc_sys_call_handler(struct kiocb *iocb, struct iov_iter *iter,
 		int write)
 {
 	struct inode *inode = file_inode(iocb->ki_filp);
-	struct ctl_table_header *head = grab_header(inode);
 	const struct ctl_table *table = PROC_I(inode)->sysctl_entry;
+	struct ctl_table_header *head;
 	size_t count = iov_iter_count(iter);
 	char *kbuf;
 	ssize_t error;
 
-	if (IS_ERR(head))
-		return PTR_ERR(head);
+	/* don't even try if the size is too large */
+	if (count >= KMALLOC_MAX_SIZE)
+		return -ENOMEM;
+	kbuf = kvzalloc(count + 1, GFP_KERNEL);
+	if (!kbuf)
+		return -ENOMEM;
+
+	/*
+	 * Copy in before grabbing the table and copy out after letting go of
+	 * it. Unregistering the table waits for us and a copy that faults can
+	 * take as long as userspace wants.
+	 */
+	if (write) {
+		error = -EFAULT;
+		if (!copy_from_iter_full(kbuf, count, iter))
+			goto out_free_buf;
+		kbuf[count] = '\0';
+	}
+
+	head = grab_header(inode);
+	if (IS_ERR(head)) {
+		error = PTR_ERR(head);
+		goto out_free_buf;
+	}
 
 	/*
 	 * At this point we know that the sysctl was not unregistered
@@ -624,28 +646,15 @@ static ssize_t proc_sys_call_handler(struct kiocb *iocb, struct iov_iter *iter,
 	if (!table->proc_handler)
 		goto out;
 
-	/* don't even try if the size is too large */
-	error = -ENOMEM;
-	if (count >= KMALLOC_MAX_SIZE)
-		goto out;
-	kbuf = kvzalloc(count + 1, GFP_KERNEL);
-	if (!kbuf)
-		goto out;
-
-	if (write) {
-		error = -EFAULT;
-		if (!copy_from_iter_full(kbuf, count, iter))
-			goto out_free_buf;
-		kbuf[count] = '\0';
-	}
-
 	error = BPF_CGROUP_RUN_PROG_SYSCTL(head, table, write, &kbuf, &count,
 					   &iocb->ki_pos);
 	if (error)
-		goto out_free_buf;
+		goto out;
 
 	/* careful: calling conventions are nasty here */
 	error = table->proc_handler(table, write, kbuf, &count, &iocb->ki_pos);
+out:
+	sysctl_head_finish(head);
 	if (error)
 		goto out_free_buf;
 
@@ -658,9 +667,6 @@ static ssize_t proc_sys_call_handler(struct kiocb *iocb, struct iov_iter *iter,
 	error = count;
 out_free_buf:
 	kvfree(kbuf);
-out:
-	sysctl_head_finish(head);
-
 	return error;
 }
 

-- 
2.53.0


  parent reply	other threads:[~2026-11-04 19:27 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20261104-work-procfs-v2-0-b45cd5789ac5@brauner>
2026-11-04 19:05 ` [PATCH RESEND v2 00/51] proc: fix a few old bugs in /proc handlers (Part 1/7) Christian Brauner
2026-11-04 19:06   ` [PATCH RESEND v2 01/51] alloc_tag: don't remove /proc/allocinfo under the codetag module lock Christian Brauner
2026-11-05  2:15     ` Hao Ge
2026-11-04 19:16   ` [PATCH RESEND v2 02/51] scsi: esas2r: don't copy kernel pointers out in EXPRESS_IOCTL_GET_MOD_INFO Christian Brauner
2026-11-04 19:16   ` [PATCH RESEND v2 03/51] ALSA: cs46xx: hand the region to the region proc files Christian Brauner
2026-11-07  9:00     ` Takashi Iwai
2026-11-04 19:16   ` [PATCH RESEND v2 04/51] PNP: isapnp: don't go on when isapnp_cfg_begin() fails Christian Brauner
2026-11-04 19:17   ` [PATCH RESEND v2 05/51] xtensa: simdisk: remove the proc entry before the disk Christian Brauner
2026-11-04 19:17   ` [PATCH RESEND v2 08/51] powerpc/pseries/lparcfg: don't drop the last byte of a write Christian Brauner
2026-11-04 19:19   ` [PATCH RESEND v2 13/51] sched/psi: don't drop the last byte of a trigger write Christian Brauner
2026-11-04 19:19   ` [PATCH RESEND v2 14/51] proc: sysctl: don't stop readdir at an entry that is being unregistered Christian Brauner
2026-11-04 19:19   ` [PATCH RESEND v2 15/51] PCI/proc: don't truncate the position of config space accesses Christian Brauner
2026-11-04 19:19   ` [PATCH RESEND v2 16/51] PNP: isapnp: don't read past the end of the buffer on a large pread() Christian Brauner
2026-11-04 19:20   ` [PATCH RESEND v2 17/51] s390/dasd: don't look in front of the buffer on an empty write Christian Brauner
2026-11-04 19:20   ` [PATCH RESEND v2 18/51] platform/x86: toshiba_acpi: reject malformed brightness and fan writes Christian Brauner
2026-11-04 19:20   ` [PATCH RESEND v2 19/51] xtensa: simdisk: don't read the file name without the lock Christian Brauner
2026-11-04 19:20   ` [PATCH RESEND v2 20/51] powerpc/rtas_flash: don't read past the validate message Christian Brauner
2026-11-04 19:21   ` [PATCH RESEND v2 21/51] powerpc/rtasd: zero the error log buffer Christian Brauner
2026-11-04 19:21   ` [PATCH RESEND v2 22/51] ALSA: info: don't write past the end of a data entry Christian Brauner
2026-11-04 19:22   ` [PATCH RESEND v2 26/51] scsi: core: NUL-terminate what is written to the host proc files Christian Brauner
2026-11-04 19:22   ` [PATCH RESEND v2 27/51] um: NUL-terminate what is written to /proc/exitcode Christian Brauner
2026-11-04 19:22   ` [PATCH RESEND v2 28/51] ntfs3: don't warn when a huge label is written Christian Brauner
2026-11-04 19:23   ` [PATCH RESEND v2 29/51] proc: don't walk through a non-directory when resolving a name Christian Brauner
2026-11-04 19:23   ` [PATCH RESEND v2 30/51] net: pktgen: reject device names with a '/' Christian Brauner
2026-11-04 19:23   ` [PATCH RESEND v2 31/51] proc: don't WARN about a name that is already registered Christian Brauner
2026-11-04 19:23   ` [PATCH RESEND v2 32/51] proc: resume readdir after the last name it returned Christian Brauner
2026-11-04 19:24   ` [PATCH RESEND v2 36/51] proc: don't let NOMMU map procfs files Christian Brauner
2026-11-04 19:25   ` [PATCH RESEND v2 37/51] proc/vmcore: don't let vmcore_cleanup() run twice at once Christian Brauner
2026-11-04 19:25   ` [PATCH RESEND v2 38/51] powerpc/crash_dump: check ioremap_cache() in copy_oldmem_page() Christian Brauner
2026-11-04 19:25   ` [PATCH RESEND v2 39/51] powerpc/crash_dump: recover from a machine check " Christian Brauner
2026-11-04 19:25   ` [PATCH RESEND v2 40/51] sunrpc: make queue_wait a global wait queue again Christian Brauner
2026-11-04 19:26   ` [PATCH RESEND v2 41/51] scsi: esas2r: bound the lengths of the HBA, SMP and firmware ioctls Christian Brauner
2026-11-04 19:26   ` [PATCH RESEND v2 42/51] powerpc/pseries: bound the lengths in the ofdt property parser Christian Brauner
2026-11-04 19:26   ` [PATCH RESEND v2 43/51] powerpc/pseries/lparcfg: return h_get_ppp()'s status as a long Christian Brauner
2026-11-04 19:26   ` [PATCH RESEND v2 44/51] proc: sysctl: resume readdir after the last name it returned Christian Brauner
2026-11-05  0:08     ` Jann Horn
2026-11-05  8:43       ` Christian Brauner
2026-11-05 16:26     ` Jann Horn
2026-11-04 19:27   ` Christian Brauner [this message]
2026-11-04 19:27   ` [PATCH RESEND v2 48/51] proc: sysctl: don't hold the tables while readdir copies to userspace Christian Brauner
2026-11-04 19:28   ` [PATCH RESEND v2 50/51] proc: don't pin a symlink's entry while readlink() copies it out Christian Brauner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261104-work-procfs-bugfixes-v2-46-021c84d852e0@kernel.org \
    --to=brauner@kernel.org \
    --cc=cel@kernel.org \
    --cc=corbet@lwn.net \
    --cc=coreteam@netfilter.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=edumazet@kernel.org \
    --cc=gregkh@suse.de \
    --cc=hch@lst.de \
    --cc=ibm-acpi-devel@lists.sourceforge.net \
    --cc=jack@suse.com \
    --cc=jack@suse.cz \
    --cc=jannh@google.com \
    --cc=jfs-discussion@lists.sourceforge.net \
    --cc=jlayton@kernel.org \
    --cc=joel.granados@kernel.org \
    --cc=josef@toxicpanda.com \
    --cc=kees@kernel.org \
    --cc=kexec@lists.infradead.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-alpha@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-atm-general@lists.sourceforge.net \
    --cc=linux-cifs@vger.kernel.org \
    --cc=linux-debuggers@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-fbdev@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-hwmon@vger.kernel.org \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-m68k@lists.linux-m68k.org \
    --cc=linux-mm@kvack.org \
    --cc=linux-modules@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux-raid@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=linux-serial@vger.kernel.org \
    --cc=linux-sh@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=linux-um@lists.infradead.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=mason@kernel.org \
    --cc=neil@brown.name \
    --cc=netdev@vger.kernel.org \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=ntfs3@lists.linux.dev \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=samba-technical@lists.samba.org \
    --cc=sparclinux@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=tglx@kernel.org \
    --cc=tiwai@suse.de \
    --cc=torvalds@linux-foundation.org \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox