From a126d0bd2708ca40b91b5c2b2ab05189475aa5fd Mon Sep 17 00:00:00 2001 From: Salvatore Bonaccorso Date: Mon, 16 Jan 2017 09:25:25 +0100 Subject: [PATCH] sysctl: Drop reference added by grab_header in proc_sys_readdir (CVE-2016-9191) --- debian/changelog | 6 +- ...rence-added-by-grab_header-in-proc_s.patch | 87 +++++++++++++++++++ debian/patches/series | 1 + 3 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 debian/patches/bugfix/all/sysctl-Drop-reference-added-by-grab_header-in-proc_s.patch diff --git a/debian/changelog b/debian/changelog index 2020c3002..cfcca6743 100644 --- a/debian/changelog +++ b/debian/changelog @@ -239,7 +239,11 @@ linux (4.9.4-1) UNRELEASED; urgency=medium support (Closes: #851481) * nbd: use loff_t for blocksize and nbd_set_size args (Closes: #851533) - -- Salvatore Bonaccorso Sun, 15 Jan 2017 14:48:41 +0100 + [ Salvatore Bonaccorso ] + * sysctl: Drop reference added by grab_header in proc_sys_readdir + (CVE-2016-9191) + + -- Salvatore Bonaccorso Mon, 16 Jan 2017 09:26:13 +0100 linux (4.9.2-2) unstable; urgency=medium diff --git a/debian/patches/bugfix/all/sysctl-Drop-reference-added-by-grab_header-in-proc_s.patch b/debian/patches/bugfix/all/sysctl-Drop-reference-added-by-grab_header-in-proc_s.patch new file mode 100644 index 000000000..c91cd09a7 --- /dev/null +++ b/debian/patches/bugfix/all/sysctl-Drop-reference-added-by-grab_header-in-proc_s.patch @@ -0,0 +1,87 @@ +From: Zhou Chengming +Date: Fri, 6 Jan 2017 09:32:32 +0800 +Subject: sysctl: Drop reference added by grab_header in proc_sys_readdir +Origin: https://git.kernel.org/linus/93362fa47fe98b62e4a34ab408c4a418432e7939 + +Fixes CVE-2016-9191, proc_sys_readdir doesn't drop reference +added by grab_header when return from !dir_emit_dots path. +It can cause any path called unregister_sysctl_table will +wait forever. + +The calltrace of CVE-2016-9191: + +[ 5535.960522] Call Trace: +[ 5535.963265] [] schedule+0x3f/0xa0 +[ 5535.968817] [] schedule_timeout+0x3db/0x6f0 +[ 5535.975346] [] ? wait_for_completion+0x45/0x130 +[ 5535.982256] [] wait_for_completion+0xc3/0x130 +[ 5535.988972] [] ? wake_up_q+0x80/0x80 +[ 5535.994804] [] drop_sysctl_table+0xc4/0xe0 +[ 5536.001227] [] drop_sysctl_table+0x77/0xe0 +[ 5536.007648] [] unregister_sysctl_table+0x4d/0xa0 +[ 5536.014654] [] unregister_sysctl_table+0x7f/0xa0 +[ 5536.021657] [] unregister_sched_domain_sysctl+0x15/0x40 +[ 5536.029344] [] partition_sched_domains+0x44/0x450 +[ 5536.036447] [] ? __mutex_unlock_slowpath+0x111/0x1f0 +[ 5536.043844] [] rebuild_sched_domains_locked+0x64/0xb0 +[ 5536.051336] [] update_flag+0x11d/0x210 +[ 5536.057373] [] ? mutex_lock_nested+0x2df/0x450 +[ 5536.064186] [] ? cpuset_css_offline+0x1b/0x60 +[ 5536.070899] [] ? trace_hardirqs_on+0xd/0x10 +[ 5536.077420] [] ? mutex_lock_nested+0x2df/0x450 +[ 5536.084234] [] ? css_killed_work_fn+0x25/0x220 +[ 5536.091049] [] cpuset_css_offline+0x35/0x60 +[ 5536.097571] [] css_killed_work_fn+0x5c/0x220 +[ 5536.104207] [] process_one_work+0x1df/0x710 +[ 5536.110736] [] ? process_one_work+0x160/0x710 +[ 5536.117461] [] worker_thread+0x12b/0x4a0 +[ 5536.123697] [] ? process_one_work+0x710/0x710 +[ 5536.130426] [] kthread+0xfe/0x120 +[ 5536.135991] [] ret_from_fork+0x1f/0x40 +[ 5536.142041] [] ? kthread_create_on_node+0x230/0x230 + +One cgroup maintainer mentioned that "cgroup is trying to offline +a cpuset css, which takes place under cgroup_mutex. The offlining +ends up trying to drain active usages of a sysctl table which apprently +is not happening." +The real reason is that proc_sys_readdir doesn't drop reference added +by grab_header when return from !dir_emit_dots path. So this cpuset +offline path will wait here forever. + +See here for details: http://www.openwall.com/lists/oss-security/2016/11/04/13 + +Fixes: f0c3b5093add ("[readdir] convert procfs") +Cc: stable@vger.kernel.org +Reported-by: CAI Qian +Tested-by: Yang Shukui +Signed-off-by: Zhou Chengming +Acked-by: Al Viro +Signed-off-by: Eric W. Biederman +--- + fs/proc/proc_sysctl.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c +index 55313d9..d4e37ac 100644 +--- a/fs/proc/proc_sysctl.c ++++ b/fs/proc/proc_sysctl.c +@@ -709,7 +709,7 @@ static int proc_sys_readdir(struct file *file, struct dir_context *ctx) + ctl_dir = container_of(head, struct ctl_dir, header); + + if (!dir_emit_dots(file, ctx)) +- return 0; ++ goto out; + + pos = 2; + +@@ -719,6 +719,7 @@ static int proc_sys_readdir(struct file *file, struct dir_context *ctx) + break; + } + } ++out: + sysctl_head_finish(head); + return 0; + } +-- +2.1.4 + diff --git a/debian/patches/series b/debian/patches/series index 14e5a838c..f305704f2 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -94,6 +94,7 @@ features/all/securelevel/arm64-add-kernel-config-option-to-set-securelevel-wh.pa # Security fixes debian/i386-686-pae-pci-set-pci-nobios-by-default.patch +bugfix/all/sysctl-Drop-reference-added-by-grab_header-in-proc_s.patch # Fix exported symbol versions bugfix/ia64/revert-ia64-move-exports-to-definitions.patch