]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/2.6.36.2/do_exit-make-sure-that-we-run-with-get_fs-user_ds.patch
fixes for 4.19
[thirdparty/kernel/stable-queue.git] / releases / 2.6.36.2 / do_exit-make-sure-that-we-run-with-get_fs-user_ds.patch
CommitLineData
d9b1f36d
GKH
1From 33dd94ae1ccbfb7bf0fb6c692bc3d1c4269e6177 Mon Sep 17 00:00:00 2001
2From: Nelson Elhage <nelhage@ksplice.com>
3Date: Thu, 2 Dec 2010 14:31:21 -0800
4Subject: do_exit(): make sure that we run with get_fs() == USER_DS
5
6From: Nelson Elhage <nelhage@ksplice.com>
7
8commit 33dd94ae1ccbfb7bf0fb6c692bc3d1c4269e6177 upstream.
9
10If a user manages to trigger an oops with fs set to KERNEL_DS, fs is not
11otherwise reset before do_exit(). do_exit may later (via mm_release in
12fork.c) do a put_user to a user-controlled address, potentially allowing
13a user to leverage an oops into a controlled write into kernel memory.
14
15This is only triggerable in the presence of another bug, but this
16potentially turns a lot of DoS bugs into privilege escalations, so it's
17worth fixing. I have proof-of-concept code which uses this bug along
18with CVE-2010-3849 to write a zero to an arbitrary kernel address, so
19I've tested that this is not theoretical.
20
21A more logical place to put this fix might be when we know an oops has
22occurred, before we call do_exit(), but that would involve changing
23every architecture, in multiple places.
24
25Let's just stick it in do_exit instead.
26
27[akpm@linux-foundation.org: update code comment]
28Signed-off-by: Nelson Elhage <nelhage@ksplice.com>
29Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
30Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
31Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
32Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
33
34---
35 kernel/exit.c | 9 +++++++++
36 1 file changed, 9 insertions(+)
37
38--- a/kernel/exit.c
39+++ b/kernel/exit.c
40@@ -903,6 +903,15 @@ NORET_TYPE void do_exit(long code)
41 if (unlikely(!tsk->pid))
42 panic("Attempted to kill the idle task!");
43
44+ /*
45+ * If do_exit is called because this processes oopsed, it's possible
46+ * that get_fs() was left as KERNEL_DS, so reset it to USER_DS before
47+ * continuing. Amongst other possible reasons, this is to prevent
48+ * mm_release()->clear_child_tid() from writing to a user-controlled
49+ * kernel address.
50+ */
51+ set_fs(USER_DS);
52+
53 tracehook_report_exit(&code);
54
55 validate_creds_for_do_exit(tsk);