Skip to contentSkip to conversation

sysctl fixes for v4.13-rc1

GIT PULL Eric W. Biederman 2 participants 3 messages Jul 13, 2017

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

Linus,

Please pull the for-linus branch from the git tree:

git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace.git for-linus

HEAD: 2fd1d2c4ceb2248a727696962cf3370dc9f5a0a4 proc: Fix proc_sys_prune_dcache to hold a sb reference

A rather embarassing and hard to hit bug was merged into 4.11-rc1. Andrei Vagin tracked this bug now and after some starting at the code I came up with a fix.

Eric

From 2fd1d2c4ceb2248a727696962cf3370dc9f5a0a4 Mon Sep 17 00:00:00 2001
From: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
Date: Thu, 6 Jul 2017 08:41:06 -0500
Subject: [PATCH] proc: Fix proc_sys_prune_dcache to hold a sb reference

Andrei Vagin writes:
FYI: This bug has been reproduced on 4.11.7

Quoted 35 lines
BUG: Dentry ffff895a3dd01240{i=4e7c09a,n=lo}  still in use (1) [unmount of proc proc]
------------[ cut here ]------------
WARNING: CPU: 1 PID: 13588 at fs/dcache.c:1445 umount_check+0x6e/0x80
CPU: 1 PID: 13588 Comm: kworker/1:1 Not tainted 4.11.7-200.fc25.x86_64 #1
Hardware name: CompuLab sbc-flt1/fitlet, BIOS SBCFLT_0.08.04 06/27/2015
Workqueue: events proc_cleanup_work
Call Trace:
 dump_stack+0x63/0x86
 __warn+0xcb/0xf0
 warn_slowpath_null+0x1d/0x20
 umount_check+0x6e/0x80
 d_walk+0xc6/0x270
 ? dentry_free+0x80/0x80
 do_one_tree+0x26/0x40
 shrink_dcache_for_umount+0x2d/0x90
 generic_shutdown_super+0x1f/0xf0
 kill_anon_super+0x12/0x20
 proc_kill_sb+0x40/0x50
 deactivate_locked_super+0x43/0x70
 deactivate_super+0x5a/0x60
 cleanup_mnt+0x3f/0x90
 mntput_no_expire+0x13b/0x190
 kern_unmount+0x3e/0x50
 pid_ns_release_proc+0x15/0x20
 proc_cleanup_work+0x15/0x20
 process_one_work+0x197/0x450
 worker_thread+0x4e/0x4a0
 kthread+0x109/0x140
 ? process_one_work+0x450/0x450
 ? kthread_park+0x90/0x90
 ret_from_fork+0x2c/0x40
---[ end trace e1c109611e5d0b41 ]---
VFS: Busy inodes after unmount of proc. Self-destruct in 5 seconds.  Have a nice day...
BUG: unable to handle kernel NULL pointer dereference at           (null)
IP: _raw_spin_lock+0xc/0x30
Quoted 1 line

PGD 0

Fix this by taking a reference to the super block in proc_sys_prune_dcache.

The superblock reference is the core of the fix however the sysctl_inodes list is converted to a hlist so that hlist_del_init_rcu may be used. This allows proc_sys_prune_dache to remove inodes the sysctl_inodes list, while not causing problems for proc_sys_evict_inode when if it later choses to remove the inode from the sysctl_inodes list. Removing inodes from the sysctl_inodes list allows proc_sys_prune_dcache to have a progress guarantee, while still being able to drop all locks. The fact that head->unregistering is set in start_unregistering ensures that no more inodes will be added to the the sysctl_inodes list.

Previously the code did a dance where it delayed calling iput until the next entry in the list was being considered to ensure the inode remained on the sysctl_inodes list until the next entry was walked to. The structure of the loop in this patch does not need that so is much easier to understand and maintain.

Fixes ace0c791e6c3 ("proc/sysctl: Don't grab i_lock under sysctl_lock.")
Fixes d6cffbbe9a7e ("proc/sysctl: prune stale dentries during unregistering")
---
 fs/proc/internal.h     |  2 +-
 fs/proc/proc_sysctl.c  | 43 ++++++++++++++++++++++++++++++-------------
 include/linux/sysctl.h |  2 +-
 3 files changed, 32 insertions(+), 15 deletions(-)
fs/proc/internal.h +1 -1
index c5ae09b6c726..18694598bebf 100644
@@ -67,7 +67,7 @@ struct proc_inode {
 	struct proc_dir_entry *pde;
 	struct ctl_table_header *sysctl;
 	struct ctl_table *sysctl_entry;
-	struct list_head sysctl_inodes;
+	struct hlist_node sysctl_inodes;
 	const struct proc_ns_operations *ns_ops;
 	struct inode vfs_inode;
 };
fs/proc/proc_sysctl.c +30 -13

76 lines not on this page · raw message

include/linux/sysctl.h +1 -1
index 80d07816def0..1c04a26bfd2f 100644
@@ -143,7 +143,7 @@ struct ctl_table_header
 	struct ctl_table_set *set;
 	struct ctl_dir *parent;
 	struct ctl_node *node;
-	struct list_head inodes; /* head for proc_inode->sysctl_inodes */
+	struct hlist_head inodes; /* head for proc_inode->sysctl_inodes */
 };
 
 struct ctl_dir {
Signature · 1 line
2.10.1
#1 lore raw
Quoted 22 lines · Eric W. Biederman

Linus,

Please pull the for-linus branch from the git tree:

git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace.git for-linus

HEAD: 2fd1d2c4ceb2248a727696962cf3370dc9f5a0a4 proc: Fix proc_sys_prune_dcache to hold a sb reference

A rather embarassing and hard to hit bug was merged into 4.11-rc1. Andrei Vagin tracked this bug now and after some starting at the code I came up with a fix.

Eric

From 2fd1d2c4ceb2248a727696962cf3370dc9f5a0a4 Mon Sep 17 00:00:00 2001
From: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
Date: Thu, 6 Jul 2017 08:41:06 -0500
Subject: [PATCH] proc: Fix proc_sys_prune_dcache to hold a sb reference

Andrei Vagin writes:
FYI: This bug has been reproduced on 4.11.7

[...]

Quoted 1 line

Please add first affected Linux-kernel release.

- Sedat -

Quoted 5 lines
Fixes ace0c791e6c3 ("proc/sysctl: Don't grab i_lock under sysctl_lock.")
Fixes d6cffbbe9a7e ("proc/sysctl: prune stale dentries during unregistering")
#2 lore raw
Quoted 24 lines · Sedat Dilek
Quoted 15 lines · Eric W. Biederman

Linus,

Please pull the for-linus branch from the git tree:

git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace.git for-linus

HEAD: 2fd1d2c4ceb2248a727696962cf3370dc9f5a0a4 proc: Fix proc_sys_prune_dcache to hold a sb reference

A rather embarassing and hard to hit bug was merged into 4.11-rc1. Andrei Vagin tracked this bug now and after some starting at the code I came up with a fix.

Eric

Quoted 7 lines

From 2fd1d2c4ceb2248a727696962cf3370dc9f5a0a4 Mon Sep 17 00:00:00 2001
From: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/[email protected]>
Date: Thu, 6 Jul 2017 08:41:06 -0500
Subject: [PATCH] proc: Fix proc_sys_prune_dcache to hold a sb reference

Andrei Vagin writes:
FYI: This bug has been reproduced on 4.11.7

Quoted 7 lines

[...]

Quoted 1 line

Please add first affected Linux-kernel release.

Please look at the fixes tags below. Especially when changes are backported that seems to be a much better indicator of what is affected than some arbitrary kernel number.

I have included a Fixes tags for the originally buggy commit and a Fixes tag for the incomplete fix for the originally buggy commit.

As a rule I only include a kernel version number if the originally affected kernel is not in Linus's git tree, and not in Thomas's conversion of the original bitkeeper tree to git.

Quoted 8 lines

- Sedat -

Quoted 5 lines
Fixes ace0c791e6c3 ("proc/sysctl: Don't grab i_lock under sysctl_lock.")
Fixes d6cffbbe9a7e ("proc/sysctl: prune stale dentries during unregistering")

Eric