]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.4.144/nospec-allow-getting-setting-on-non-current-task.patch
6.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.4.144 / nospec-allow-getting-setting-on-non-current-task.patch
CommitLineData
e9e21f07
GKH
1From foo@baz Mon Jul 23 10:04:05 CEST 2018
2From: "Srivatsa S. Bhat" <srivatsa@csail.mit.edu>
3Date: Sat, 14 Jul 2018 02:36:17 -0700
4Subject: nospec: Allow getting/setting on non-current task
5To: gregkh@linuxfoundation.org, stable@vger.kernel.org
6Cc: Kees Cook <keescook@chromium.org>, Thomas Gleixner <tglx@linutronix.de>, David Woodhouse <dwmw@amazon.co.uk>, "Matt Helsley \(VMware\)" <matt.helsley@gmail.com>, Alexey Makhalov <amakhalov@vmware.com>, Bo Gan <ganb@vmware.com>, matt.helsley@gmail.com, rostedt@goodmis.org, amakhalov@vmware.com, ganb@vmware.com, srivatsa@csail.mit.edu, srivatsab@vmware.com
7Message-ID: <153156097734.10043.17651791931697056953.stgit@srivatsa-ubuntu>
8
9From: Kees Cook <keescook@chromium.org>
10
11commit 7bbf1373e228840bb0295a2ca26d548ef37f448e upstream
12
13Adjust arch_prctl_get/set_spec_ctrl() to operate on tasks other than
14current.
15
16This is needed both for /proc/$pid/status queries and for seccomp (since
17thread-syncing can trigger seccomp in non-current threads).
18
19Signed-off-by: Kees Cook <keescook@chromium.org>
20Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
21Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
22Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
23Signed-off-by: Srivatsa S. Bhat <srivatsa@csail.mit.edu>
24Reviewed-by: Matt Helsley (VMware) <matt.helsley@gmail.com>
25Reviewed-by: Alexey Makhalov <amakhalov@vmware.com>
26Reviewed-by: Bo Gan <ganb@vmware.com>
27Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
28---
29
30 arch/x86/kernel/cpu/bugs.c | 27 ++++++++++++++++-----------
31 include/linux/nospec.h | 7 +++++--
32 kernel/sys.c | 9 +++++----
33 3 files changed, 26 insertions(+), 17 deletions(-)
34
35--- a/arch/x86/kernel/cpu/bugs.c
36+++ b/arch/x86/kernel/cpu/bugs.c
37@@ -529,31 +529,35 @@ static void ssb_select_mitigation()
38
39 #undef pr_fmt
40
41-static int ssb_prctl_set(unsigned long ctrl)
42+static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl)
43 {
44- bool rds = !!test_tsk_thread_flag(current, TIF_RDS);
45+ bool rds = !!test_tsk_thread_flag(task, TIF_RDS);
46
47 if (ssb_mode != SPEC_STORE_BYPASS_PRCTL)
48 return -ENXIO;
49
50 if (ctrl == PR_SPEC_ENABLE)
51- clear_tsk_thread_flag(current, TIF_RDS);
52+ clear_tsk_thread_flag(task, TIF_RDS);
53 else
54- set_tsk_thread_flag(current, TIF_RDS);
55+ set_tsk_thread_flag(task, TIF_RDS);
56
57- if (rds != !!test_tsk_thread_flag(current, TIF_RDS))
58+ /*
59+ * If being set on non-current task, delay setting the CPU
60+ * mitigation until it is next scheduled.
61+ */
62+ if (task == current && rds != !!test_tsk_thread_flag(task, TIF_RDS))
63 speculative_store_bypass_update();
64
65 return 0;
66 }
67
68-static int ssb_prctl_get(void)
69+static int ssb_prctl_get(struct task_struct *task)
70 {
71 switch (ssb_mode) {
72 case SPEC_STORE_BYPASS_DISABLE:
73 return PR_SPEC_DISABLE;
74 case SPEC_STORE_BYPASS_PRCTL:
75- if (test_tsk_thread_flag(current, TIF_RDS))
76+ if (test_tsk_thread_flag(task, TIF_RDS))
77 return PR_SPEC_PRCTL | PR_SPEC_DISABLE;
78 return PR_SPEC_PRCTL | PR_SPEC_ENABLE;
79 default:
80@@ -563,24 +567,25 @@ static int ssb_prctl_get(void)
81 }
82 }
83
84-int arch_prctl_spec_ctrl_set(unsigned long which, unsigned long ctrl)
85+int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which,
86+ unsigned long ctrl)
87 {
88 if (ctrl != PR_SPEC_ENABLE && ctrl != PR_SPEC_DISABLE)
89 return -ERANGE;
90
91 switch (which) {
92 case PR_SPEC_STORE_BYPASS:
93- return ssb_prctl_set(ctrl);
94+ return ssb_prctl_set(task, ctrl);
95 default:
96 return -ENODEV;
97 }
98 }
99
100-int arch_prctl_spec_ctrl_get(unsigned long which)
101+int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which)
102 {
103 switch (which) {
104 case PR_SPEC_STORE_BYPASS:
105- return ssb_prctl_get();
106+ return ssb_prctl_get(task);
107 default:
108 return -ENODEV;
109 }
110--- a/include/linux/nospec.h
111+++ b/include/linux/nospec.h
112@@ -7,6 +7,8 @@
113 #define _LINUX_NOSPEC_H
114 #include <asm/barrier.h>
115
116+struct task_struct;
117+
118 /**
119 * array_index_mask_nospec() - generate a ~0 mask when index < size, 0 otherwise
120 * @index: array element index
121@@ -57,7 +59,8 @@ static inline unsigned long array_index_
122 })
123
124 /* Speculation control prctl */
125-int arch_prctl_spec_ctrl_get(unsigned long which);
126-int arch_prctl_spec_ctrl_set(unsigned long which, unsigned long ctrl);
127+int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which);
128+int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which,
129+ unsigned long ctrl);
130
131 #endif /* _LINUX_NOSPEC_H */
132--- a/kernel/sys.c
133+++ b/kernel/sys.c
134@@ -2075,12 +2075,13 @@ static int prctl_get_tid_address(struct
135 }
136 #endif
137
138-int __weak arch_prctl_spec_ctrl_get(unsigned long which)
139+int __weak arch_prctl_spec_ctrl_get(struct task_struct *t, unsigned long which)
140 {
141 return -EINVAL;
142 }
143
144-int __weak arch_prctl_spec_ctrl_set(unsigned long which, unsigned long ctrl)
145+int __weak arch_prctl_spec_ctrl_set(struct task_struct *t, unsigned long which,
146+ unsigned long ctrl)
147 {
148 return -EINVAL;
149 }
150@@ -2282,12 +2283,12 @@ SYSCALL_DEFINE5(prctl, int, option, unsi
151 case PR_GET_SPECULATION_CTRL:
152 if (arg3 || arg4 || arg5)
153 return -EINVAL;
154- error = arch_prctl_spec_ctrl_get(arg2);
155+ error = arch_prctl_spec_ctrl_get(me, arg2);
156 break;
157 case PR_SET_SPECULATION_CTRL:
158 if (arg4 || arg5)
159 return -EINVAL;
160- error = arch_prctl_spec_ctrl_set(arg2, arg3);
161+ error = arch_prctl_spec_ctrl_set(me, arg2, arg3);
162 break;
163 default:
164 error = -EINVAL;