1 |
commit: ee6147f8d257074979248d11bf7736e30662d0ea |
2 |
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org> |
3 |
AuthorDate: Tue Nov 5 00:05:54 2013 +0000 |
4 |
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org> |
5 |
CommitDate: Tue Nov 5 00:05:54 2013 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/hardened-patchset.git;a=commit;h=ee6147f8 |
7 |
|
8 |
Grsec/PaX: 2.9.1-{3.2.52,3.11.6}-201311021635 |
9 |
|
10 |
--- |
11 |
3.11.6/0000_README | 2 +- |
12 |
...420_grsecurity-2.9.1-3.11.6-201311021635.patch} | 107 ++ |
13 |
3.2.52/0000_README | 2 +- |
14 |
...420_grsecurity-2.9.1-3.2.52-201311021628.patch} | 1688 ++++++++++++++++++-- |
15 |
4 files changed, 1690 insertions(+), 109 deletions(-) |
16 |
|
17 |
diff --git a/3.11.6/0000_README b/3.11.6/0000_README |
18 |
index 2489326..358a97d 100644 |
19 |
--- a/3.11.6/0000_README |
20 |
+++ b/3.11.6/0000_README |
21 |
@@ -2,7 +2,7 @@ README |
22 |
----------------------------------------------------------------------------- |
23 |
Individual Patch Descriptions: |
24 |
----------------------------------------------------------------------------- |
25 |
-Patch: 4420_grsecurity-2.9.1-3.11.6-201310292050.patch |
26 |
+Patch: 4420_grsecurity-2.9.1-3.11.6-201311021635.patch |
27 |
From: http://www.grsecurity.net |
28 |
Desc: hardened-sources base patch from upstream grsecurity |
29 |
|
30 |
|
31 |
diff --git a/3.11.6/4420_grsecurity-2.9.1-3.11.6-201310292050.patch b/3.11.6/4420_grsecurity-2.9.1-3.11.6-201311021635.patch |
32 |
similarity index 99% |
33 |
rename from 3.11.6/4420_grsecurity-2.9.1-3.11.6-201310292050.patch |
34 |
rename to 3.11.6/4420_grsecurity-2.9.1-3.11.6-201311021635.patch |
35 |
index 020c231..306363f 100644 |
36 |
--- a/3.11.6/4420_grsecurity-2.9.1-3.11.6-201310292050.patch |
37 |
+++ b/3.11.6/4420_grsecurity-2.9.1-3.11.6-201311021635.patch |
38 |
@@ -46087,6 +46087,19 @@ index fcb0329..d77b7f2 100644 |
39 |
|
40 |
ret = sysfs_create_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr); |
41 |
if (ret) |
42 |
+diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c |
43 |
+index 408a42e..f0d432c 100644 |
44 |
+--- a/drivers/scsi/aacraid/linit.c |
45 |
++++ b/drivers/scsi/aacraid/linit.c |
46 |
+@@ -771,6 +771,8 @@ static long aac_compat_do_ioctl(struct aac_dev *dev, unsigned cmd, unsigned long |
47 |
+ static int aac_compat_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) |
48 |
+ { |
49 |
+ struct aac_dev *dev = (struct aac_dev *)sdev->host->hostdata; |
50 |
++ if (!capable(CAP_SYS_RAWIO)) |
51 |
++ return -EPERM; |
52 |
+ return aac_compat_do_ioctl(dev, cmd, (unsigned long)arg); |
53 |
+ } |
54 |
+ |
55 |
diff --git a/drivers/scsi/bfa/bfa_fcpim.h b/drivers/scsi/bfa/bfa_fcpim.h |
56 |
index e693af6..2e525b6 100644 |
57 |
--- a/drivers/scsi/bfa/bfa_fcpim.h |
58 |
@@ -47112,6 +47125,18 @@ index ee3a57f..18368c1 100644 |
59 |
tdev->dev = device_create(timed_output_class, NULL, |
60 |
MKDEV(0, tdev->index), NULL, "%s", tdev->name); |
61 |
if (IS_ERR(tdev->dev)) |
62 |
+diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c |
63 |
+index f67a225..756b634 100644 |
64 |
+--- a/drivers/staging/bcm/Bcmchar.c |
65 |
++++ b/drivers/staging/bcm/Bcmchar.c |
66 |
+@@ -1960,6 +1960,7 @@ cntrlEnd: |
67 |
+ |
68 |
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Called IOCTL_BCM_GET_DEVICE_DRIVER_INFO\n"); |
69 |
+ |
70 |
++ memset(&DevInfo, 0, sizeof(DevInfo)); |
71 |
+ DevInfo.MaxRDMBufferSize = BUFFER_4K; |
72 |
+ DevInfo.u32DSDStartOffset = EEPROM_CALPARAM_START; |
73 |
+ DevInfo.u32RxAlignmentCorrection = 0; |
74 |
diff --git a/drivers/staging/media/solo6x10/solo6x10-core.c b/drivers/staging/media/solo6x10/solo6x10-core.c |
75 |
index 3675020..e80d92c 100644 |
76 |
--- a/drivers/staging/media/solo6x10/solo6x10-core.c |
77 |
@@ -47203,6 +47228,20 @@ index c3a90e7..023619a 100644 |
78 |
#endif |
79 |
} |
80 |
|
81 |
+diff --git a/drivers/staging/ozwpan/ozcdev.c b/drivers/staging/ozwpan/ozcdev.c |
82 |
+index 374fdc3..ea5f9f3 100644 |
83 |
+--- a/drivers/staging/ozwpan/ozcdev.c |
84 |
++++ b/drivers/staging/ozwpan/ozcdev.c |
85 |
+@@ -152,6 +152,9 @@ static ssize_t oz_cdev_write(struct file *filp, const char __user *buf, |
86 |
+ struct oz_app_hdr *app_hdr; |
87 |
+ struct oz_serial_ctx *ctx; |
88 |
+ |
89 |
++ if (count > sizeof(ei->data) - sizeof(*elt) - sizeof(*app_hdr)) |
90 |
++ return -EINVAL; |
91 |
++ |
92 |
+ spin_lock_bh(&g_cdev.lock); |
93 |
+ pd = g_cdev.active_pd; |
94 |
+ if (pd) |
95 |
diff --git a/drivers/staging/rtl8712/rtl871x_io.h b/drivers/staging/rtl8712/rtl871x_io.h |
96 |
index dc23395..cf7e9b1 100644 |
97 |
--- a/drivers/staging/rtl8712/rtl871x_io.h |
98 |
@@ -47346,6 +47385,47 @@ index c699a30..b90a5fd 100644 |
99 |
pDevice->apdev->netdev_ops = &apdev_netdev_ops; |
100 |
|
101 |
pDevice->apdev->type = ARPHRD_IEEE80211; |
102 |
+diff --git a/drivers/staging/wlags49_h2/wl_priv.c b/drivers/staging/wlags49_h2/wl_priv.c |
103 |
+index c97e0e1..7e10dcd 100644 |
104 |
+--- a/drivers/staging/wlags49_h2/wl_priv.c |
105 |
++++ b/drivers/staging/wlags49_h2/wl_priv.c |
106 |
+@@ -570,6 +570,7 @@ int wvlan_uil_put_info(struct uilreq *urq, struct wl_private *lp) |
107 |
+ ltv_t *pLtv; |
108 |
+ bool_t ltvAllocated = FALSE; |
109 |
+ ENCSTRCT sEncryption; |
110 |
++ size_t len; |
111 |
+ |
112 |
+ #ifdef USE_WDS |
113 |
+ hcf_16 hcfPort = HCF_PORT_0; |
114 |
+@@ -686,7 +687,8 @@ int wvlan_uil_put_info(struct uilreq *urq, struct wl_private *lp) |
115 |
+ break; |
116 |
+ case CFG_CNF_OWN_NAME: |
117 |
+ memset(lp->StationName, 0, sizeof(lp->StationName)); |
118 |
+- memcpy((void *)lp->StationName, (void *)&pLtv->u.u8[2], (size_t)pLtv->u.u16[0]); |
119 |
++ len = min_t(size_t, pLtv->u.u16[0], sizeof(lp->StationName)); |
120 |
++ strlcpy(lp->StationName, &pLtv->u.u8[2], len); |
121 |
+ pLtv->u.u16[0] = CNV_INT_TO_LITTLE(pLtv->u.u16[0]); |
122 |
+ break; |
123 |
+ case CFG_CNF_LOAD_BALANCING: |
124 |
+@@ -1783,6 +1785,7 @@ int wvlan_set_station_nickname(struct net_device *dev, |
125 |
+ { |
126 |
+ struct wl_private *lp = wl_priv(dev); |
127 |
+ unsigned long flags; |
128 |
++ size_t len; |
129 |
+ int ret = 0; |
130 |
+ /*------------------------------------------------------------------------*/ |
131 |
+ |
132 |
+@@ -1793,8 +1796,8 @@ int wvlan_set_station_nickname(struct net_device *dev, |
133 |
+ wl_lock(lp, &flags); |
134 |
+ |
135 |
+ memset(lp->StationName, 0, sizeof(lp->StationName)); |
136 |
+- |
137 |
+- memcpy(lp->StationName, extra, wrqu->data.length); |
138 |
++ len = min_t(size_t, wrqu->data.length, sizeof(lp->StationName)); |
139 |
++ strlcpy(lp->StationName, extra, len); |
140 |
+ |
141 |
+ /* Commit the adapter parameters */ |
142 |
+ wl_apply(lp); |
143 |
diff --git a/drivers/staging/zcache/tmem.h b/drivers/staging/zcache/tmem.h |
144 |
index d128ce2..fc1f9a1 100644 |
145 |
--- a/drivers/staging/zcache/tmem.h |
146 |
@@ -85733,6 +85813,20 @@ index e796429..6e38f9f 100644 |
147 |
|
148 |
static inline void *ptr_to_indirect(void *ptr) |
149 |
{ |
150 |
+diff --git a/lib/scatterlist.c b/lib/scatterlist.c |
151 |
+index a685c8a..d16fa29 100644 |
152 |
+--- a/lib/scatterlist.c |
153 |
++++ b/lib/scatterlist.c |
154 |
+@@ -577,7 +577,8 @@ void sg_miter_stop(struct sg_mapping_iter *miter) |
155 |
+ miter->__offset += miter->consumed; |
156 |
+ miter->__remaining -= miter->consumed; |
157 |
+ |
158 |
+- if (miter->__flags & SG_MITER_TO_SG) |
159 |
++ if ((miter->__flags & SG_MITER_TO_SG) && |
160 |
++ !PageSlab(miter->page)) |
161 |
+ flush_kernel_dcache_page(miter->page); |
162 |
+ |
163 |
+ if (miter->__flags & SG_MITER_ATOMIC) { |
164 |
diff --git a/lib/strncpy_from_user.c b/lib/strncpy_from_user.c |
165 |
index bb2b201..46abaf9 100644 |
166 |
--- a/lib/strncpy_from_user.c |
167 |
@@ -91613,6 +91707,19 @@ index dfa602c..3103d88 100644 |
168 |
if (!IS_ERR(flo)) |
169 |
fle->object = flo; |
170 |
else |
171 |
+diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c |
172 |
+index 52d0f83..4a1d064 100644 |
173 |
+--- a/net/core/flow_dissector.c |
174 |
++++ b/net/core/flow_dissector.c |
175 |
+@@ -40,7 +40,7 @@ again: |
176 |
+ struct iphdr _iph; |
177 |
+ ip: |
178 |
+ iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph); |
179 |
+- if (!iph) |
180 |
++ if (!iph || iph->ihl < 5) |
181 |
+ return false; |
182 |
+ |
183 |
+ if (ip_is_fragment(iph)) |
184 |
diff --git a/net/core/iovec.c b/net/core/iovec.c |
185 |
index de178e4..1dabd8b 100644 |
186 |
--- a/net/core/iovec.c |
187 |
|
188 |
diff --git a/3.2.52/0000_README b/3.2.52/0000_README |
189 |
index f3e1e87..7ddab2f 100644 |
190 |
--- a/3.2.52/0000_README |
191 |
+++ b/3.2.52/0000_README |
192 |
@@ -126,7 +126,7 @@ Patch: 1051_linux-3.2.52.patch |
193 |
From: http://www.kernel.org |
194 |
Desc: Linux 3.2.52 |
195 |
|
196 |
-Patch: 4420_grsecurity-2.9.1-3.2.52-201310292049.patch |
197 |
+Patch: 4420_grsecurity-2.9.1-3.2.52-201311021628.patch |
198 |
From: http://www.grsecurity.net |
199 |
Desc: hardened-sources base patch from upstream grsecurity |
200 |
|
201 |
|
202 |
diff --git a/3.2.52/4420_grsecurity-2.9.1-3.2.52-201310292049.patch b/3.2.52/4420_grsecurity-2.9.1-3.2.52-201311021628.patch |
203 |
similarity index 98% |
204 |
rename from 3.2.52/4420_grsecurity-2.9.1-3.2.52-201310292049.patch |
205 |
rename to 3.2.52/4420_grsecurity-2.9.1-3.2.52-201311021628.patch |
206 |
index e09de55..398b6be 100644 |
207 |
--- a/3.2.52/4420_grsecurity-2.9.1-3.2.52-201310292049.patch |
208 |
+++ b/3.2.52/4420_grsecurity-2.9.1-3.2.52-201311021628.patch |
209 |
@@ -485,6 +485,39 @@ index 1dd2c09..6f850c4 100644 |
210 |
$(cmd_crmodverdir) |
211 |
$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ |
212 |
$(build)=$(build-dir) $(@:.ko=.o) |
213 |
+diff --git a/arch/Kconfig b/arch/Kconfig |
214 |
+index 4b0669c..7389b35 100644 |
215 |
+--- a/arch/Kconfig |
216 |
++++ b/arch/Kconfig |
217 |
+@@ -181,4 +181,28 @@ config HAVE_RCU_TABLE_FREE |
218 |
+ config ARCH_HAVE_NMI_SAFE_CMPXCHG |
219 |
+ bool |
220 |
+ |
221 |
++config HAVE_ARCH_SECCOMP_FILTER |
222 |
++ bool |
223 |
++ help |
224 |
++ An arch should select this symbol if it provides all of these things: |
225 |
++ - syscall_get_arch() |
226 |
++ - syscall_get_arguments() |
227 |
++ - syscall_rollback() |
228 |
++ - syscall_set_return_value() |
229 |
++ - SIGSYS siginfo_t support |
230 |
++ - uses __secure_computing_int() or secure_computing() |
231 |
++ - secure_computing is called from a ptrace_event()-safe context |
232 |
++ - secure_computing return value is checked and a return value of -1 |
233 |
++ results in the system call being skipped immediately. |
234 |
++ |
235 |
++config SECCOMP_FILTER |
236 |
++ def_bool y |
237 |
++ depends on HAVE_ARCH_SECCOMP_FILTER && SECCOMP && NET |
238 |
++ help |
239 |
++ Enable tasks to build secure computing environments defined |
240 |
++ in terms of Berkeley Packet Filter programs which implement |
241 |
++ task-defined system call filtering polices. |
242 |
++ |
243 |
++ See Documentation/prctl/seccomp_filter.txt for details. |
244 |
++ |
245 |
+ source "kernel/gcov/Kconfig" |
246 |
diff --git a/arch/alpha/include/asm/atomic.h b/arch/alpha/include/asm/atomic.h |
247 |
index 6f1aca7..fa956e0 100644 |
248 |
--- a/arch/alpha/include/asm/atomic.h |
249 |
@@ -8873,10 +8906,18 @@ index ad8f795..2c7eec6 100644 |
250 |
/* |
251 |
* Memory returned by kmalloc() may be used for DMA, so we must make |
252 |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig |
253 |
-index fb2e69d..9cd4eea 100644 |
254 |
+index fb2e69d..27ff8ca 100644 |
255 |
--- a/arch/x86/Kconfig |
256 |
+++ b/arch/x86/Kconfig |
257 |
-@@ -235,7 +235,7 @@ config X86_HT |
258 |
+@@ -75,6 +75,7 @@ config X86 |
259 |
+ select HAVE_BPF_JIT if (X86_64 && NET) |
260 |
+ select CLKEVT_I8253 |
261 |
+ select ARCH_HAVE_NMI_SAFE_CMPXCHG |
262 |
++ select HAVE_ARCH_SECCOMP_FILTER |
263 |
+ |
264 |
+ config INSTRUCTION_DECODER |
265 |
+ def_bool (KPROBES || PERF_EVENTS) |
266 |
+@@ -235,7 +236,7 @@ config X86_HT |
267 |
|
268 |
config X86_32_LAZY_GS |
269 |
def_bool y |
270 |
@@ -8885,7 +8926,7 @@ index fb2e69d..9cd4eea 100644 |
271 |
|
272 |
config ARCH_HWEIGHT_CFLAGS |
273 |
string |
274 |
-@@ -999,6 +999,7 @@ config MICROCODE_OLD_INTERFACE |
275 |
+@@ -999,6 +1000,7 @@ config MICROCODE_OLD_INTERFACE |
276 |
|
277 |
config X86_MSR |
278 |
tristate "/dev/cpu/*/msr - Model-specific register support" |
279 |
@@ -8893,7 +8934,7 @@ index fb2e69d..9cd4eea 100644 |
280 |
---help--- |
281 |
This device gives privileged processes access to the x86 |
282 |
Model-Specific Registers (MSRs). It is a character device with |
283 |
-@@ -1022,7 +1023,7 @@ choice |
284 |
+@@ -1022,7 +1024,7 @@ choice |
285 |
|
286 |
config NOHIGHMEM |
287 |
bool "off" |
288 |
@@ -8902,7 +8943,7 @@ index fb2e69d..9cd4eea 100644 |
289 |
---help--- |
290 |
Linux can use up to 64 Gigabytes of physical memory on x86 systems. |
291 |
However, the address space of 32-bit x86 processors is only 4 |
292 |
-@@ -1059,7 +1060,7 @@ config NOHIGHMEM |
293 |
+@@ -1059,7 +1061,7 @@ config NOHIGHMEM |
294 |
|
295 |
config HIGHMEM4G |
296 |
bool "4GB" |
297 |
@@ -8911,7 +8952,7 @@ index fb2e69d..9cd4eea 100644 |
298 |
---help--- |
299 |
Select this if you have a 32-bit processor and between 1 and 4 |
300 |
gigabytes of physical RAM. |
301 |
-@@ -1113,7 +1114,7 @@ config PAGE_OFFSET |
302 |
+@@ -1113,7 +1115,7 @@ config PAGE_OFFSET |
303 |
hex |
304 |
default 0xB0000000 if VMSPLIT_3G_OPT |
305 |
default 0x80000000 if VMSPLIT_2G |
306 |
@@ -8920,7 +8961,7 @@ index fb2e69d..9cd4eea 100644 |
307 |
default 0x40000000 if VMSPLIT_1G |
308 |
default 0xC0000000 |
309 |
depends on X86_32 |
310 |
-@@ -1496,6 +1497,7 @@ config SECCOMP |
311 |
+@@ -1496,6 +1498,7 @@ config SECCOMP |
312 |
|
313 |
config CC_STACKPROTECTOR |
314 |
bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" |
315 |
@@ -8928,7 +8969,7 @@ index fb2e69d..9cd4eea 100644 |
316 |
---help--- |
317 |
This option turns on the -fstack-protector GCC feature. This |
318 |
feature puts, at the beginning of functions, a canary value on |
319 |
-@@ -1616,6 +1618,8 @@ config X86_NEED_RELOCS |
320 |
+@@ -1616,6 +1619,8 @@ config X86_NEED_RELOCS |
321 |
config PHYSICAL_ALIGN |
322 |
hex "Alignment value to which kernel should be aligned" if X86_32 |
323 |
default "0x1000000" |
324 |
@@ -8937,7 +8978,7 @@ index fb2e69d..9cd4eea 100644 |
325 |
range 0x2000 0x1000000 |
326 |
---help--- |
327 |
This value puts the alignment restrictions on physical address |
328 |
-@@ -1647,9 +1651,10 @@ config HOTPLUG_CPU |
329 |
+@@ -1647,9 +1652,10 @@ config HOTPLUG_CPU |
330 |
Say N if you want to disable CPU hotplug. |
331 |
|
332 |
config COMPAT_VDSO |
333 |
@@ -9766,10 +9807,21 @@ index fd84387..887aa7e 100644 |
334 |
(unsigned long)create_aout_tables((char __user *)bprm->p, bprm); |
335 |
/* start thread */ |
336 |
diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c |
337 |
-index 6557769..ef6ae89 100644 |
338 |
+index 6557769..dfa8ead 100644 |
339 |
--- a/arch/x86/ia32/ia32_signal.c |
340 |
+++ b/arch/x86/ia32/ia32_signal.c |
341 |
-@@ -169,7 +169,7 @@ asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr, |
342 |
+@@ -73,6 +73,10 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) |
343 |
+ switch (from->si_code >> 16) { |
344 |
+ case __SI_FAULT >> 16: |
345 |
+ break; |
346 |
++ case __SI_SYS >> 16: |
347 |
++ put_user_ex(from->si_syscall, &to->si_syscall); |
348 |
++ put_user_ex(from->si_arch, &to->si_arch); |
349 |
++ break; |
350 |
+ case __SI_CHLD >> 16: |
351 |
+ put_user_ex(from->si_utime, &to->si_utime); |
352 |
+ put_user_ex(from->si_stime, &to->si_stime); |
353 |
+@@ -169,7 +173,7 @@ asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr, |
354 |
} |
355 |
seg = get_fs(); |
356 |
set_fs(KERNEL_DS); |
357 |
@@ -9778,7 +9830,7 @@ index 6557769..ef6ae89 100644 |
358 |
set_fs(seg); |
359 |
if (ret >= 0 && uoss_ptr) { |
360 |
if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_ia32_t))) |
361 |
-@@ -370,7 +370,7 @@ static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, |
362 |
+@@ -370,7 +374,7 @@ static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, |
363 |
*/ |
364 |
static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, |
365 |
size_t frame_size, |
366 |
@@ -9787,7 +9839,7 @@ index 6557769..ef6ae89 100644 |
367 |
{ |
368 |
unsigned long sp; |
369 |
|
370 |
-@@ -391,7 +391,7 @@ static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, |
371 |
+@@ -391,7 +395,7 @@ static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, |
372 |
|
373 |
if (used_math()) { |
374 |
sp = sp - sig_xstate_ia32_size; |
375 |
@@ -9796,7 +9848,7 @@ index 6557769..ef6ae89 100644 |
376 |
if (save_i387_xstate_ia32(*fpstate) < 0) |
377 |
return (void __user *) -1L; |
378 |
} |
379 |
-@@ -399,7 +399,7 @@ static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, |
380 |
+@@ -399,7 +403,7 @@ static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, |
381 |
sp -= frame_size; |
382 |
/* Align the stack pointer according to the i386 ABI, |
383 |
* i.e. so that on function entry ((sp + 4) & 15) == 0. */ |
384 |
@@ -9805,7 +9857,7 @@ index 6557769..ef6ae89 100644 |
385 |
return (void __user *) sp; |
386 |
} |
387 |
|
388 |
-@@ -457,7 +457,7 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka, |
389 |
+@@ -457,7 +461,7 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka, |
390 |
* These are actually not used anymore, but left because some |
391 |
* gdb versions depend on them as a marker. |
392 |
*/ |
393 |
@@ -9814,7 +9866,7 @@ index 6557769..ef6ae89 100644 |
394 |
} put_user_catch(err); |
395 |
|
396 |
if (err) |
397 |
-@@ -499,7 +499,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
398 |
+@@ -499,7 +503,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
399 |
0xb8, |
400 |
__NR_ia32_rt_sigreturn, |
401 |
0x80cd, |
402 |
@@ -9823,7 +9875,7 @@ index 6557769..ef6ae89 100644 |
403 |
}; |
404 |
|
405 |
frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate); |
406 |
-@@ -529,16 +529,18 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
407 |
+@@ -529,16 +533,18 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
408 |
|
409 |
if (ka->sa.sa_flags & SA_RESTORER) |
410 |
restorer = ka->sa.sa_restorer; |
411 |
@@ -11945,6 +11997,23 @@ index a203659..9889f1c 100644 |
412 |
|
413 |
extern struct legacy_pic *legacy_pic; |
414 |
extern struct legacy_pic null_legacy_pic; |
415 |
+diff --git a/arch/x86/include/asm/ia32.h b/arch/x86/include/asm/ia32.h |
416 |
+index 1f7e625..541485f 100644 |
417 |
+--- a/arch/x86/include/asm/ia32.h |
418 |
++++ b/arch/x86/include/asm/ia32.h |
419 |
+@@ -126,6 +126,12 @@ typedef struct compat_siginfo { |
420 |
+ int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ |
421 |
+ int _fd; |
422 |
+ } _sigpoll; |
423 |
++ |
424 |
++ struct { |
425 |
++ unsigned int _call_addr; /* calling insn */ |
426 |
++ int _syscall; /* triggering system call number */ |
427 |
++ unsigned int _arch; /* AUDIT_ARCH_* of syscall */ |
428 |
++ } _sigsys; |
429 |
+ } _sifields; |
430 |
+ } compat_siginfo_t; |
431 |
+ |
432 |
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h |
433 |
index d8e8eef..1765f78 100644 |
434 |
--- a/arch/x86/include/asm/io.h |
435 |
@@ -13832,6 +13901,54 @@ index cb23852..2dde194 100644 |
436 |
asmlinkage long sys32_sysfs(int, u32, u32); |
437 |
|
438 |
asmlinkage long sys32_sched_rr_get_interval(compat_pid_t, |
439 |
+diff --git a/arch/x86/include/asm/syscall.h b/arch/x86/include/asm/syscall.h |
440 |
+index c4a348f..e2ad7ea 100644 |
441 |
+--- a/arch/x86/include/asm/syscall.h |
442 |
++++ b/arch/x86/include/asm/syscall.h |
443 |
+@@ -13,6 +13,7 @@ |
444 |
+ #ifndef _ASM_X86_SYSCALL_H |
445 |
+ #define _ASM_X86_SYSCALL_H |
446 |
+ |
447 |
++#include <linux/audit.h> |
448 |
+ #include <linux/sched.h> |
449 |
+ #include <linux/err.h> |
450 |
+ |
451 |
+@@ -86,6 +87,12 @@ static inline void syscall_set_arguments(struct task_struct *task, |
452 |
+ memcpy(®s->bx + i, args, n * sizeof(args[0])); |
453 |
+ } |
454 |
+ |
455 |
++static inline int syscall_get_arch(struct task_struct *task, |
456 |
++ struct pt_regs *regs) |
457 |
++{ |
458 |
++ return AUDIT_ARCH_I386; |
459 |
++} |
460 |
++ |
461 |
+ #else /* CONFIG_X86_64 */ |
462 |
+ |
463 |
+ static inline void syscall_get_arguments(struct task_struct *task, |
464 |
+@@ -210,6 +217,22 @@ static inline void syscall_set_arguments(struct task_struct *task, |
465 |
+ } |
466 |
+ } |
467 |
+ |
468 |
++static inline int syscall_get_arch(struct task_struct *task, |
469 |
++ struct pt_regs *regs) |
470 |
++{ |
471 |
++#ifdef CONFIG_IA32_EMULATION |
472 |
++ /* |
473 |
++ * TS_COMPAT is set for 32-bit syscall entries and then |
474 |
++ * remains set until we return to user mode. |
475 |
++ * |
476 |
++ * TIF_IA32 tasks should always have TS_COMPAT set at |
477 |
++ * system call time. |
478 |
++ */ |
479 |
++ if (task_thread_info(task)->status & TS_COMPAT) |
480 |
++ return AUDIT_ARCH_I386; |
481 |
++#endif |
482 |
++ return AUDIT_ARCH_X86_64; |
483 |
++} |
484 |
+ #endif /* CONFIG_X86_32 */ |
485 |
+ |
486 |
+ #endif /* _ASM_X86_SYSCALL_H */ |
487 |
diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h |
488 |
index d75adff..c0cc78b 100644 |
489 |
--- a/arch/x86/include/asm/system.h |
490 |
@@ -20676,7 +20793,7 @@ index 6a364a6..b147d11 100644 |
491 |
ip = *(u64 *)(fp+8); |
492 |
if (!in_sched_functions(ip)) |
493 |
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c |
494 |
-index 2dc4121..869e219 100644 |
495 |
+index 2dc4121..60e1086 100644 |
496 |
--- a/arch/x86/kernel/ptrace.c |
497 |
+++ b/arch/x86/kernel/ptrace.c |
498 |
@@ -181,14 +181,13 @@ unsigned long kernel_stack_pointer(struct pt_regs *regs) |
499 |
@@ -20792,7 +20909,28 @@ index 2dc4121..869e219 100644 |
500 |
/* |
501 |
* If we stepped into a sysenter/syscall insn, it trapped in |
502 |
* kernel mode; do_debug() cleared TF and set TIF_SINGLESTEP. |
503 |
-@@ -1443,6 +1451,11 @@ void syscall_trace_leave(struct pt_regs *regs) |
504 |
+@@ -1409,7 +1417,11 @@ long syscall_trace_enter(struct pt_regs *regs) |
505 |
+ regs->flags |= X86_EFLAGS_TF; |
506 |
+ |
507 |
+ /* do the secure computing check first */ |
508 |
+- secure_computing(regs->orig_ax); |
509 |
++ if (secure_computing(regs->orig_ax)) { |
510 |
++ /* seccomp failures shouldn't expose any additional code. */ |
511 |
++ ret = -1L; |
512 |
++ goto out; |
513 |
++ } |
514 |
+ |
515 |
+ if (unlikely(test_thread_flag(TIF_SYSCALL_EMU))) |
516 |
+ ret = -1L; |
517 |
+@@ -1436,6 +1448,7 @@ long syscall_trace_enter(struct pt_regs *regs) |
518 |
+ #endif |
519 |
+ } |
520 |
+ |
521 |
++out: |
522 |
+ return ret ?: regs->orig_ax; |
523 |
+ } |
524 |
+ |
525 |
+@@ -1443,6 +1456,11 @@ void syscall_trace_leave(struct pt_regs *regs) |
526 |
{ |
527 |
bool step; |
528 |
|
529 |
@@ -42476,7 +42614,7 @@ index 2836538..30edf9d 100644 |
530 |
ret = sysfs_create_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr); |
531 |
if (ret) { |
532 |
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c |
533 |
-index 705e13e..91c873c 100644 |
534 |
+index 705e13e..46f4afb 100644 |
535 |
--- a/drivers/scsi/aacraid/linit.c |
536 |
+++ b/drivers/scsi/aacraid/linit.c |
537 |
@@ -93,7 +93,7 @@ static DECLARE_PCI_DEVICE_TABLE(aac_pci_tbl) = { |
538 |
@@ -42488,6 +42626,15 @@ index 705e13e..91c873c 100644 |
539 |
#endif |
540 |
{ 0x1028, 0x0001, 0x1028, 0x0001, 0, 0, 0 }, /* PERC 2/Si (Iguana/PERC2Si) */ |
541 |
{ 0x1028, 0x0002, 0x1028, 0x0002, 0, 0, 1 }, /* PERC 3/Di (Opal/PERC3Di) */ |
542 |
+@@ -771,6 +771,8 @@ static long aac_compat_do_ioctl(struct aac_dev *dev, unsigned cmd, unsigned long |
543 |
+ static int aac_compat_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) |
544 |
+ { |
545 |
+ struct aac_dev *dev = (struct aac_dev *)sdev->host->hostdata; |
546 |
++ if (!capable(CAP_SYS_RAWIO)) |
547 |
++ return -EPERM; |
548 |
+ return aac_compat_do_ioctl(dev, cmd, (unsigned long)arg); |
549 |
+ } |
550 |
+ |
551 |
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c |
552 |
index d5ff142..49c0ebb 100644 |
553 |
--- a/drivers/scsi/aic94xx/aic94xx_init.c |
554 |
@@ -43447,6 +43594,18 @@ index b2ccdea..84cde75 100644 |
555 |
|
556 |
static u8 *buf; |
557 |
|
558 |
+diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c |
559 |
+index 2fa658e..391b768 100644 |
560 |
+--- a/drivers/staging/bcm/Bcmchar.c |
561 |
++++ b/drivers/staging/bcm/Bcmchar.c |
562 |
+@@ -1932,6 +1932,7 @@ cntrlEnd: |
563 |
+ |
564 |
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Called IOCTL_BCM_GET_DEVICE_DRIVER_INFO\n"); |
565 |
+ |
566 |
++ memset(&DevInfo, 0, sizeof(DevInfo)); |
567 |
+ DevInfo.MaxRDMBufferSize = BUFFER_4K; |
568 |
+ DevInfo.u32DSDStartOffset = EEPROM_CALPARAM_START; |
569 |
+ DevInfo.u32RxAlignmentCorrection = 0; |
570 |
diff --git a/drivers/staging/gma500/power.c b/drivers/staging/gma500/power.c |
571 |
index 436fe97..4082570 100644 |
572 |
--- a/drivers/staging/gma500/power.c |
573 |
@@ -43809,6 +43968,59 @@ index df8ea25..47dd9c6 100644 |
574 |
pDevice->apdev->netdev_ops = &apdev_netdev_ops; |
575 |
|
576 |
pDevice->apdev->type = ARPHRD_IEEE80211; |
577 |
+diff --git a/drivers/staging/wlags49_h2/wl_priv.c b/drivers/staging/wlags49_h2/wl_priv.c |
578 |
+index 260d4f0..ed836c2 100644 |
579 |
+--- a/drivers/staging/wlags49_h2/wl_priv.c |
580 |
++++ b/drivers/staging/wlags49_h2/wl_priv.c |
581 |
+@@ -570,6 +570,7 @@ int wvlan_uil_put_info( struct uilreq *urq, struct wl_private *lp ) |
582 |
+ ltv_t *pLtv; |
583 |
+ bool_t ltvAllocated = FALSE; |
584 |
+ ENCSTRCT sEncryption; |
585 |
++ size_t len; |
586 |
+ |
587 |
+ #ifdef USE_WDS |
588 |
+ hcf_16 hcfPort = HCF_PORT_0; |
589 |
+@@ -685,9 +686,10 @@ int wvlan_uil_put_info( struct uilreq *urq, struct wl_private *lp ) |
590 |
+ pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
591 |
+ break; |
592 |
+ case CFG_CNF_OWN_NAME: |
593 |
+- memset( lp->StationName, 0, sizeof( lp->StationName )); |
594 |
+- memcpy( (void *)lp->StationName, (void *)&pLtv->u.u8[2], (size_t)pLtv->u.u16[0]); |
595 |
+- pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
596 |
++ memset(lp->StationName, 0, sizeof(lp->StationName)); |
597 |
++ len = min_t(size_t, pLtv->u.u16[0], sizeof(lp->StationName)); |
598 |
++ strlcpy(lp->StationName, &pLtv->u.u8[2], len); |
599 |
++ pLtv->u.u16[0] = CNV_INT_TO_LITTLE(pLtv->u.u16[0]); |
600 |
+ break; |
601 |
+ case CFG_CNF_LOAD_BALANCING: |
602 |
+ lp->loadBalancing = pLtv->u.u16[0]; |
603 |
+@@ -1798,9 +1800,10 @@ int wvlan_set_station_nickname(struct net_device *dev, |
604 |
+ union iwreq_data *wrqu, |
605 |
+ char *extra) |
606 |
+ { |
607 |
+- struct wl_private *lp = wl_priv(dev); |
608 |
+- unsigned long flags; |
609 |
+- int ret = 0; |
610 |
++ struct wl_private *lp = wl_priv(dev); |
611 |
++ unsigned long flags; |
612 |
++ size_t len; |
613 |
++ int ret = 0; |
614 |
+ /*------------------------------------------------------------------------*/ |
615 |
+ |
616 |
+ |
617 |
+@@ -1809,9 +1812,9 @@ int wvlan_set_station_nickname(struct net_device *dev, |
618 |
+ |
619 |
+ wl_lock(lp, &flags); |
620 |
+ |
621 |
+- memset( lp->StationName, 0, sizeof( lp->StationName )); |
622 |
+- |
623 |
+- memcpy( lp->StationName, extra, wrqu->data.length); |
624 |
++ memset(lp->StationName, 0, sizeof(lp->StationName)); |
625 |
++ len = min_t(size_t, wrqu->data.length, sizeof(lp->StationName)); |
626 |
++ strlcpy(lp->StationName, extra, len); |
627 |
+ |
628 |
+ /* Commit the adapter parameters */ |
629 |
+ wl_apply( lp ); |
630 |
diff --git a/drivers/staging/zcache/tmem.c b/drivers/staging/zcache/tmem.c |
631 |
index 1ca66ea..76f1343 100644 |
632 |
--- a/drivers/staging/zcache/tmem.c |
633 |
@@ -51373,7 +51585,7 @@ index 451b9b8..12e5a03 100644 |
634 |
|
635 |
out_free_fd: |
636 |
diff --git a/fs/exec.c b/fs/exec.c |
637 |
-index a2d0e51..d46efb6 100644 |
638 |
+index a2d0e51..0d1143c 100644 |
639 |
--- a/fs/exec.c |
640 |
+++ b/fs/exec.c |
641 |
@@ -55,12 +55,35 @@ |
642 |
@@ -51760,7 +51972,21 @@ index a2d0e51..d46efb6 100644 |
643 |
|
644 |
/* Set the new mm task size. We have to do that late because it may |
645 |
* depend on TIF_32BIT which is only updated in flush_thread() on |
646 |
-@@ -1268,7 +1347,7 @@ int check_unsafe_exec(struct linux_binprm *bprm) |
647 |
+@@ -1259,6 +1338,13 @@ int check_unsafe_exec(struct linux_binprm *bprm) |
648 |
+ bprm->unsafe |= LSM_UNSAFE_PTRACE; |
649 |
+ } |
650 |
+ |
651 |
++ /* |
652 |
++ * This isn't strictly necessary, but it makes it harder for LSMs to |
653 |
++ * mess up. |
654 |
++ */ |
655 |
++ if (current->no_new_privs) |
656 |
++ bprm->unsafe |= LSM_UNSAFE_NO_NEW_PRIVS; |
657 |
++ |
658 |
+ n_fs = 1; |
659 |
+ spin_lock(&p->fs->lock); |
660 |
+ rcu_read_lock(); |
661 |
+@@ -1268,7 +1354,7 @@ int check_unsafe_exec(struct linux_binprm *bprm) |
662 |
} |
663 |
rcu_read_unlock(); |
664 |
|
665 |
@@ -51769,7 +51995,17 @@ index a2d0e51..d46efb6 100644 |
666 |
bprm->unsafe |= LSM_UNSAFE_SHARE; |
667 |
} else { |
668 |
res = -EAGAIN; |
669 |
-@@ -1463,6 +1542,31 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) |
670 |
+@@ -1302,7 +1388,8 @@ int prepare_binprm(struct linux_binprm *bprm) |
671 |
+ bprm->cred->euid = current_euid(); |
672 |
+ bprm->cred->egid = current_egid(); |
673 |
+ |
674 |
+- if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)) { |
675 |
++ if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) && |
676 |
++ !current->no_new_privs) { |
677 |
+ /* Set-uid? */ |
678 |
+ if (mode & S_ISUID) { |
679 |
+ bprm->per_clear |= PER_CLEAR_ON_SETID; |
680 |
+@@ -1463,6 +1550,31 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) |
681 |
|
682 |
EXPORT_SYMBOL(search_binary_handler); |
683 |
|
684 |
@@ -51801,7 +52037,7 @@ index a2d0e51..d46efb6 100644 |
685 |
/* |
686 |
* sys_execve() executes a new program. |
687 |
*/ |
688 |
-@@ -1471,6 +1575,11 @@ static int do_execve_common(const char *filename, |
689 |
+@@ -1471,6 +1583,11 @@ static int do_execve_common(const char *filename, |
690 |
struct user_arg_ptr envp, |
691 |
struct pt_regs *regs) |
692 |
{ |
693 |
@@ -51813,7 +52049,7 @@ index a2d0e51..d46efb6 100644 |
694 |
struct linux_binprm *bprm; |
695 |
struct file *file; |
696 |
struct files_struct *displaced; |
697 |
-@@ -1478,6 +1587,8 @@ static int do_execve_common(const char *filename, |
698 |
+@@ -1478,6 +1595,8 @@ static int do_execve_common(const char *filename, |
699 |
int retval; |
700 |
const struct cred *cred = current_cred(); |
701 |
|
702 |
@@ -51822,7 +52058,7 @@ index a2d0e51..d46efb6 100644 |
703 |
/* |
704 |
* We move the actual failure in case of RLIMIT_NPROC excess from |
705 |
* set*uid() to execve() because too many poorly written programs |
706 |
-@@ -1518,12 +1629,22 @@ static int do_execve_common(const char *filename, |
707 |
+@@ -1518,12 +1637,22 @@ static int do_execve_common(const char *filename, |
708 |
if (IS_ERR(file)) |
709 |
goto out_unmark; |
710 |
|
711 |
@@ -51845,7 +52081,7 @@ index a2d0e51..d46efb6 100644 |
712 |
retval = bprm_mm_init(bprm); |
713 |
if (retval) |
714 |
goto out_file; |
715 |
-@@ -1540,24 +1661,70 @@ static int do_execve_common(const char *filename, |
716 |
+@@ -1540,24 +1669,70 @@ static int do_execve_common(const char *filename, |
717 |
if (retval < 0) |
718 |
goto out; |
719 |
|
720 |
@@ -51920,7 +52156,7 @@ index a2d0e51..d46efb6 100644 |
721 |
current->fs->in_exec = 0; |
722 |
current->in_execve = 0; |
723 |
acct_update_integrals(current); |
724 |
-@@ -1566,6 +1733,14 @@ static int do_execve_common(const char *filename, |
725 |
+@@ -1566,6 +1741,14 @@ static int do_execve_common(const char *filename, |
726 |
put_files_struct(displaced); |
727 |
return retval; |
728 |
|
729 |
@@ -51935,7 +52171,7 @@ index a2d0e51..d46efb6 100644 |
730 |
out: |
731 |
if (bprm->mm) { |
732 |
acct_arg_size(bprm, 0); |
733 |
-@@ -1639,7 +1814,7 @@ static int expand_corename(struct core_name *cn) |
734 |
+@@ -1639,7 +1822,7 @@ static int expand_corename(struct core_name *cn) |
735 |
{ |
736 |
char *old_corename = cn->corename; |
737 |
|
738 |
@@ -51944,7 +52180,7 @@ index a2d0e51..d46efb6 100644 |
739 |
cn->corename = krealloc(old_corename, cn->size, GFP_KERNEL); |
740 |
|
741 |
if (!cn->corename) { |
742 |
-@@ -1736,7 +1911,7 @@ static int format_corename(struct core_name *cn, long signr) |
743 |
+@@ -1736,7 +1919,7 @@ static int format_corename(struct core_name *cn, long signr) |
744 |
int pid_in_pattern = 0; |
745 |
int err = 0; |
746 |
|
747 |
@@ -51953,7 +52189,7 @@ index a2d0e51..d46efb6 100644 |
748 |
cn->corename = kmalloc(cn->size, GFP_KERNEL); |
749 |
cn->used = 0; |
750 |
|
751 |
-@@ -1833,6 +2008,284 @@ out: |
752 |
+@@ -1833,6 +2016,284 @@ out: |
753 |
return ispipe; |
754 |
} |
755 |
|
756 |
@@ -52238,7 +52474,7 @@ index a2d0e51..d46efb6 100644 |
757 |
static int zap_process(struct task_struct *start, int exit_code) |
758 |
{ |
759 |
struct task_struct *t; |
760 |
-@@ -2006,17 +2459,17 @@ static void coredump_finish(struct mm_struct *mm) |
761 |
+@@ -2006,17 +2467,17 @@ static void coredump_finish(struct mm_struct *mm) |
762 |
void set_dumpable(struct mm_struct *mm, int value) |
763 |
{ |
764 |
switch (value) { |
765 |
@@ -52259,7 +52495,7 @@ index a2d0e51..d46efb6 100644 |
766 |
set_bit(MMF_DUMP_SECURELY, &mm->flags); |
767 |
smp_wmb(); |
768 |
set_bit(MMF_DUMPABLE, &mm->flags); |
769 |
-@@ -2029,7 +2482,7 @@ static int __get_dumpable(unsigned long mm_flags) |
770 |
+@@ -2029,7 +2490,7 @@ static int __get_dumpable(unsigned long mm_flags) |
771 |
int ret; |
772 |
|
773 |
ret = mm_flags & MMF_DUMPABLE_MASK; |
774 |
@@ -52268,7 +52504,7 @@ index a2d0e51..d46efb6 100644 |
775 |
} |
776 |
|
777 |
int get_dumpable(struct mm_struct *mm) |
778 |
-@@ -2044,17 +2497,17 @@ static void wait_for_dump_helpers(struct file *file) |
779 |
+@@ -2044,17 +2505,17 @@ static void wait_for_dump_helpers(struct file *file) |
780 |
pipe = file->f_path.dentry->d_inode->i_pipe; |
781 |
|
782 |
pipe_lock(pipe); |
783 |
@@ -52291,7 +52527,7 @@ index a2d0e51..d46efb6 100644 |
784 |
pipe_unlock(pipe); |
785 |
|
786 |
} |
787 |
-@@ -2115,7 +2568,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
788 |
+@@ -2115,7 +2576,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
789 |
int retval = 0; |
790 |
int flag = 0; |
791 |
int ispipe; |
792 |
@@ -52301,7 +52537,7 @@ index a2d0e51..d46efb6 100644 |
793 |
struct coredump_params cprm = { |
794 |
.signr = signr, |
795 |
.regs = regs, |
796 |
-@@ -2130,6 +2584,9 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
797 |
+@@ -2130,6 +2592,9 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
798 |
|
799 |
audit_core_dumps(signr); |
800 |
|
801 |
@@ -52311,7 +52547,7 @@ index a2d0e51..d46efb6 100644 |
802 |
binfmt = mm->binfmt; |
803 |
if (!binfmt || !binfmt->core_dump) |
804 |
goto fail; |
805 |
-@@ -2140,14 +2597,16 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
806 |
+@@ -2140,14 +2605,16 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
807 |
if (!cred) |
808 |
goto fail; |
809 |
/* |
810 |
@@ -52332,7 +52568,7 @@ index a2d0e51..d46efb6 100644 |
811 |
} |
812 |
|
813 |
retval = coredump_wait(exit_code, &core_state); |
814 |
-@@ -2197,7 +2656,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
815 |
+@@ -2197,7 +2664,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
816 |
} |
817 |
cprm.limit = RLIM_INFINITY; |
818 |
|
819 |
@@ -52341,7 +52577,7 @@ index a2d0e51..d46efb6 100644 |
820 |
if (core_pipe_limit && (core_pipe_limit < dump_count)) { |
821 |
printk(KERN_WARNING "Pid %d(%s) over core_pipe_limit\n", |
822 |
task_tgid_vnr(current), current->comm); |
823 |
-@@ -2224,9 +2683,19 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
824 |
+@@ -2224,9 +2691,19 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
825 |
} else { |
826 |
struct inode *inode; |
827 |
|
828 |
@@ -52361,7 +52597,7 @@ index a2d0e51..d46efb6 100644 |
829 |
cprm.file = filp_open(cn.corename, |
830 |
O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, |
831 |
0600); |
832 |
-@@ -2267,7 +2736,7 @@ close_fail: |
833 |
+@@ -2267,7 +2744,7 @@ close_fail: |
834 |
filp_close(cprm.file, NULL); |
835 |
fail_dropcount: |
836 |
if (ispipe) |
837 |
@@ -52370,7 +52606,7 @@ index a2d0e51..d46efb6 100644 |
838 |
fail_unlock: |
839 |
kfree(cn.corename); |
840 |
fail_corename: |
841 |
-@@ -2286,7 +2755,7 @@ fail: |
842 |
+@@ -2286,7 +2763,7 @@ fail: |
843 |
*/ |
844 |
int dump_write(struct file *file, const void *addr, int nr) |
845 |
{ |
846 |
@@ -70045,6 +70281,93 @@ index bc00876..9aa9b1f 100644 |
847 |
#endif /* CONFIG_MMU */ |
848 |
|
849 |
#endif /* !__ASSEMBLY__ */ |
850 |
+diff --git a/include/asm-generic/siginfo.h b/include/asm-generic/siginfo.h |
851 |
+index 0dd4e87..af5d035 100644 |
852 |
+--- a/include/asm-generic/siginfo.h |
853 |
++++ b/include/asm-generic/siginfo.h |
854 |
+@@ -90,9 +90,18 @@ typedef struct siginfo { |
855 |
+ __ARCH_SI_BAND_T _band; /* POLL_IN, POLL_OUT, POLL_MSG */ |
856 |
+ int _fd; |
857 |
+ } _sigpoll; |
858 |
++ |
859 |
++ /* SIGSYS */ |
860 |
++ struct { |
861 |
++ void __user *_call_addr; /* calling user insn */ |
862 |
++ int _syscall; /* triggering system call number */ |
863 |
++ unsigned int _arch; /* AUDIT_ARCH_* of syscall */ |
864 |
++ } _sigsys; |
865 |
+ } _sifields; |
866 |
+ } siginfo_t; |
867 |
+ |
868 |
++/* If the arch shares siginfo, then it has SIGSYS. */ |
869 |
++#define __ARCH_SIGSYS |
870 |
+ #endif |
871 |
+ |
872 |
+ /* |
873 |
+@@ -116,6 +125,11 @@ typedef struct siginfo { |
874 |
+ #define si_addr_lsb _sifields._sigfault._addr_lsb |
875 |
+ #define si_band _sifields._sigpoll._band |
876 |
+ #define si_fd _sifields._sigpoll._fd |
877 |
++#ifdef __ARCH_SIGSYS |
878 |
++#define si_call_addr _sifields._sigsys._call_addr |
879 |
++#define si_syscall _sifields._sigsys._syscall |
880 |
++#define si_arch _sifields._sigsys._arch |
881 |
++#endif |
882 |
+ |
883 |
+ #ifdef __KERNEL__ |
884 |
+ #define __SI_MASK 0xffff0000u |
885 |
+@@ -126,6 +140,7 @@ typedef struct siginfo { |
886 |
+ #define __SI_CHLD (4 << 16) |
887 |
+ #define __SI_RT (5 << 16) |
888 |
+ #define __SI_MESGQ (6 << 16) |
889 |
++#define __SI_SYS (7 << 16) |
890 |
+ #define __SI_CODE(T,N) ((T) | ((N) & 0xffff)) |
891 |
+ #else |
892 |
+ #define __SI_KILL 0 |
893 |
+@@ -135,6 +150,7 @@ typedef struct siginfo { |
894 |
+ #define __SI_CHLD 0 |
895 |
+ #define __SI_RT 0 |
896 |
+ #define __SI_MESGQ 0 |
897 |
++#define __SI_SYS 0 |
898 |
+ #define __SI_CODE(T,N) (N) |
899 |
+ #endif |
900 |
+ |
901 |
+@@ -232,6 +248,12 @@ typedef struct siginfo { |
902 |
+ #define NSIGPOLL 6 |
903 |
+ |
904 |
+ /* |
905 |
++ * SIGSYS si_codes |
906 |
++ */ |
907 |
++#define SYS_SECCOMP (__SI_SYS|1) /* seccomp triggered */ |
908 |
++#define NSIGSYS 1 |
909 |
++ |
910 |
++/* |
911 |
+ * sigevent definitions |
912 |
+ * |
913 |
+ * It seems likely that SIGEV_THREAD will have to be handled from |
914 |
+diff --git a/include/asm-generic/syscall.h b/include/asm-generic/syscall.h |
915 |
+index 5c122ae..a2c13dc 100644 |
916 |
+--- a/include/asm-generic/syscall.h |
917 |
++++ b/include/asm-generic/syscall.h |
918 |
+@@ -142,4 +142,18 @@ void syscall_set_arguments(struct task_struct *task, struct pt_regs *regs, |
919 |
+ unsigned int i, unsigned int n, |
920 |
+ const unsigned long *args); |
921 |
+ |
922 |
++/** |
923 |
++ * syscall_get_arch - return the AUDIT_ARCH for the current system call |
924 |
++ * @task: task of interest, must be in system call entry tracing |
925 |
++ * @regs: task_pt_regs() of @task |
926 |
++ * |
927 |
++ * Returns the AUDIT_ARCH_* based on the system call convention in use. |
928 |
++ * |
929 |
++ * It's only valid to call this when @task is stopped on entry to a system |
930 |
++ * call, due to %TIF_SYSCALL_TRACE, %TIF_SYSCALL_AUDIT, or %TIF_SECCOMP. |
931 |
++ * |
932 |
++ * Note, at present this function is only required with |
933 |
++ * CONFIG_HAVE_ARCH_SECCOMP_FILTER. |
934 |
++ */ |
935 |
++int syscall_get_arch(struct task_struct *task, struct pt_regs *regs); |
936 |
+ #endif /* _ASM_SYSCALL_H */ |
937 |
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h |
938 |
index b5e2e4c..6a5373e 100644 |
939 |
--- a/include/asm-generic/vmlinux.lds.h |
940 |
@@ -70207,6 +70530,18 @@ index 26c1f78..6722682 100644 |
941 |
|
942 |
/** |
943 |
* struct ttm_mem_global - Global memory accounting structure. |
944 |
+diff --git a/include/linux/Kbuild b/include/linux/Kbuild |
945 |
+index a3ce901..fd50c75 100644 |
946 |
+--- a/include/linux/Kbuild |
947 |
++++ b/include/linux/Kbuild |
948 |
+@@ -329,6 +329,7 @@ header-y += scc.h |
949 |
+ header-y += sched.h |
950 |
+ header-y += screen_info.h |
951 |
+ header-y += sdla.h |
952 |
++header-y += seccomp.h |
953 |
+ header-y += securebits.h |
954 |
+ header-y += selinux_netlink.h |
955 |
+ header-y += sem.h |
956 |
diff --git a/include/linux/a.out.h b/include/linux/a.out.h |
957 |
index e86dfca..40cc55f 100644 |
958 |
--- a/include/linux/a.out.h |
959 |
@@ -70248,6 +70583,40 @@ index 49a83ca..d0a847e 100644 |
960 |
|
961 |
struct atmphy_ops { |
962 |
int (*start)(struct atm_dev *dev); |
963 |
+diff --git a/include/linux/audit.h b/include/linux/audit.h |
964 |
+index 2f81c6f..225b4e4 100644 |
965 |
+--- a/include/linux/audit.h |
966 |
++++ b/include/linux/audit.h |
967 |
+@@ -430,6 +430,7 @@ extern void audit_putname(const char *name); |
968 |
+ extern void __audit_inode(const char *name, const struct dentry *dentry); |
969 |
+ extern void __audit_inode_child(const struct dentry *dentry, |
970 |
+ const struct inode *parent); |
971 |
++extern void __audit_seccomp(unsigned long syscall, long signr, int code); |
972 |
+ extern void __audit_ptrace(struct task_struct *t); |
973 |
+ |
974 |
+ static inline int audit_dummy_context(void) |
975 |
+@@ -453,6 +454,12 @@ static inline void audit_inode_child(const struct dentry *dentry, |
976 |
+ } |
977 |
+ void audit_core_dumps(long signr); |
978 |
+ |
979 |
++static inline void audit_seccomp(unsigned long syscall, long signr, int code) |
980 |
++{ |
981 |
++ if (unlikely(!audit_dummy_context())) |
982 |
++ __audit_seccomp(syscall, signr, code); |
983 |
++} |
984 |
++ |
985 |
+ static inline void audit_ptrace(struct task_struct *t) |
986 |
+ { |
987 |
+ if (unlikely(!audit_dummy_context())) |
988 |
+@@ -558,6 +565,8 @@ extern int audit_signals; |
989 |
+ #define audit_inode(n,d) do { (void)(d); } while (0) |
990 |
+ #define audit_inode_child(i,p) do { ; } while (0) |
991 |
+ #define audit_core_dumps(i) do { ; } while (0) |
992 |
++#define audit_seccomp(i,s,c) do { ; } while (0) |
993 |
++#define __audit_seccomp(i,s,c) do { ; } while (0) |
994 |
+ #define auditsc_get_stamp(c,t,s) (0) |
995 |
+ #define audit_get_loginuid(t) (-1) |
996 |
+ #define audit_get_sessionid(t) (-1) |
997 |
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h |
998 |
index acd8d4b..f2defe2 100644 |
999 |
--- a/include/linux/binfmts.h |
1000 |
@@ -71053,18 +71422,38 @@ index 82163c4..c4b3b50 100644 |
1001 |
extern struct kmem_cache *files_cachep; |
1002 |
|
1003 |
diff --git a/include/linux/filter.h b/include/linux/filter.h |
1004 |
-index 8eeb205..d59bfa2 100644 |
1005 |
+index 8eeb205..13d571c 100644 |
1006 |
--- a/include/linux/filter.h |
1007 |
+++ b/include/linux/filter.h |
1008 |
-@@ -134,6 +134,7 @@ struct sock_fprog { /* Required for SO_ATTACH_FILTER. */ |
1009 |
+@@ -10,6 +10,7 @@ |
1010 |
|
1011 |
+ #ifdef __KERNEL__ |
1012 |
+ #include <linux/atomic.h> |
1013 |
++#include <linux/compat.h> |
1014 |
+ #endif |
1015 |
+ |
1016 |
+ /* |
1017 |
+@@ -132,8 +133,19 @@ struct sock_fprog { /* Required for SO_ATTACH_FILTER. */ |
1018 |
+ |
1019 |
+ #ifdef __KERNEL__ |
1020 |
+ |
1021 |
++#ifdef CONFIG_COMPAT |
1022 |
++/* |
1023 |
++ * A struct sock_filter is architecture independent. |
1024 |
++ */ |
1025 |
++struct compat_sock_fprog { |
1026 |
++ u16 len; |
1027 |
++ compat_uptr_t filter; /* struct sock_filter * */ |
1028 |
++}; |
1029 |
++#endif |
1030 |
++ |
1031 |
struct sk_buff; |
1032 |
struct sock; |
1033 |
+struct bpf_jit_work; |
1034 |
|
1035 |
struct sk_filter |
1036 |
{ |
1037 |
-@@ -141,6 +142,9 @@ struct sk_filter |
1038 |
+@@ -141,6 +153,9 @@ struct sk_filter |
1039 |
unsigned int len; /* Number of filter blocks */ |
1040 |
unsigned int (*bpf_func)(const struct sk_buff *skb, |
1041 |
const struct sock_filter *filter); |
1042 |
@@ -71074,6 +71463,14 @@ index 8eeb205..d59bfa2 100644 |
1043 |
struct rcu_head rcu; |
1044 |
struct sock_filter insns[0]; |
1045 |
}; |
1046 |
+@@ -228,6 +243,7 @@ enum { |
1047 |
+ BPF_S_ANC_HATYPE, |
1048 |
+ BPF_S_ANC_RXHASH, |
1049 |
+ BPF_S_ANC_CPU, |
1050 |
++ BPF_S_ANC_SECCOMP_LD_W, |
1051 |
+ }; |
1052 |
+ |
1053 |
+ #endif /* __KERNEL__ */ |
1054 |
diff --git a/include/linux/fs.h b/include/linux/fs.h |
1055 |
index a276817..ba31358 100644 |
1056 |
--- a/include/linux/fs.h |
1057 |
@@ -73967,6 +74364,30 @@ index b8d4ddd..bb59d8b 100644 |
1058 |
|
1059 |
/* |
1060 |
* The return value from decompress routine is the length of the |
1061 |
+diff --git a/include/linux/prctl.h b/include/linux/prctl.h |
1062 |
+index a3baeb2..b527252 100644 |
1063 |
+--- a/include/linux/prctl.h |
1064 |
++++ b/include/linux/prctl.h |
1065 |
+@@ -102,4 +102,19 @@ |
1066 |
+ |
1067 |
+ #define PR_MCE_KILL_GET 34 |
1068 |
+ |
1069 |
++/* |
1070 |
++ * If no_new_privs is set, then operations that grant new privileges (i.e. |
1071 |
++ * execve) will either fail or not grant them. This affects suid/sgid, |
1072 |
++ * file capabilities, and LSMs. |
1073 |
++ * |
1074 |
++ * Operations that merely manipulate or drop existing privileges (setresuid, |
1075 |
++ * capset, etc.) will still work. Drop those privileges if you want them gone. |
1076 |
++ * |
1077 |
++ * Changing LSM security domain is considered a new privilege. So, for example, |
1078 |
++ * asking selinux for a specific new context (e.g. with runcon) will result |
1079 |
++ * in execve returning -EPERM. |
1080 |
++ */ |
1081 |
++#define PR_SET_NO_NEW_PRIVS 38 |
1082 |
++#define PR_GET_NO_NEW_PRIVS 39 |
1083 |
++ |
1084 |
+ #endif /* _LINUX_PRCTL_H */ |
1085 |
diff --git a/include/linux/printk.h b/include/linux/printk.h |
1086 |
index f0e22f7..82dd544 100644 |
1087 |
--- a/include/linux/printk.h |
1088 |
@@ -74022,10 +74443,40 @@ index 643b96c..9544c71 100644 |
1089 |
extern const struct proc_ns_operations utsns_operations; |
1090 |
extern const struct proc_ns_operations ipcns_operations; |
1091 |
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h |
1092 |
-index 800f113..12c82ec 100644 |
1093 |
+index 800f113..13b3715 100644 |
1094 |
--- a/include/linux/ptrace.h |
1095 |
+++ b/include/linux/ptrace.h |
1096 |
-@@ -129,10 +129,12 @@ extern void __ptrace_unlink(struct task_struct *child); |
1097 |
+@@ -62,8 +62,9 @@ |
1098 |
+ #define PTRACE_O_TRACEEXEC 0x00000010 |
1099 |
+ #define PTRACE_O_TRACEVFORKDONE 0x00000020 |
1100 |
+ #define PTRACE_O_TRACEEXIT 0x00000040 |
1101 |
++#define PTRACE_O_TRACESECCOMP 0x00000080 |
1102 |
+ |
1103 |
+-#define PTRACE_O_MASK 0x0000007f |
1104 |
++#define PTRACE_O_MASK 0x000000ff |
1105 |
+ |
1106 |
+ /* Wait extended result codes for the above trace options. */ |
1107 |
+ #define PTRACE_EVENT_FORK 1 |
1108 |
+@@ -73,6 +74,7 @@ |
1109 |
+ #define PTRACE_EVENT_VFORK_DONE 5 |
1110 |
+ #define PTRACE_EVENT_EXIT 6 |
1111 |
+ #define PTRACE_EVENT_STOP 7 |
1112 |
++#define PTRACE_EVENT_SECCOMP 8 |
1113 |
+ |
1114 |
+ #include <asm/ptrace.h> |
1115 |
+ |
1116 |
+@@ -101,8 +103,9 @@ |
1117 |
+ #define PT_TRACE_EXEC PT_EVENT_FLAG(PTRACE_EVENT_EXEC) |
1118 |
+ #define PT_TRACE_VFORK_DONE PT_EVENT_FLAG(PTRACE_EVENT_VFORK_DONE) |
1119 |
+ #define PT_TRACE_EXIT PT_EVENT_FLAG(PTRACE_EVENT_EXIT) |
1120 |
++#define PT_TRACE_SECCOMP PT_EVENT_FLAG(PTRACE_EVENT_SECCOMP) |
1121 |
+ |
1122 |
+-#define PT_TRACE_MASK 0x000003f4 |
1123 |
++#define PT_TRACE_MASK 0x00000bf4 |
1124 |
+ |
1125 |
+ /* single stepping state bits (used on ARM and PA-RISC) */ |
1126 |
+ #define PT_SINGLESTEP_BIT 31 |
1127 |
+@@ -129,10 +132,12 @@ extern void __ptrace_unlink(struct task_struct *child); |
1128 |
extern void exit_ptrace(struct task_struct *tracer); |
1129 |
#define PTRACE_MODE_READ 1 |
1130 |
#define PTRACE_MODE_ATTACH 2 |
1131 |
@@ -74040,7 +74491,7 @@ index 800f113..12c82ec 100644 |
1132 |
|
1133 |
static inline int ptrace_reparented(struct task_struct *child) |
1134 |
{ |
1135 |
-@@ -197,9 +199,10 @@ static inline void ptrace_event(int event, unsigned long message) |
1136 |
+@@ -197,9 +202,10 @@ static inline void ptrace_event(int event, unsigned long message) |
1137 |
if (unlikely(ptrace_event_enabled(current, event))) { |
1138 |
current->ptrace_message = message; |
1139 |
ptrace_notify((event << 8) | SIGTRAP); |
1140 |
@@ -74267,7 +74718,7 @@ index 2148b12..519b820 100644 |
1141 |
|
1142 |
static inline void anon_vma_merge(struct vm_area_struct *vma, |
1143 |
diff --git a/include/linux/sched.h b/include/linux/sched.h |
1144 |
-index 8204898..76f518d 100644 |
1145 |
+index 8204898..070429f 100644 |
1146 |
--- a/include/linux/sched.h |
1147 |
+++ b/include/linux/sched.h |
1148 |
@@ -101,6 +101,7 @@ struct bio_list; |
1149 |
@@ -74365,7 +74816,16 @@ index 8204898..76f518d 100644 |
1150 |
|
1151 |
struct load_weight { |
1152 |
unsigned long weight, inv_weight; |
1153 |
-@@ -1341,8 +1379,8 @@ struct task_struct { |
1154 |
+@@ -1301,6 +1339,8 @@ struct task_struct { |
1155 |
+ * execve */ |
1156 |
+ unsigned in_iowait:1; |
1157 |
+ |
1158 |
++ /* task may not gain privileges */ |
1159 |
++ unsigned no_new_privs:1; |
1160 |
+ |
1161 |
+ /* Revert to default priority/policy when forking */ |
1162 |
+ unsigned sched_reset_on_fork:1; |
1163 |
+@@ -1341,8 +1381,8 @@ struct task_struct { |
1164 |
struct list_head thread_group; |
1165 |
|
1166 |
struct completion *vfork_done; /* for vfork() */ |
1167 |
@@ -74376,7 +74836,7 @@ index 8204898..76f518d 100644 |
1168 |
|
1169 |
cputime_t utime, stime, utimescaled, stimescaled; |
1170 |
cputime_t gtime; |
1171 |
-@@ -1358,13 +1396,6 @@ struct task_struct { |
1172 |
+@@ -1358,13 +1398,6 @@ struct task_struct { |
1173 |
struct task_cputime cputime_expires; |
1174 |
struct list_head cpu_timers[3]; |
1175 |
|
1176 |
@@ -74390,7 +74850,7 @@ index 8204898..76f518d 100644 |
1177 |
char comm[TASK_COMM_LEN]; /* executable name excluding path |
1178 |
- access with [gs]et_task_comm (which lock |
1179 |
it with task_lock()) |
1180 |
-@@ -1381,8 +1412,16 @@ struct task_struct { |
1181 |
+@@ -1381,8 +1414,16 @@ struct task_struct { |
1182 |
#endif |
1183 |
/* CPU-specific state of this task */ |
1184 |
struct thread_struct thread; |
1185 |
@@ -74407,7 +74867,16 @@ index 8204898..76f518d 100644 |
1186 |
/* open file information */ |
1187 |
struct files_struct *files; |
1188 |
/* namespaces */ |
1189 |
-@@ -1429,6 +1468,11 @@ struct task_struct { |
1190 |
+@@ -1405,7 +1446,7 @@ struct task_struct { |
1191 |
+ uid_t loginuid; |
1192 |
+ unsigned int sessionid; |
1193 |
+ #endif |
1194 |
+- seccomp_t seccomp; |
1195 |
++ struct seccomp seccomp; |
1196 |
+ |
1197 |
+ /* Thread group tracking */ |
1198 |
+ u32 parent_exec_id; |
1199 |
+@@ -1429,6 +1470,11 @@ struct task_struct { |
1200 |
struct rt_mutex_waiter *pi_blocked_on; |
1201 |
#endif |
1202 |
|
1203 |
@@ -74419,7 +74888,7 @@ index 8204898..76f518d 100644 |
1204 |
#ifdef CONFIG_DEBUG_MUTEXES |
1205 |
/* mutex deadlock detection */ |
1206 |
struct mutex_waiter *blocked_on; |
1207 |
-@@ -1544,6 +1588,28 @@ struct task_struct { |
1208 |
+@@ -1544,6 +1590,28 @@ struct task_struct { |
1209 |
unsigned long default_timer_slack_ns; |
1210 |
|
1211 |
struct list_head *scm_work_list; |
1212 |
@@ -74448,7 +74917,7 @@ index 8204898..76f518d 100644 |
1213 |
#ifdef CONFIG_FUNCTION_GRAPH_TRACER |
1214 |
/* Index of current stored address in ret_stack */ |
1215 |
int curr_ret_stack; |
1216 |
-@@ -1578,6 +1644,52 @@ struct task_struct { |
1217 |
+@@ -1578,6 +1646,52 @@ struct task_struct { |
1218 |
#endif |
1219 |
}; |
1220 |
|
1221 |
@@ -74501,7 +74970,7 @@ index 8204898..76f518d 100644 |
1222 |
/* Future-safe accessor for struct task_struct's cpus_allowed. */ |
1223 |
#define tsk_cpus_allowed(tsk) (&(tsk)->cpus_allowed) |
1224 |
|
1225 |
-@@ -2093,7 +2205,9 @@ void yield(void); |
1226 |
+@@ -2093,7 +2207,9 @@ void yield(void); |
1227 |
extern struct exec_domain default_exec_domain; |
1228 |
|
1229 |
union thread_union { |
1230 |
@@ -74511,7 +74980,7 @@ index 8204898..76f518d 100644 |
1231 |
unsigned long stack[THREAD_SIZE/sizeof(long)]; |
1232 |
}; |
1233 |
|
1234 |
-@@ -2126,6 +2240,7 @@ extern struct pid_namespace init_pid_ns; |
1235 |
+@@ -2126,6 +2242,7 @@ extern struct pid_namespace init_pid_ns; |
1236 |
*/ |
1237 |
|
1238 |
extern struct task_struct *find_task_by_vpid(pid_t nr); |
1239 |
@@ -74519,7 +74988,7 @@ index 8204898..76f518d 100644 |
1240 |
extern struct task_struct *find_task_by_pid_ns(pid_t nr, |
1241 |
struct pid_namespace *ns); |
1242 |
|
1243 |
-@@ -2247,6 +2362,12 @@ static inline void mmdrop(struct mm_struct * mm) |
1244 |
+@@ -2247,6 +2364,12 @@ static inline void mmdrop(struct mm_struct * mm) |
1245 |
extern void mmput(struct mm_struct *); |
1246 |
/* Grab a reference to a task's mm, if it is not already going away */ |
1247 |
extern struct mm_struct *get_task_mm(struct task_struct *task); |
1248 |
@@ -74532,7 +75001,7 @@ index 8204898..76f518d 100644 |
1249 |
/* Remove the current tasks stale references to the old mm_struct */ |
1250 |
extern void mm_release(struct task_struct *, struct mm_struct *); |
1251 |
/* Allocate a new mm structure and copy contents from tsk->mm */ |
1252 |
-@@ -2263,7 +2384,7 @@ extern void __cleanup_sighand(struct sighand_struct *); |
1253 |
+@@ -2263,7 +2386,7 @@ extern void __cleanup_sighand(struct sighand_struct *); |
1254 |
extern void exit_itimers(struct signal_struct *); |
1255 |
extern void flush_itimer_signals(void); |
1256 |
|
1257 |
@@ -74541,7 +75010,7 @@ index 8204898..76f518d 100644 |
1258 |
|
1259 |
extern void daemonize(const char *, ...); |
1260 |
extern int allow_signal(int); |
1261 |
-@@ -2428,9 +2549,9 @@ static inline unsigned long *end_of_stack(struct task_struct *p) |
1262 |
+@@ -2428,9 +2551,9 @@ static inline unsigned long *end_of_stack(struct task_struct *p) |
1263 |
|
1264 |
#endif |
1265 |
|
1266 |
@@ -74567,8 +75036,154 @@ index 899fbb4..1cb4138 100644 |
1267 |
} __attribute__((packed)); |
1268 |
|
1269 |
#define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */ |
1270 |
+diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h |
1271 |
+index cc7a4e9..306733e 100644 |
1272 |
+--- a/include/linux/seccomp.h |
1273 |
++++ b/include/linux/seccomp.h |
1274 |
+@@ -1,25 +1,89 @@ |
1275 |
+ #ifndef _LINUX_SECCOMP_H |
1276 |
+ #define _LINUX_SECCOMP_H |
1277 |
+ |
1278 |
++#include <linux/compiler.h> |
1279 |
++#include <linux/types.h> |
1280 |
+ |
1281 |
++ |
1282 |
++/* Valid values for seccomp.mode and prctl(PR_SET_SECCOMP, <mode>) */ |
1283 |
++#define SECCOMP_MODE_DISABLED 0 /* seccomp is not in use. */ |
1284 |
++#define SECCOMP_MODE_STRICT 1 /* uses hard-coded filter. */ |
1285 |
++#define SECCOMP_MODE_FILTER 2 /* uses user-supplied filter. */ |
1286 |
++ |
1287 |
++/* |
1288 |
++ * All BPF programs must return a 32-bit value. |
1289 |
++ * The bottom 16-bits are for optional return data. |
1290 |
++ * The upper 16-bits are ordered from least permissive values to most. |
1291 |
++ * |
1292 |
++ * The ordering ensures that a min_t() over composed return values always |
1293 |
++ * selects the least permissive choice. |
1294 |
++ */ |
1295 |
++#define SECCOMP_RET_KILL 0x00000000U /* kill the task immediately */ |
1296 |
++#define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */ |
1297 |
++#define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */ |
1298 |
++#define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */ |
1299 |
++#define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */ |
1300 |
++ |
1301 |
++/* Masks for the return value sections. */ |
1302 |
++#define SECCOMP_RET_ACTION 0xffff0000U |
1303 |
++#define SECCOMP_RET_DATA 0x0000ffffU |
1304 |
++ |
1305 |
++/** |
1306 |
++ * struct seccomp_data - the format the BPF program executes over. |
1307 |
++ * @nr: the system call number |
1308 |
++ * @arch: indicates system call convention as an AUDIT_ARCH_* value |
1309 |
++ * as defined in <linux/audit.h>. |
1310 |
++ * @instruction_pointer: at the time of the system call. |
1311 |
++ * @args: up to 6 system call arguments always stored as 64-bit values |
1312 |
++ * regardless of the architecture. |
1313 |
++ */ |
1314 |
++struct seccomp_data { |
1315 |
++ int nr; |
1316 |
++ __u32 arch; |
1317 |
++ __u64 instruction_pointer; |
1318 |
++ __u64 args[6]; |
1319 |
++}; |
1320 |
++ |
1321 |
++#ifdef __KERNEL__ |
1322 |
+ #ifdef CONFIG_SECCOMP |
1323 |
+ |
1324 |
+ #include <linux/thread_info.h> |
1325 |
+ #include <asm/seccomp.h> |
1326 |
+ |
1327 |
+-typedef struct { int mode; } seccomp_t; |
1328 |
++struct seccomp_filter; |
1329 |
++/** |
1330 |
++ * struct seccomp - the state of a seccomp'ed process |
1331 |
++ * |
1332 |
++ * @mode: indicates one of the valid values above for controlled |
1333 |
++ * system calls available to a process. |
1334 |
++ * @filter: The metadata and ruleset for determining what system calls |
1335 |
++ * are allowed for a task. |
1336 |
++ * |
1337 |
++ * @filter must only be accessed from the context of current as there |
1338 |
++ * is no locking. |
1339 |
++ */ |
1340 |
++struct seccomp { |
1341 |
++ int mode; |
1342 |
++ struct seccomp_filter *filter; |
1343 |
++}; |
1344 |
+ |
1345 |
+-extern void __secure_computing(int); |
1346 |
+-static inline void secure_computing(int this_syscall) |
1347 |
++/* |
1348 |
++ * Direct callers to __secure_computing should be updated as |
1349 |
++ * CONFIG_HAVE_ARCH_SECCOMP_FILTER propagates. |
1350 |
++ */ |
1351 |
++extern void __secure_computing(int) __deprecated; |
1352 |
++extern int __secure_computing_int(int); |
1353 |
++static inline int secure_computing(int this_syscall) |
1354 |
+ { |
1355 |
+ if (unlikely(test_thread_flag(TIF_SECCOMP))) |
1356 |
+- __secure_computing(this_syscall); |
1357 |
++ return __secure_computing_int(this_syscall); |
1358 |
++ return 0; |
1359 |
+ } |
1360 |
+ |
1361 |
+ extern long prctl_get_seccomp(void); |
1362 |
+-extern long prctl_set_seccomp(unsigned long); |
1363 |
++extern long prctl_set_seccomp(unsigned long, char __user *); |
1364 |
+ |
1365 |
+-static inline int seccomp_mode(seccomp_t *s) |
1366 |
++static inline int seccomp_mode(struct seccomp *s) |
1367 |
+ { |
1368 |
+ return s->mode; |
1369 |
+ } |
1370 |
+@@ -28,25 +92,40 @@ static inline int seccomp_mode(seccomp_t *s) |
1371 |
+ |
1372 |
+ #include <linux/errno.h> |
1373 |
+ |
1374 |
+-typedef struct { } seccomp_t; |
1375 |
++struct seccomp { }; |
1376 |
++struct seccomp_filter { }; |
1377 |
+ |
1378 |
+-#define secure_computing(x) do { } while (0) |
1379 |
++#define secure_computing(x) 0 |
1380 |
+ |
1381 |
+ static inline long prctl_get_seccomp(void) |
1382 |
+ { |
1383 |
+ return -EINVAL; |
1384 |
+ } |
1385 |
+ |
1386 |
+-static inline long prctl_set_seccomp(unsigned long arg2) |
1387 |
++static inline long prctl_set_seccomp(unsigned long arg2, char __user *arg3) |
1388 |
+ { |
1389 |
+ return -EINVAL; |
1390 |
+ } |
1391 |
+ |
1392 |
+-static inline int seccomp_mode(seccomp_t *s) |
1393 |
++static inline int seccomp_mode(struct seccomp *s) |
1394 |
+ { |
1395 |
+ return 0; |
1396 |
+ } |
1397 |
+- |
1398 |
+ #endif /* CONFIG_SECCOMP */ |
1399 |
+ |
1400 |
++#ifdef CONFIG_SECCOMP_FILTER |
1401 |
++extern void put_seccomp_filter(struct task_struct *tsk); |
1402 |
++extern void get_seccomp_filter(struct task_struct *tsk); |
1403 |
++extern u32 seccomp_bpf_load(int off); |
1404 |
++#else /* CONFIG_SECCOMP_FILTER */ |
1405 |
++static inline void put_seccomp_filter(struct task_struct *tsk) |
1406 |
++{ |
1407 |
++ return; |
1408 |
++} |
1409 |
++static inline void get_seccomp_filter(struct task_struct *tsk) |
1410 |
++{ |
1411 |
++ return; |
1412 |
++} |
1413 |
++#endif /* CONFIG_SECCOMP_FILTER */ |
1414 |
++#endif /* __KERNEL__ */ |
1415 |
+ #endif /* _LINUX_SECCOMP_H */ |
1416 |
diff --git a/include/linux/security.h b/include/linux/security.h |
1417 |
-index e8c619d..ff41b06 100644 |
1418 |
+index e8c619d..99d0f1f 100644 |
1419 |
--- a/include/linux/security.h |
1420 |
+++ b/include/linux/security.h |
1421 |
@@ -37,6 +37,7 @@ |
1422 |
@@ -74588,7 +75203,15 @@ index e8c619d..ff41b06 100644 |
1423 |
#ifdef CONFIG_MMU |
1424 |
extern unsigned long mmap_min_addr; |
1425 |
extern unsigned long dac_mmap_min_addr; |
1426 |
-@@ -1676,6 +1675,8 @@ int security_capset(struct cred *new, const struct cred *old, |
1427 |
+@@ -130,6 +129,7 @@ struct request_sock; |
1428 |
+ #define LSM_UNSAFE_SHARE 1 |
1429 |
+ #define LSM_UNSAFE_PTRACE 2 |
1430 |
+ #define LSM_UNSAFE_PTRACE_CAP 4 |
1431 |
++#define LSM_UNSAFE_NO_NEW_PRIVS 8 |
1432 |
+ |
1433 |
+ #ifdef CONFIG_MMU |
1434 |
+ /* |
1435 |
+@@ -1676,6 +1676,8 @@ int security_capset(struct cred *new, const struct cred *old, |
1436 |
const kernel_cap_t *permitted); |
1437 |
int security_capable(struct user_namespace *ns, const struct cred *cred, |
1438 |
int cap); |
1439 |
@@ -74597,7 +75220,7 @@ index e8c619d..ff41b06 100644 |
1440 |
int security_real_capable(struct task_struct *tsk, struct user_namespace *ns, |
1441 |
int cap); |
1442 |
int security_real_capable_noaudit(struct task_struct *tsk, |
1443 |
-@@ -1880,6 +1881,12 @@ static inline int security_capable(struct user_namespace *ns, |
1444 |
+@@ -1880,6 +1882,12 @@ static inline int security_capable(struct user_namespace *ns, |
1445 |
return cap_capable(current, cred, ns, cap, SECURITY_CAP_AUDIT); |
1446 |
} |
1447 |
|
1448 |
@@ -77495,10 +78118,18 @@ index d4bc594..efa193f 100644 |
1449 |
return; |
1450 |
} |
1451 |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c |
1452 |
-index 47b7fc1..c003c33 100644 |
1453 |
+index 47b7fc1..9af0605 100644 |
1454 |
--- a/kernel/auditsc.c |
1455 |
+++ b/kernel/auditsc.c |
1456 |
-@@ -1166,8 +1166,8 @@ static void audit_log_execve_info(struct audit_context *context, |
1457 |
+@@ -67,6 +67,7 @@ |
1458 |
+ #include <linux/syscalls.h> |
1459 |
+ #include <linux/capability.h> |
1460 |
+ #include <linux/fs_struct.h> |
1461 |
++#include <linux/compat.h> |
1462 |
+ |
1463 |
+ #include "audit.h" |
1464 |
+ |
1465 |
+@@ -1166,8 +1167,8 @@ static void audit_log_execve_info(struct audit_context *context, |
1466 |
struct audit_buffer **ab, |
1467 |
struct audit_aux_data_execve *axi) |
1468 |
{ |
1469 |
@@ -77509,7 +78140,7 @@ index 47b7fc1..c003c33 100644 |
1470 |
const char __user *p; |
1471 |
char *buf; |
1472 |
|
1473 |
-@@ -2118,7 +2118,7 @@ int auditsc_get_stamp(struct audit_context *ctx, |
1474 |
+@@ -2118,7 +2119,7 @@ int auditsc_get_stamp(struct audit_context *ctx, |
1475 |
} |
1476 |
|
1477 |
/* global counter which is incremented every time something logs in */ |
1478 |
@@ -77518,7 +78149,7 @@ index 47b7fc1..c003c33 100644 |
1479 |
|
1480 |
/** |
1481 |
* audit_set_loginuid - set a task's audit_context loginuid |
1482 |
-@@ -2131,7 +2131,7 @@ static atomic_t session_id = ATOMIC_INIT(0); |
1483 |
+@@ -2131,7 +2132,7 @@ static atomic_t session_id = ATOMIC_INIT(0); |
1484 |
*/ |
1485 |
int audit_set_loginuid(struct task_struct *task, uid_t loginuid) |
1486 |
{ |
1487 |
@@ -77527,6 +78158,97 @@ index 47b7fc1..c003c33 100644 |
1488 |
struct audit_context *context = task->audit_context; |
1489 |
|
1490 |
if (context && context->in_syscall) { |
1491 |
+@@ -2499,46 +2500,59 @@ void __audit_mmap_fd(int fd, int flags) |
1492 |
+ context->type = AUDIT_MMAP; |
1493 |
+ } |
1494 |
+ |
1495 |
+-/** |
1496 |
+- * audit_core_dumps - record information about processes that end abnormally |
1497 |
+- * @signr: signal value |
1498 |
+- * |
1499 |
+- * If a process ends with a core dump, something fishy is going on and we |
1500 |
+- * should record the event for investigation. |
1501 |
+- */ |
1502 |
+-void audit_core_dumps(long signr) |
1503 |
++static void audit_log_abend(struct audit_buffer *ab, char *reason, long signr) |
1504 |
+ { |
1505 |
+- struct audit_buffer *ab; |
1506 |
+- u32 sid; |
1507 |
+- uid_t auid = audit_get_loginuid(current), uid; |
1508 |
++ uid_t auid, uid; |
1509 |
+ gid_t gid; |
1510 |
+- unsigned int sessionid = audit_get_sessionid(current); |
1511 |
++ unsigned int sessionid; |
1512 |
+ |
1513 |
+- if (!audit_enabled) |
1514 |
+- return; |
1515 |
+- |
1516 |
+- if (signr == SIGQUIT) /* don't care for those */ |
1517 |
+- return; |
1518 |
+- |
1519 |
+- ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); |
1520 |
++ auid = audit_get_loginuid(current); |
1521 |
++ sessionid = audit_get_sessionid(current); |
1522 |
+ current_uid_gid(&uid, &gid); |
1523 |
++ |
1524 |
+ audit_log_format(ab, "auid=%u uid=%u gid=%u ses=%u", |
1525 |
+ auid, uid, gid, sessionid); |
1526 |
+- security_task_getsecid(current, &sid); |
1527 |
+- if (sid) { |
1528 |
+- char *ctx = NULL; |
1529 |
+- u32 len; |
1530 |
+- |
1531 |
+- if (security_secid_to_secctx(sid, &ctx, &len)) |
1532 |
+- audit_log_format(ab, " ssid=%u", sid); |
1533 |
+- else { |
1534 |
+- audit_log_format(ab, " subj=%s", ctx); |
1535 |
+- security_release_secctx(ctx, len); |
1536 |
+- } |
1537 |
+- } |
1538 |
++ audit_log_task_context(ab); |
1539 |
+ audit_log_format(ab, " pid=%d comm=", current->pid); |
1540 |
+ audit_log_untrustedstring(ab, current->comm); |
1541 |
++ audit_log_format(ab, " reason="); |
1542 |
++ audit_log_string(ab, reason); |
1543 |
+ audit_log_format(ab, " sig=%ld", signr); |
1544 |
++} |
1545 |
++/** |
1546 |
++ * audit_core_dumps - record information about processes that end abnormally |
1547 |
++ * @signr: signal value |
1548 |
++ * |
1549 |
++ * If a process ends with a core dump, something fishy is going on and we |
1550 |
++ * should record the event for investigation. |
1551 |
++ */ |
1552 |
++void audit_core_dumps(long signr) |
1553 |
++{ |
1554 |
++ struct audit_buffer *ab; |
1555 |
++ |
1556 |
++ if (!audit_enabled) |
1557 |
++ return; |
1558 |
++ |
1559 |
++ if (signr == SIGQUIT) /* don't care for those */ |
1560 |
++ return; |
1561 |
++ |
1562 |
++ ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); |
1563 |
++ audit_log_abend(ab, "memory violation", signr); |
1564 |
++ audit_log_end(ab); |
1565 |
++} |
1566 |
++ |
1567 |
++void __audit_seccomp(unsigned long syscall, long signr, int code) |
1568 |
++{ |
1569 |
++ struct audit_buffer *ab; |
1570 |
++ |
1571 |
++ ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); |
1572 |
++ audit_log_abend(ab, "seccomp", signr); |
1573 |
++ audit_log_format(ab, " syscall=%ld", syscall); |
1574 |
++#ifdef CONFIG_COMPAT |
1575 |
++ audit_log_format(ab, " compat=%d", is_compat_task()); |
1576 |
++#endif |
1577 |
++ audit_log_format(ab, " ip=0x%lx", KSTK_EIP(current)); |
1578 |
++ audit_log_format(ab, " code=0x%x", code); |
1579 |
+ audit_log_end(ab); |
1580 |
+ } |
1581 |
+ |
1582 |
diff --git a/kernel/capability.c b/kernel/capability.c |
1583 |
index b463871..59495fd 100644 |
1584 |
--- a/kernel/capability.c |
1585 |
@@ -78224,10 +78946,26 @@ index 234e152..0ae0243 100644 |
1586 |
{ |
1587 |
struct signal_struct *sig = current->signal; |
1588 |
diff --git a/kernel/fork.c b/kernel/fork.c |
1589 |
-index ce0c182..360568a 100644 |
1590 |
+index ce0c182..c6ec99a 100644 |
1591 |
--- a/kernel/fork.c |
1592 |
+++ b/kernel/fork.c |
1593 |
-@@ -270,19 +270,24 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) |
1594 |
+@@ -34,6 +34,7 @@ |
1595 |
+ #include <linux/cgroup.h> |
1596 |
+ #include <linux/security.h> |
1597 |
+ #include <linux/hugetlb.h> |
1598 |
++#include <linux/seccomp.h> |
1599 |
+ #include <linux/swap.h> |
1600 |
+ #include <linux/syscalls.h> |
1601 |
+ #include <linux/jiffies.h> |
1602 |
+@@ -168,6 +169,7 @@ void free_task(struct task_struct *tsk) |
1603 |
+ free_thread_info(tsk->stack); |
1604 |
+ rt_mutex_debug_task_free(tsk); |
1605 |
+ ftrace_graph_exit_task(tsk); |
1606 |
++ put_seccomp_filter(tsk); |
1607 |
+ free_task_struct(tsk); |
1608 |
+ } |
1609 |
+ EXPORT_SYMBOL(free_task); |
1610 |
+@@ -270,19 +272,24 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) |
1611 |
} |
1612 |
|
1613 |
err = arch_dup_task_struct(tsk, orig); |
1614 |
@@ -78256,7 +78994,7 @@ index ce0c182..360568a 100644 |
1615 |
#endif |
1616 |
|
1617 |
/* |
1618 |
-@@ -306,13 +311,78 @@ out: |
1619 |
+@@ -306,13 +313,78 @@ out: |
1620 |
} |
1621 |
|
1622 |
#ifdef CONFIG_MMU |
1623 |
@@ -78339,7 +79077,7 @@ index ce0c182..360568a 100644 |
1624 |
|
1625 |
down_write(&oldmm->mmap_sem); |
1626 |
flush_cache_dup_mm(oldmm); |
1627 |
-@@ -324,8 +394,8 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) |
1628 |
+@@ -324,8 +396,8 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) |
1629 |
mm->locked_vm = 0; |
1630 |
mm->mmap = NULL; |
1631 |
mm->mmap_cache = NULL; |
1632 |
@@ -78350,7 +79088,7 @@ index ce0c182..360568a 100644 |
1633 |
mm->map_count = 0; |
1634 |
cpumask_clear(mm_cpumask(mm)); |
1635 |
mm->mm_rb = RB_ROOT; |
1636 |
-@@ -341,63 +411,16 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) |
1637 |
+@@ -341,63 +413,16 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) |
1638 |
|
1639 |
prev = NULL; |
1640 |
for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) { |
1641 |
@@ -78419,7 +79157,7 @@ index ce0c182..360568a 100644 |
1642 |
|
1643 |
/* |
1644 |
* Link in the new vma and copy the page table entries. |
1645 |
-@@ -420,6 +443,31 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) |
1646 |
+@@ -420,6 +445,31 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) |
1647 |
if (retval) |
1648 |
goto out; |
1649 |
} |
1650 |
@@ -78451,7 +79189,7 @@ index ce0c182..360568a 100644 |
1651 |
/* a new mm has just been created */ |
1652 |
arch_dup_mmap(oldmm, mm); |
1653 |
retval = 0; |
1654 |
-@@ -428,14 +476,6 @@ out: |
1655 |
+@@ -428,14 +478,6 @@ out: |
1656 |
flush_tlb_mm(oldmm); |
1657 |
up_write(&oldmm->mmap_sem); |
1658 |
return retval; |
1659 |
@@ -78466,7 +79204,7 @@ index ce0c182..360568a 100644 |
1660 |
} |
1661 |
|
1662 |
static inline int mm_alloc_pgd(struct mm_struct *mm) |
1663 |
-@@ -647,6 +687,26 @@ struct mm_struct *get_task_mm(struct task_struct *task) |
1664 |
+@@ -647,6 +689,26 @@ struct mm_struct *get_task_mm(struct task_struct *task) |
1665 |
} |
1666 |
EXPORT_SYMBOL_GPL(get_task_mm); |
1667 |
|
1668 |
@@ -78493,7 +79231,7 @@ index ce0c182..360568a 100644 |
1669 |
/* Please note the differences between mmput and mm_release. |
1670 |
* mmput is called whenever we stop holding onto a mm_struct, |
1671 |
* error success whatever. |
1672 |
-@@ -832,13 +892,20 @@ static int copy_fs(unsigned long clone_flags, struct task_struct *tsk) |
1673 |
+@@ -832,13 +894,20 @@ static int copy_fs(unsigned long clone_flags, struct task_struct *tsk) |
1674 |
spin_unlock(&fs->lock); |
1675 |
return -EAGAIN; |
1676 |
} |
1677 |
@@ -78515,7 +79253,7 @@ index ce0c182..360568a 100644 |
1678 |
return 0; |
1679 |
} |
1680 |
|
1681 |
-@@ -1047,7 +1114,7 @@ static void posix_cpu_timers_init(struct task_struct *tsk) |
1682 |
+@@ -1047,7 +1116,7 @@ static void posix_cpu_timers_init(struct task_struct *tsk) |
1683 |
* parts of the process environment (as per the clone |
1684 |
* flags). The actual kick-off is left to the caller. |
1685 |
*/ |
1686 |
@@ -78524,7 +79262,15 @@ index ce0c182..360568a 100644 |
1687 |
unsigned long stack_start, |
1688 |
struct pt_regs *regs, |
1689 |
unsigned long stack_size, |
1690 |
-@@ -1104,10 +1171,13 @@ static struct task_struct *copy_process(unsigned long clone_flags, |
1691 |
+@@ -1096,6 +1165,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, |
1692 |
+ goto fork_out; |
1693 |
+ |
1694 |
+ ftrace_graph_init_task(p); |
1695 |
++ get_seccomp_filter(p); |
1696 |
+ |
1697 |
+ rt_mutex_init_task(p); |
1698 |
+ |
1699 |
+@@ -1104,10 +1174,13 @@ static struct task_struct *copy_process(unsigned long clone_flags, |
1700 |
DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled); |
1701 |
#endif |
1702 |
retval = -EAGAIN; |
1703 |
@@ -78540,7 +79286,7 @@ index ce0c182..360568a 100644 |
1704 |
goto bad_fork_free; |
1705 |
} |
1706 |
current->flags &= ~PF_NPROC_EXCEEDED; |
1707 |
-@@ -1341,6 +1411,11 @@ static struct task_struct *copy_process(unsigned long clone_flags, |
1708 |
+@@ -1341,6 +1414,11 @@ static struct task_struct *copy_process(unsigned long clone_flags, |
1709 |
goto bad_fork_free_pid; |
1710 |
} |
1711 |
|
1712 |
@@ -78552,7 +79298,7 @@ index ce0c182..360568a 100644 |
1713 |
if (clone_flags & CLONE_THREAD) { |
1714 |
current->signal->nr_threads++; |
1715 |
atomic_inc(¤t->signal->live); |
1716 |
-@@ -1421,6 +1496,8 @@ bad_fork_cleanup_count: |
1717 |
+@@ -1421,6 +1499,8 @@ bad_fork_cleanup_count: |
1718 |
bad_fork_free: |
1719 |
free_task(p); |
1720 |
fork_out: |
1721 |
@@ -78561,7 +79307,7 @@ index ce0c182..360568a 100644 |
1722 |
return ERR_PTR(retval); |
1723 |
} |
1724 |
|
1725 |
-@@ -1507,6 +1584,7 @@ long do_fork(unsigned long clone_flags, |
1726 |
+@@ -1507,6 +1587,7 @@ long do_fork(unsigned long clone_flags, |
1727 |
|
1728 |
p = copy_process(clone_flags, stack_start, regs, stack_size, |
1729 |
child_tidptr, NULL, trace); |
1730 |
@@ -78569,7 +79315,7 @@ index ce0c182..360568a 100644 |
1731 |
/* |
1732 |
* Do this prior waking up the new thread - the thread pointer |
1733 |
* might get invalid after that point, if the thread exits quickly. |
1734 |
-@@ -1521,6 +1599,8 @@ long do_fork(unsigned long clone_flags, |
1735 |
+@@ -1521,6 +1602,8 @@ long do_fork(unsigned long clone_flags, |
1736 |
if (clone_flags & CLONE_PARENT_SETTID) |
1737 |
put_user(nr, parent_tidptr); |
1738 |
|
1739 |
@@ -78578,7 +79324,7 @@ index ce0c182..360568a 100644 |
1740 |
if (clone_flags & CLONE_VFORK) { |
1741 |
p->vfork_done = &vfork; |
1742 |
init_completion(&vfork); |
1743 |
-@@ -1591,7 +1671,7 @@ void __init proc_caches_init(void) |
1744 |
+@@ -1591,7 +1674,7 @@ void __init proc_caches_init(void) |
1745 |
mm_cachep = kmem_cache_create("mm_struct", |
1746 |
sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN, |
1747 |
SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); |
1748 |
@@ -78587,7 +79333,7 @@ index ce0c182..360568a 100644 |
1749 |
mmap_init(); |
1750 |
nsproxy_cache_init(); |
1751 |
} |
1752 |
-@@ -1630,7 +1710,7 @@ static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp) |
1753 |
+@@ -1630,7 +1713,7 @@ static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp) |
1754 |
return 0; |
1755 |
|
1756 |
/* don't need lock here; in the worst case we'll do useless copy */ |
1757 |
@@ -78596,7 +79342,7 @@ index ce0c182..360568a 100644 |
1758 |
return 0; |
1759 |
|
1760 |
*new_fsp = copy_fs_struct(fs); |
1761 |
-@@ -1719,7 +1799,8 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags) |
1762 |
+@@ -1719,7 +1802,8 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags) |
1763 |
fs = current->fs; |
1764 |
spin_lock(&fs->lock); |
1765 |
current->fs = new_fs; |
1766 |
@@ -80543,7 +81289,7 @@ index 76b8e77..a2930e8 100644 |
1767 |
} |
1768 |
|
1769 |
diff --git a/kernel/ptrace.c b/kernel/ptrace.c |
1770 |
-index 67fedad..32d32a04 100644 |
1771 |
+index 67fedad..82362a6 100644 |
1772 |
--- a/kernel/ptrace.c |
1773 |
+++ b/kernel/ptrace.c |
1774 |
@@ -211,7 +211,8 @@ int ptrace_check_attach(struct task_struct *child, bool ignore_state) |
1775 |
@@ -80627,7 +81373,17 @@ index 67fedad..32d32a04 100644 |
1776 |
return -EFAULT; |
1777 |
copied += retval; |
1778 |
src += retval; |
1779 |
-@@ -719,7 +737,7 @@ int ptrace_request(struct task_struct *child, long request, |
1780 |
+@@ -582,6 +600,9 @@ static int ptrace_setoptions(struct task_struct *child, unsigned long data) |
1781 |
+ if (data & PTRACE_O_TRACEEXIT) |
1782 |
+ child->ptrace |= PT_TRACE_EXIT; |
1783 |
+ |
1784 |
++ if (data & PTRACE_O_TRACESECCOMP) |
1785 |
++ child->ptrace |= PT_TRACE_SECCOMP; |
1786 |
++ |
1787 |
+ return (data & ~PTRACE_O_MASK) ? -EINVAL : 0; |
1788 |
+ } |
1789 |
+ |
1790 |
+@@ -719,7 +740,7 @@ int ptrace_request(struct task_struct *child, long request, |
1791 |
bool seized = child->ptrace & PT_SEIZED; |
1792 |
int ret = -EIO; |
1793 |
siginfo_t siginfo, *si; |
1794 |
@@ -80636,7 +81392,7 @@ index 67fedad..32d32a04 100644 |
1795 |
unsigned long __user *datalp = datavp; |
1796 |
unsigned long flags; |
1797 |
|
1798 |
-@@ -921,14 +939,21 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr, |
1799 |
+@@ -921,14 +942,21 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr, |
1800 |
goto out; |
1801 |
} |
1802 |
|
1803 |
@@ -80659,7 +81415,7 @@ index 67fedad..32d32a04 100644 |
1804 |
goto out_put_task_struct; |
1805 |
} |
1806 |
|
1807 |
-@@ -956,7 +981,7 @@ int generic_ptrace_peekdata(struct task_struct *tsk, unsigned long addr, |
1808 |
+@@ -956,7 +984,7 @@ int generic_ptrace_peekdata(struct task_struct *tsk, unsigned long addr, |
1809 |
copied = access_process_vm(tsk, addr, &tmp, sizeof(tmp), 0); |
1810 |
if (copied != sizeof(tmp)) |
1811 |
return -EIO; |
1812 |
@@ -80668,7 +81424,7 @@ index 67fedad..32d32a04 100644 |
1813 |
} |
1814 |
|
1815 |
int generic_ptrace_pokedata(struct task_struct *tsk, unsigned long addr, |
1816 |
-@@ -1050,7 +1075,7 @@ int compat_ptrace_request(struct task_struct *child, compat_long_t request, |
1817 |
+@@ -1050,7 +1078,7 @@ int compat_ptrace_request(struct task_struct *child, compat_long_t request, |
1818 |
} |
1819 |
|
1820 |
asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid, |
1821 |
@@ -80677,7 +81433,7 @@ index 67fedad..32d32a04 100644 |
1822 |
{ |
1823 |
struct task_struct *child; |
1824 |
long ret; |
1825 |
-@@ -1066,14 +1091,21 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid, |
1826 |
+@@ -1066,14 +1094,21 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid, |
1827 |
goto out; |
1828 |
} |
1829 |
|
1830 |
@@ -81428,8 +82184,513 @@ index c261da7..4e5221ad 100644 |
1831 |
{ |
1832 |
int this_cpu = smp_processor_id(); |
1833 |
struct rq *this_rq = cpu_rq(this_cpu); |
1834 |
+diff --git a/kernel/seccomp.c b/kernel/seccomp.c |
1835 |
+index 57d4b13..bc84054 100644 |
1836 |
+--- a/kernel/seccomp.c |
1837 |
++++ b/kernel/seccomp.c |
1838 |
+@@ -3,15 +3,353 @@ |
1839 |
+ * |
1840 |
+ * Copyright 2004-2005 Andrea Arcangeli <andrea@××××××××.com> |
1841 |
+ * |
1842 |
+- * This defines a simple but solid secure-computing mode. |
1843 |
++ * Copyright (C) 2012 Google, Inc. |
1844 |
++ * Will Drewry <wad@××××××××.org> |
1845 |
++ * |
1846 |
++ * This defines a simple but solid secure-computing facility. |
1847 |
++ * |
1848 |
++ * Mode 1 uses a fixed list of allowed system calls. |
1849 |
++ * Mode 2 allows user-defined system call filters in the form |
1850 |
++ * of Berkeley Packet Filters/Linux Socket Filters. |
1851 |
+ */ |
1852 |
+ |
1853 |
+-#include <linux/seccomp.h> |
1854 |
+-#include <linux/sched.h> |
1855 |
++#include <linux/atomic.h> |
1856 |
++#include <linux/audit.h> |
1857 |
+ #include <linux/compat.h> |
1858 |
++#include <linux/filter.h> |
1859 |
++#include <linux/ptrace.h> |
1860 |
++#include <linux/sched.h> |
1861 |
++#include <linux/seccomp.h> |
1862 |
++#include <linux/security.h> |
1863 |
++#include <linux/slab.h> |
1864 |
++#include <linux/uaccess.h> |
1865 |
++ |
1866 |
++#ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER |
1867 |
++#include <asm/syscall.h> |
1868 |
++#endif |
1869 |
+ |
1870 |
+ /* #define SECCOMP_DEBUG 1 */ |
1871 |
+-#define NR_SECCOMP_MODES 1 |
1872 |
++ |
1873 |
++#ifdef CONFIG_SECCOMP_FILTER |
1874 |
++/** |
1875 |
++ * struct seccomp_filter - container for seccomp BPF programs |
1876 |
++ * |
1877 |
++ * @usage: reference count to manage the object liftime. |
1878 |
++ * get/put helpers should be used when accessing an instance |
1879 |
++ * outside of a lifetime-guarded section. In general, this |
1880 |
++ * is only needed for handling filters shared across tasks. |
1881 |
++ * @prev: points to a previously installed, or inherited, filter |
1882 |
++ * @len: the number of instructions in the program |
1883 |
++ * @insns: the BPF program instructions to evaluate |
1884 |
++ * |
1885 |
++ * seccomp_filter objects are organized in a tree linked via the @prev |
1886 |
++ * pointer. For any task, it appears to be a singly-linked list starting |
1887 |
++ * with current->seccomp.filter, the most recently attached or inherited filter. |
1888 |
++ * However, multiple filters may share a @prev node, by way of fork(), which |
1889 |
++ * results in a unidirectional tree existing in memory. This is similar to |
1890 |
++ * how namespaces work. |
1891 |
++ * |
1892 |
++ * seccomp_filter objects should never be modified after being attached |
1893 |
++ * to a task_struct (other than @usage). |
1894 |
++ */ |
1895 |
++struct seccomp_filter { |
1896 |
++ atomic_t usage; |
1897 |
++ struct seccomp_filter *prev; |
1898 |
++ unsigned short len; /* Instruction count */ |
1899 |
++ struct sock_filter insns[]; |
1900 |
++}; |
1901 |
++ |
1902 |
++/* Limit any path through the tree to 256KB worth of instructions. */ |
1903 |
++#define MAX_INSNS_PER_PATH ((1 << 18) / sizeof(struct sock_filter)) |
1904 |
++ |
1905 |
++/** |
1906 |
++ * get_u32 - returns a u32 offset into data |
1907 |
++ * @data: a unsigned 64 bit value |
1908 |
++ * @index: 0 or 1 to return the first or second 32-bits |
1909 |
++ * |
1910 |
++ * This inline exists to hide the length of unsigned long. |
1911 |
++ * If a 32-bit unsigned long is passed in, it will be extended |
1912 |
++ * and the top 32-bits will be 0. If it is a 64-bit unsigned |
1913 |
++ * long, then whatever data is resident will be properly returned. |
1914 |
++ */ |
1915 |
++static inline u32 get_u32(u64 data, int index) |
1916 |
++{ |
1917 |
++ return ((u32 *)&data)[index]; |
1918 |
++} |
1919 |
++ |
1920 |
++/* Helper for bpf_load below. */ |
1921 |
++#define BPF_DATA(_name) offsetof(struct seccomp_data, _name) |
1922 |
++/** |
1923 |
++ * bpf_load: checks and returns a pointer to the requested offset |
1924 |
++ * @off: offset into struct seccomp_data to load from |
1925 |
++ * |
1926 |
++ * Returns the requested 32-bits of data. |
1927 |
++ * seccomp_chk_filter() should assure that @off is 32-bit aligned |
1928 |
++ * and not out of bounds. Failure to do so is a BUG. |
1929 |
++ */ |
1930 |
++u32 seccomp_bpf_load(int off) |
1931 |
++{ |
1932 |
++ struct pt_regs *regs = task_pt_regs(current); |
1933 |
++ if (off == BPF_DATA(nr)) |
1934 |
++ return syscall_get_nr(current, regs); |
1935 |
++ if (off == BPF_DATA(arch)) |
1936 |
++ return syscall_get_arch(current, regs); |
1937 |
++ if (off >= BPF_DATA(args[0]) && off < BPF_DATA(args[6])) { |
1938 |
++ unsigned long value; |
1939 |
++ int arg = (off - BPF_DATA(args[0])) / sizeof(u64); |
1940 |
++ int index = !!(off % sizeof(u64)); |
1941 |
++ syscall_get_arguments(current, regs, arg, 1, &value); |
1942 |
++ return get_u32(value, index); |
1943 |
++ } |
1944 |
++ if (off == BPF_DATA(instruction_pointer)) |
1945 |
++ return get_u32(KSTK_EIP(current), 0); |
1946 |
++ if (off == BPF_DATA(instruction_pointer) + sizeof(u32)) |
1947 |
++ return get_u32(KSTK_EIP(current), 1); |
1948 |
++ /* seccomp_chk_filter should make this impossible. */ |
1949 |
++ BUG(); |
1950 |
++} |
1951 |
++ |
1952 |
++/** |
1953 |
++ * seccomp_chk_filter - verify seccomp filter code |
1954 |
++ * @filter: filter to verify |
1955 |
++ * @flen: length of filter |
1956 |
++ * |
1957 |
++ * Takes a previously checked filter (by sk_chk_filter) and |
1958 |
++ * redirects all filter code that loads struct sk_buff data |
1959 |
++ * and related data through seccomp_bpf_load. It also |
1960 |
++ * enforces length and alignment checking of those loads. |
1961 |
++ * |
1962 |
++ * Returns 0 if the rule set is legal or -EINVAL if not. |
1963 |
++ */ |
1964 |
++static int seccomp_chk_filter(struct sock_filter *filter, unsigned int flen) |
1965 |
++{ |
1966 |
++ int pc; |
1967 |
++ for (pc = 0; pc < flen; pc++) { |
1968 |
++ struct sock_filter *ftest = &filter[pc]; |
1969 |
++ u16 code = ftest->code; |
1970 |
++ u32 k = ftest->k; |
1971 |
++ switch (code) { |
1972 |
++ case BPF_S_LD_W_ABS: |
1973 |
++ ftest->code = BPF_S_ANC_SECCOMP_LD_W; |
1974 |
++ /* 32-bit aligned and not out of bounds. */ |
1975 |
++ if (k >= sizeof(struct seccomp_data) || k & 3) |
1976 |
++ return -EINVAL; |
1977 |
++ continue; |
1978 |
++ case BPF_S_LD_W_LEN: |
1979 |
++ ftest->code = BPF_S_LD_IMM; |
1980 |
++ ftest->k = sizeof(struct seccomp_data); |
1981 |
++ continue; |
1982 |
++ case BPF_S_LDX_W_LEN: |
1983 |
++ ftest->code = BPF_S_LDX_IMM; |
1984 |
++ ftest->k = sizeof(struct seccomp_data); |
1985 |
++ continue; |
1986 |
++ /* Explicitly include allowed calls. */ |
1987 |
++ case BPF_S_RET_K: |
1988 |
++ case BPF_S_RET_A: |
1989 |
++ case BPF_S_ALU_ADD_K: |
1990 |
++ case BPF_S_ALU_ADD_X: |
1991 |
++ case BPF_S_ALU_SUB_K: |
1992 |
++ case BPF_S_ALU_SUB_X: |
1993 |
++ case BPF_S_ALU_MUL_K: |
1994 |
++ case BPF_S_ALU_MUL_X: |
1995 |
++ case BPF_S_ALU_DIV_X: |
1996 |
++ case BPF_S_ALU_AND_K: |
1997 |
++ case BPF_S_ALU_AND_X: |
1998 |
++ case BPF_S_ALU_OR_K: |
1999 |
++ case BPF_S_ALU_OR_X: |
2000 |
++ case BPF_S_ALU_LSH_K: |
2001 |
++ case BPF_S_ALU_LSH_X: |
2002 |
++ case BPF_S_ALU_RSH_K: |
2003 |
++ case BPF_S_ALU_RSH_X: |
2004 |
++ case BPF_S_ALU_NEG: |
2005 |
++ case BPF_S_LD_IMM: |
2006 |
++ case BPF_S_LDX_IMM: |
2007 |
++ case BPF_S_MISC_TAX: |
2008 |
++ case BPF_S_MISC_TXA: |
2009 |
++ case BPF_S_ALU_DIV_K: |
2010 |
++ case BPF_S_LD_MEM: |
2011 |
++ case BPF_S_LDX_MEM: |
2012 |
++ case BPF_S_ST: |
2013 |
++ case BPF_S_STX: |
2014 |
++ case BPF_S_JMP_JA: |
2015 |
++ case BPF_S_JMP_JEQ_K: |
2016 |
++ case BPF_S_JMP_JEQ_X: |
2017 |
++ case BPF_S_JMP_JGE_K: |
2018 |
++ case BPF_S_JMP_JGE_X: |
2019 |
++ case BPF_S_JMP_JGT_K: |
2020 |
++ case BPF_S_JMP_JGT_X: |
2021 |
++ case BPF_S_JMP_JSET_K: |
2022 |
++ case BPF_S_JMP_JSET_X: |
2023 |
++ continue; |
2024 |
++ default: |
2025 |
++ return -EINVAL; |
2026 |
++ } |
2027 |
++ } |
2028 |
++ return 0; |
2029 |
++} |
2030 |
++ |
2031 |
++/** |
2032 |
++ * seccomp_run_filters - evaluates all seccomp filters against @syscall |
2033 |
++ * @syscall: number of the current system call |
2034 |
++ * |
2035 |
++ * Returns valid seccomp BPF response codes. |
2036 |
++ */ |
2037 |
++static u32 seccomp_run_filters(int syscall) |
2038 |
++{ |
2039 |
++ struct seccomp_filter *f; |
2040 |
++ u32 ret = SECCOMP_RET_ALLOW; |
2041 |
++ |
2042 |
++ /* Ensure unexpected behavior doesn't result in failing open. */ |
2043 |
++ if (WARN_ON(current->seccomp.filter == NULL)) |
2044 |
++ return SECCOMP_RET_KILL; |
2045 |
++ |
2046 |
++ /* |
2047 |
++ * All filters are evaluated in order of youngest to oldest. The lowest |
2048 |
++ * BPF return value (ignoring the DATA) always takes priority. |
2049 |
++ */ |
2050 |
++ for (f = current->seccomp.filter; f; f = f->prev) { |
2051 |
++ u32 cur_ret = sk_run_filter(NULL, f->insns); |
2052 |
++ if ((cur_ret & SECCOMP_RET_ACTION) < (ret & SECCOMP_RET_ACTION)) |
2053 |
++ ret = cur_ret; |
2054 |
++ } |
2055 |
++ return ret; |
2056 |
++} |
2057 |
++ |
2058 |
++/** |
2059 |
++ * seccomp_attach_filter: Attaches a seccomp filter to current. |
2060 |
++ * @fprog: BPF program to install |
2061 |
++ * |
2062 |
++ * Returns 0 on success or an errno on failure. |
2063 |
++ */ |
2064 |
++static long seccomp_attach_filter(struct sock_fprog *fprog) |
2065 |
++{ |
2066 |
++ struct seccomp_filter *filter; |
2067 |
++ unsigned long fp_size = fprog->len * sizeof(struct sock_filter); |
2068 |
++ unsigned long total_insns = fprog->len; |
2069 |
++ long ret; |
2070 |
++ |
2071 |
++ if (fprog->len == 0 || fprog->len > BPF_MAXINSNS) |
2072 |
++ return -EINVAL; |
2073 |
++ |
2074 |
++ for (filter = current->seccomp.filter; filter; filter = filter->prev) |
2075 |
++ total_insns += filter->len + 4; /* include a 4 instr penalty */ |
2076 |
++ if (total_insns > MAX_INSNS_PER_PATH) |
2077 |
++ return -ENOMEM; |
2078 |
++ |
2079 |
++ /* |
2080 |
++ * Installing a seccomp filter requires that the task have |
2081 |
++ * CAP_SYS_ADMIN in its namespace or be running with no_new_privs. |
2082 |
++ * This avoids scenarios where unprivileged tasks can affect the |
2083 |
++ * behavior of privileged children. |
2084 |
++ */ |
2085 |
++ if (!current->no_new_privs && |
2086 |
++ security_real_capable_noaudit(current, current_user_ns(), |
2087 |
++ CAP_SYS_ADMIN) != 0) |
2088 |
++ return -EACCES; |
2089 |
++ |
2090 |
++ /* Allocate a new seccomp_filter */ |
2091 |
++ filter = kzalloc(sizeof(struct seccomp_filter) + fp_size, GFP_KERNEL); |
2092 |
++ if (!filter) |
2093 |
++ return -ENOMEM; |
2094 |
++ atomic_set(&filter->usage, 1); |
2095 |
++ filter->len = fprog->len; |
2096 |
++ |
2097 |
++ /* Copy the instructions from fprog. */ |
2098 |
++ ret = -EFAULT; |
2099 |
++ if (copy_from_user(filter->insns, fprog->filter, fp_size)) |
2100 |
++ goto fail; |
2101 |
++ |
2102 |
++ /* Check and rewrite the fprog via the skb checker */ |
2103 |
++ ret = sk_chk_filter(filter->insns, filter->len); |
2104 |
++ if (ret) |
2105 |
++ goto fail; |
2106 |
++ |
2107 |
++ /* Check and rewrite the fprog for seccomp use */ |
2108 |
++ ret = seccomp_chk_filter(filter->insns, filter->len); |
2109 |
++ if (ret) |
2110 |
++ goto fail; |
2111 |
++ |
2112 |
++ /* |
2113 |
++ * If there is an existing filter, make it the prev and don't drop its |
2114 |
++ * task reference. |
2115 |
++ */ |
2116 |
++ filter->prev = current->seccomp.filter; |
2117 |
++ current->seccomp.filter = filter; |
2118 |
++ return 0; |
2119 |
++fail: |
2120 |
++ kfree(filter); |
2121 |
++ return ret; |
2122 |
++} |
2123 |
++ |
2124 |
++/** |
2125 |
++ * seccomp_attach_user_filter - attaches a user-supplied sock_fprog |
2126 |
++ * @user_filter: pointer to the user data containing a sock_fprog. |
2127 |
++ * |
2128 |
++ * Returns 0 on success and non-zero otherwise. |
2129 |
++ */ |
2130 |
++long seccomp_attach_user_filter(char __user *user_filter) |
2131 |
++{ |
2132 |
++ struct sock_fprog fprog; |
2133 |
++ long ret = -EFAULT; |
2134 |
++ |
2135 |
++#ifdef CONFIG_COMPAT |
2136 |
++ if (is_compat_task()) { |
2137 |
++ struct compat_sock_fprog fprog32; |
2138 |
++ if (copy_from_user(&fprog32, user_filter, sizeof(fprog32))) |
2139 |
++ goto out; |
2140 |
++ fprog.len = fprog32.len; |
2141 |
++ fprog.filter = compat_ptr(fprog32.filter); |
2142 |
++ } else /* falls through to the if below. */ |
2143 |
++#endif |
2144 |
++ if (copy_from_user(&fprog, user_filter, sizeof(fprog))) |
2145 |
++ goto out; |
2146 |
++ ret = seccomp_attach_filter(&fprog); |
2147 |
++out: |
2148 |
++ return ret; |
2149 |
++} |
2150 |
++ |
2151 |
++/* get_seccomp_filter - increments the reference count of the filter on @tsk */ |
2152 |
++void get_seccomp_filter(struct task_struct *tsk) |
2153 |
++{ |
2154 |
++ struct seccomp_filter *orig = tsk->seccomp.filter; |
2155 |
++ if (!orig) |
2156 |
++ return; |
2157 |
++ /* Reference count is bounded by the number of total processes. */ |
2158 |
++ atomic_inc(&orig->usage); |
2159 |
++} |
2160 |
++ |
2161 |
++/* put_seccomp_filter - decrements the ref count of tsk->seccomp.filter */ |
2162 |
++void put_seccomp_filter(struct task_struct *tsk) |
2163 |
++{ |
2164 |
++ struct seccomp_filter *orig = tsk->seccomp.filter; |
2165 |
++ /* Clean up single-reference branches iteratively. */ |
2166 |
++ while (orig && atomic_dec_and_test(&orig->usage)) { |
2167 |
++ struct seccomp_filter *freeme = orig; |
2168 |
++ orig = orig->prev; |
2169 |
++ kfree(freeme); |
2170 |
++ } |
2171 |
++} |
2172 |
++ |
2173 |
++/** |
2174 |
++ * seccomp_send_sigsys - signals the task to allow in-process syscall emulation |
2175 |
++ * @syscall: syscall number to send to userland |
2176 |
++ * @reason: filter-supplied reason code to send to userland (via si_errno) |
2177 |
++ * |
2178 |
++ * Forces a SIGSYS with a code of SYS_SECCOMP and related sigsys info. |
2179 |
++ */ |
2180 |
++static void seccomp_send_sigsys(int syscall, int reason) |
2181 |
++{ |
2182 |
++ struct siginfo info; |
2183 |
++ memset(&info, 0, sizeof(info)); |
2184 |
++ info.si_signo = SIGSYS; |
2185 |
++ info.si_code = SYS_SECCOMP; |
2186 |
++ info.si_call_addr = (void __user *)KSTK_EIP(current); |
2187 |
++ info.si_errno = reason; |
2188 |
++ info.si_arch = syscall_get_arch(current, task_pt_regs(current)); |
2189 |
++ info.si_syscall = syscall; |
2190 |
++ force_sig_info(SIGSYS, &info, current); |
2191 |
++} |
2192 |
++#endif /* CONFIG_SECCOMP_FILTER */ |
2193 |
+ |
2194 |
+ /* |
2195 |
+ * Secure computing mode 1 allows only read/write/exit/sigreturn. |
2196 |
+@@ -32,11 +370,21 @@ static int mode1_syscalls_32[] = { |
2197 |
+ |
2198 |
+ void __secure_computing(int this_syscall) |
2199 |
+ { |
2200 |
++ /* Filter calls should never use this function. */ |
2201 |
++ BUG_ON(current->seccomp.mode == SECCOMP_MODE_FILTER); |
2202 |
++ __secure_computing_int(this_syscall); |
2203 |
++} |
2204 |
++ |
2205 |
++int __secure_computing_int(int this_syscall) |
2206 |
++{ |
2207 |
+ int mode = current->seccomp.mode; |
2208 |
+- int * syscall; |
2209 |
++ int exit_sig = 0; |
2210 |
++ int *syscall; |
2211 |
++ u32 ret = SECCOMP_RET_KILL; |
2212 |
++ int data; |
2213 |
+ |
2214 |
+ switch (mode) { |
2215 |
+- case 1: |
2216 |
++ case SECCOMP_MODE_STRICT: |
2217 |
+ syscall = mode1_syscalls; |
2218 |
+ #ifdef CONFIG_COMPAT |
2219 |
+ if (is_compat_task()) |
2220 |
+@@ -44,9 +392,44 @@ void __secure_computing(int this_syscall) |
2221 |
+ #endif |
2222 |
+ do { |
2223 |
+ if (*syscall == this_syscall) |
2224 |
+- return; |
2225 |
++ return 0; |
2226 |
+ } while (*++syscall); |
2227 |
++ exit_sig = SIGKILL; |
2228 |
+ break; |
2229 |
++#ifdef CONFIG_SECCOMP_FILTER |
2230 |
++ case SECCOMP_MODE_FILTER: |
2231 |
++ ret = seccomp_run_filters(this_syscall); |
2232 |
++ data = ret & SECCOMP_RET_DATA; |
2233 |
++ switch (ret & SECCOMP_RET_ACTION) { |
2234 |
++ case SECCOMP_RET_ERRNO: |
2235 |
++ /* Set the low-order 16-bits as a errno. */ |
2236 |
++ syscall_set_return_value(current, task_pt_regs(current), |
2237 |
++ -data, 0); |
2238 |
++ goto skip; |
2239 |
++ case SECCOMP_RET_TRAP: |
2240 |
++ /* Show the handler the original registers. */ |
2241 |
++ syscall_rollback(current, task_pt_regs(current)); |
2242 |
++ /* Let the filter pass back 16 bits of data. */ |
2243 |
++ seccomp_send_sigsys(this_syscall, data); |
2244 |
++ goto skip; |
2245 |
++ case SECCOMP_RET_TRACE: |
2246 |
++ /* Skip these calls if there is no tracer. */ |
2247 |
++ if (!ptrace_event_enabled(current, PTRACE_EVENT_SECCOMP)) |
2248 |
++ goto skip; |
2249 |
++ /* Allow the BPF to provide the event message */ |
2250 |
++ ptrace_event(PTRACE_EVENT_SECCOMP, data); |
2251 |
++ if (fatal_signal_pending(current)) |
2252 |
++ break; |
2253 |
++ return 0; |
2254 |
++ case SECCOMP_RET_ALLOW: |
2255 |
++ return 0; |
2256 |
++ case SECCOMP_RET_KILL: |
2257 |
++ default: |
2258 |
++ break; |
2259 |
++ } |
2260 |
++ exit_sig = SIGSYS; |
2261 |
++ break; |
2262 |
++#endif |
2263 |
+ default: |
2264 |
+ BUG(); |
2265 |
+ } |
2266 |
+@@ -54,7 +437,11 @@ void __secure_computing(int this_syscall) |
2267 |
+ #ifdef SECCOMP_DEBUG |
2268 |
+ dump_stack(); |
2269 |
+ #endif |
2270 |
+- do_exit(SIGKILL); |
2271 |
++ __audit_seccomp(this_syscall, exit_sig, ret); |
2272 |
++ do_exit(exit_sig); |
2273 |
++skip: |
2274 |
++ audit_seccomp(this_syscall, exit_sig, ret); |
2275 |
++ return -1; |
2276 |
+ } |
2277 |
+ |
2278 |
+ long prctl_get_seccomp(void) |
2279 |
+@@ -62,25 +449,48 @@ long prctl_get_seccomp(void) |
2280 |
+ return current->seccomp.mode; |
2281 |
+ } |
2282 |
+ |
2283 |
+-long prctl_set_seccomp(unsigned long seccomp_mode) |
2284 |
++/** |
2285 |
++ * prctl_set_seccomp: configures current->seccomp.mode |
2286 |
++ * @seccomp_mode: requested mode to use |
2287 |
++ * @filter: optional struct sock_fprog for use with SECCOMP_MODE_FILTER |
2288 |
++ * |
2289 |
++ * This function may be called repeatedly with a @seccomp_mode of |
2290 |
++ * SECCOMP_MODE_FILTER to install additional filters. Every filter |
2291 |
++ * successfully installed will be evaluated (in reverse order) for each system |
2292 |
++ * call the task makes. |
2293 |
++ * |
2294 |
++ * Once current->seccomp.mode is non-zero, it may not be changed. |
2295 |
++ * |
2296 |
++ * Returns 0 on success or -EINVAL on failure. |
2297 |
++ */ |
2298 |
++long prctl_set_seccomp(unsigned long seccomp_mode, char __user *filter) |
2299 |
+ { |
2300 |
+- long ret; |
2301 |
++ long ret = -EINVAL; |
2302 |
+ |
2303 |
+- /* can set it only once to be even more secure */ |
2304 |
+- ret = -EPERM; |
2305 |
+- if (unlikely(current->seccomp.mode)) |
2306 |
++ if (current->seccomp.mode && |
2307 |
++ current->seccomp.mode != seccomp_mode) |
2308 |
+ goto out; |
2309 |
+ |
2310 |
+- ret = -EINVAL; |
2311 |
+- if (seccomp_mode && seccomp_mode <= NR_SECCOMP_MODES) { |
2312 |
+- current->seccomp.mode = seccomp_mode; |
2313 |
+- set_thread_flag(TIF_SECCOMP); |
2314 |
++ switch (seccomp_mode) { |
2315 |
++ case SECCOMP_MODE_STRICT: |
2316 |
++ ret = 0; |
2317 |
+ #ifdef TIF_NOTSC |
2318 |
+ disable_TSC(); |
2319 |
+ #endif |
2320 |
+- ret = 0; |
2321 |
++ break; |
2322 |
++#ifdef CONFIG_SECCOMP_FILTER |
2323 |
++ case SECCOMP_MODE_FILTER: |
2324 |
++ ret = seccomp_attach_user_filter(filter); |
2325 |
++ if (ret) |
2326 |
++ goto out; |
2327 |
++ break; |
2328 |
++#endif |
2329 |
++ default: |
2330 |
++ goto out; |
2331 |
+ } |
2332 |
+ |
2333 |
+- out: |
2334 |
++ current->seccomp.mode = seccomp_mode; |
2335 |
++ set_thread_flag(TIF_SECCOMP); |
2336 |
++out: |
2337 |
+ return ret; |
2338 |
+ } |
2339 |
diff --git a/kernel/signal.c b/kernel/signal.c |
2340 |
-index 3ecf574..7b5d245 100644 |
2341 |
+index 3ecf574..0541e21 100644 |
2342 |
--- a/kernel/signal.c |
2343 |
+++ b/kernel/signal.c |
2344 |
@@ -45,12 +45,12 @@ static struct kmem_cache *sigqueue_cachep; |
2345 |
@@ -81456,6 +82717,15 @@ index 3ecf574..7b5d245 100644 |
2346 |
|
2347 |
handler = sig_handler(t, sig); |
2348 |
|
2349 |
+@@ -159,7 +159,7 @@ void recalc_sigpending(void) |
2350 |
+ |
2351 |
+ #define SYNCHRONOUS_MASK \ |
2352 |
+ (sigmask(SIGSEGV) | sigmask(SIGBUS) | sigmask(SIGILL) | \ |
2353 |
+- sigmask(SIGTRAP) | sigmask(SIGFPE)) |
2354 |
++ sigmask(SIGTRAP) | sigmask(SIGFPE) | sigmask(SIGSYS)) |
2355 |
+ |
2356 |
+ int next_signal(struct sigpending *pending, sigset_t *mask) |
2357 |
+ { |
2358 |
@@ -364,6 +364,9 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi |
2359 |
atomic_inc(&user->sigpending); |
2360 |
rcu_read_unlock(); |
2361 |
@@ -81538,7 +82808,21 @@ index 3ecf574..7b5d245 100644 |
2362 |
|
2363 |
return ret; |
2364 |
} |
2365 |
-@@ -2765,7 +2788,15 @@ do_send_specific(pid_t tgid, pid_t pid, int sig, struct siginfo *info) |
2366 |
+@@ -2631,6 +2654,13 @@ int copy_siginfo_to_user(siginfo_t __user *to, siginfo_t *from) |
2367 |
+ err |= __put_user(from->si_uid, &to->si_uid); |
2368 |
+ err |= __put_user(from->si_ptr, &to->si_ptr); |
2369 |
+ break; |
2370 |
++#ifdef __ARCH_SIGSYS |
2371 |
++ case __SI_SYS: |
2372 |
++ err |= __put_user(from->si_call_addr, &to->si_call_addr); |
2373 |
++ err |= __put_user(from->si_syscall, &to->si_syscall); |
2374 |
++ err |= __put_user(from->si_arch, &to->si_arch); |
2375 |
++ break; |
2376 |
++#endif |
2377 |
+ default: /* this is just in case for now ... */ |
2378 |
+ err |= __put_user(from->si_pid, &to->si_pid); |
2379 |
+ err |= __put_user(from->si_uid, &to->si_uid); |
2380 |
+@@ -2765,7 +2795,15 @@ do_send_specific(pid_t tgid, pid_t pid, int sig, struct siginfo *info) |
2381 |
int error = -ESRCH; |
2382 |
|
2383 |
rcu_read_lock(); |
2384 |
@@ -81681,7 +82965,7 @@ index 2f194e9..2c05ea9 100644 |
2385 |
.priority = 10, |
2386 |
}; |
2387 |
diff --git a/kernel/sys.c b/kernel/sys.c |
2388 |
-index 9d557df..691558c 100644 |
2389 |
+index 9d557df..b2a5319 100644 |
2390 |
--- a/kernel/sys.c |
2391 |
+++ b/kernel/sys.c |
2392 |
@@ -158,6 +158,12 @@ static int set_one_prio(struct task_struct *p, int niceval, int error) |
2393 |
@@ -81852,6 +83136,32 @@ index 9d557df..691558c 100644 |
2394 |
error = -EINVAL; |
2395 |
break; |
2396 |
} |
2397 |
+@@ -1808,7 +1851,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, |
2398 |
+ error = prctl_get_seccomp(); |
2399 |
+ break; |
2400 |
+ case PR_SET_SECCOMP: |
2401 |
+- error = prctl_set_seccomp(arg2); |
2402 |
++ error = prctl_set_seccomp(arg2, (char __user *)arg3); |
2403 |
+ break; |
2404 |
+ case PR_GET_TSC: |
2405 |
+ error = GET_TSC_CTL(arg2); |
2406 |
+@@ -1868,6 +1911,16 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, |
2407 |
+ else |
2408 |
+ error = PR_MCE_KILL_DEFAULT; |
2409 |
+ break; |
2410 |
++ case PR_SET_NO_NEW_PRIVS: |
2411 |
++ if (arg2 != 1 || arg3 || arg4 || arg5) |
2412 |
++ return -EINVAL; |
2413 |
++ |
2414 |
++ current->no_new_privs = 1; |
2415 |
++ break; |
2416 |
++ case PR_GET_NO_NEW_PRIVS: |
2417 |
++ if (arg2 || arg3 || arg4 || arg5) |
2418 |
++ return -EINVAL; |
2419 |
++ return current->no_new_privs ? 1 : 0; |
2420 |
+ default: |
2421 |
+ error = -EINVAL; |
2422 |
+ break; |
2423 |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c |
2424 |
index ea7ec7f..798623e 100644 |
2425 |
--- a/kernel/sysctl.c |
2426 |
@@ -83724,6 +85034,20 @@ index d9df745..e73c2fe 100644 |
2427 |
|
2428 |
static inline void *ptr_to_indirect(void *ptr) |
2429 |
{ |
2430 |
+diff --git a/lib/scatterlist.c b/lib/scatterlist.c |
2431 |
+index 4ceb05d..2ffcb3c 100644 |
2432 |
+--- a/lib/scatterlist.c |
2433 |
++++ b/lib/scatterlist.c |
2434 |
+@@ -419,7 +419,8 @@ void sg_miter_stop(struct sg_mapping_iter *miter) |
2435 |
+ if (miter->addr) { |
2436 |
+ miter->__offset += miter->consumed; |
2437 |
+ |
2438 |
+- if (miter->__flags & SG_MITER_TO_SG) |
2439 |
++ if ((miter->__flags & SG_MITER_TO_SG) && |
2440 |
++ !PageSlab(miter->page)) |
2441 |
+ flush_kernel_dcache_page(miter->page); |
2442 |
+ |
2443 |
+ if (miter->__flags & SG_MITER_ATOMIC) { |
2444 |
diff --git a/lib/vsprintf.c b/lib/vsprintf.c |
2445 |
index d74c317..1170419 100644 |
2446 |
--- a/lib/vsprintf.c |
2447 |
@@ -89809,7 +91133,7 @@ index f78f898..d7aa843 100644 |
2448 |
|
2449 |
if (__rtnl_register(PF_CAN, RTM_GETROUTE, NULL, cgw_dump_jobs, NULL)) { |
2450 |
diff --git a/net/compat.c b/net/compat.c |
2451 |
-index 8c979cc..2b1960c 100644 |
2452 |
+index 8c979cc..453a165 100644 |
2453 |
--- a/net/compat.c |
2454 |
+++ b/net/compat.c |
2455 |
@@ -71,9 +71,11 @@ int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg) |
2456 |
@@ -89887,7 +91211,22 @@ index 8c979cc..2b1960c 100644 |
2457 |
int fdmax = (kmsg->msg_controllen - sizeof(struct compat_cmsghdr)) / sizeof(int); |
2458 |
int fdnum = scm->fp->count; |
2459 |
struct file **fp = scm->fp->fp; |
2460 |
-@@ -370,7 +372,7 @@ static int do_set_sock_timeout(struct socket *sock, int level, |
2461 |
+@@ -326,14 +328,6 @@ void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm) |
2462 |
+ __scm_destroy(scm); |
2463 |
+ } |
2464 |
+ |
2465 |
+-/* |
2466 |
+- * A struct sock_filter is architecture independent. |
2467 |
+- */ |
2468 |
+-struct compat_sock_fprog { |
2469 |
+- u16 len; |
2470 |
+- compat_uptr_t filter; /* struct sock_filter * */ |
2471 |
+-}; |
2472 |
+- |
2473 |
+ static int do_set_attach_filter(struct socket *sock, int level, int optname, |
2474 |
+ char __user *optval, unsigned int optlen) |
2475 |
+ { |
2476 |
+@@ -370,7 +364,7 @@ static int do_set_sock_timeout(struct socket *sock, int level, |
2477 |
return -EFAULT; |
2478 |
old_fs = get_fs(); |
2479 |
set_fs(KERNEL_DS); |
2480 |
@@ -89896,7 +91235,7 @@ index 8c979cc..2b1960c 100644 |
2481 |
set_fs(old_fs); |
2482 |
|
2483 |
return err; |
2484 |
-@@ -431,7 +433,7 @@ static int do_get_sock_timeout(struct socket *sock, int level, int optname, |
2485 |
+@@ -431,7 +425,7 @@ static int do_get_sock_timeout(struct socket *sock, int level, int optname, |
2486 |
len = sizeof(ktime); |
2487 |
old_fs = get_fs(); |
2488 |
set_fs(KERNEL_DS); |
2489 |
@@ -89905,7 +91244,7 @@ index 8c979cc..2b1960c 100644 |
2490 |
set_fs(old_fs); |
2491 |
|
2492 |
if (!err) { |
2493 |
-@@ -566,7 +568,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname, |
2494 |
+@@ -566,7 +560,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname, |
2495 |
case MCAST_JOIN_GROUP: |
2496 |
case MCAST_LEAVE_GROUP: |
2497 |
{ |
2498 |
@@ -89914,7 +91253,7 @@ index 8c979cc..2b1960c 100644 |
2499 |
struct group_req __user *kgr = |
2500 |
compat_alloc_user_space(sizeof(struct group_req)); |
2501 |
u32 interface; |
2502 |
-@@ -587,7 +589,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname, |
2503 |
+@@ -587,7 +581,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname, |
2504 |
case MCAST_BLOCK_SOURCE: |
2505 |
case MCAST_UNBLOCK_SOURCE: |
2506 |
{ |
2507 |
@@ -89923,7 +91262,7 @@ index 8c979cc..2b1960c 100644 |
2508 |
struct group_source_req __user *kgsr = compat_alloc_user_space( |
2509 |
sizeof(struct group_source_req)); |
2510 |
u32 interface; |
2511 |
-@@ -608,7 +610,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname, |
2512 |
+@@ -608,7 +602,7 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname, |
2513 |
} |
2514 |
case MCAST_MSFILTER: |
2515 |
{ |
2516 |
@@ -89932,7 +91271,7 @@ index 8c979cc..2b1960c 100644 |
2517 |
struct group_filter __user *kgf; |
2518 |
u32 interface, fmode, numsrc; |
2519 |
|
2520 |
-@@ -646,7 +648,7 @@ int compat_mc_getsockopt(struct sock *sock, int level, int optname, |
2521 |
+@@ -646,7 +640,7 @@ int compat_mc_getsockopt(struct sock *sock, int level, int optname, |
2522 |
char __user *optval, int __user *optlen, |
2523 |
int (*getsockopt)(struct sock *, int, int, char __user *, int __user *)) |
2524 |
{ |
2525 |
@@ -89941,7 +91280,7 @@ index 8c979cc..2b1960c 100644 |
2526 |
struct group_filter __user *kgf; |
2527 |
int __user *koptlen; |
2528 |
u32 interface, fmode, numsrc; |
2529 |
-@@ -799,7 +801,7 @@ asmlinkage long compat_sys_socketcall(int call, u32 __user *args) |
2530 |
+@@ -799,7 +793,7 @@ asmlinkage long compat_sys_socketcall(int call, u32 __user *args) |
2531 |
|
2532 |
if (call < SYS_SOCKET || call > SYS_SENDMMSG) |
2533 |
return -EINVAL; |
2534 |
@@ -90150,6 +91489,30 @@ index 2367246..4a0a677 100644 |
2535 |
if (copy_to_user(useraddr, &dump, sizeof(dump))) { |
2536 |
ret = -EFAULT; |
2537 |
goto out; |
2538 |
+diff --git a/net/core/filter.c b/net/core/filter.c |
2539 |
+index 5dea452..d775edc 100644 |
2540 |
+--- a/net/core/filter.c |
2541 |
++++ b/net/core/filter.c |
2542 |
+@@ -39,6 +39,7 @@ |
2543 |
+ #include <linux/filter.h> |
2544 |
+ #include <linux/reciprocal_div.h> |
2545 |
+ #include <linux/ratelimit.h> |
2546 |
++#include <linux/seccomp.h> |
2547 |
+ |
2548 |
+ /* No hurry in this branch */ |
2549 |
+ static void *__load_pointer(const struct sk_buff *skb, int k, unsigned int size) |
2550 |
+@@ -350,6 +351,11 @@ load_b: |
2551 |
+ A = 0; |
2552 |
+ continue; |
2553 |
+ } |
2554 |
++#ifdef CONFIG_SECCOMP_FILTER |
2555 |
++ case BPF_S_ANC_SECCOMP_LD_W: |
2556 |
++ A = seccomp_bpf_load(fentry->k); |
2557 |
++ continue; |
2558 |
++#endif |
2559 |
+ default: |
2560 |
+ WARN_RATELIMIT(1, "Unknown code:%u jt:%u tf:%u k:%u\n", |
2561 |
+ fentry->code, fentry->jt, |
2562 |
diff --git a/net/core/flow.c b/net/core/flow.c |
2563 |
index e318c7e..168b1d0 100644 |
2564 |
--- a/net/core/flow.c |
2565 |
@@ -98042,6 +99405,73 @@ index 69ddb47..be0f0f9 100644 |
2566 |
error = aafs_create(".load", 0640, &aa_fs_profile_load); |
2567 |
if (error) |
2568 |
goto error; |
2569 |
+diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c |
2570 |
+index c1e18ba..7316d77 100644 |
2571 |
+--- a/security/apparmor/domain.c |
2572 |
++++ b/security/apparmor/domain.c |
2573 |
+@@ -395,6 +395,11 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm) |
2574 |
+ new_profile = find_attach(ns, &ns->base.profiles, name); |
2575 |
+ if (!new_profile) |
2576 |
+ goto cleanup; |
2577 |
++ /* |
2578 |
++ * NOTE: Domain transitions from unconfined are allowed |
2579 |
++ * even when no_new_privs is set because this aways results |
2580 |
++ * in a further reduction of permissions. |
2581 |
++ */ |
2582 |
+ goto apply; |
2583 |
+ } |
2584 |
+ |
2585 |
+@@ -455,6 +460,16 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm) |
2586 |
+ /* fail exec */ |
2587 |
+ error = -EACCES; |
2588 |
+ |
2589 |
++ /* |
2590 |
++ * Policy has specified a domain transition, if no_new_privs then |
2591 |
++ * fail the exec. |
2592 |
++ */ |
2593 |
++ if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) { |
2594 |
++ aa_put_profile(new_profile); |
2595 |
++ error = -EPERM; |
2596 |
++ goto cleanup; |
2597 |
++ } |
2598 |
++ |
2599 |
+ if (!new_profile) |
2600 |
+ goto audit; |
2601 |
+ |
2602 |
+@@ -609,6 +624,14 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest) |
2603 |
+ const char *target = NULL, *info = NULL; |
2604 |
+ int error = 0; |
2605 |
+ |
2606 |
++ /* |
2607 |
++ * Fail explicitly requested domain transitions if no_new_privs. |
2608 |
++ * There is no exception for unconfined as change_hat is not |
2609 |
++ * available. |
2610 |
++ */ |
2611 |
++ if (current->no_new_privs) |
2612 |
++ return -EPERM; |
2613 |
++ |
2614 |
+ /* released below */ |
2615 |
+ cred = get_current_cred(); |
2616 |
+ cxt = cred->security; |
2617 |
+@@ -750,6 +773,18 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec, |
2618 |
+ cxt = cred->security; |
2619 |
+ profile = aa_cred_profile(cred); |
2620 |
+ |
2621 |
++ /* |
2622 |
++ * Fail explicitly requested domain transitions if no_new_privs |
2623 |
++ * and not unconfined. |
2624 |
++ * Domain transitions from unconfined are allowed even when |
2625 |
++ * no_new_privs is set because this aways results in a reduction |
2626 |
++ * of permissions. |
2627 |
++ */ |
2628 |
++ if (current->no_new_privs && !unconfined(profile)) { |
2629 |
++ put_cred(cred); |
2630 |
++ return -EPERM; |
2631 |
++ } |
2632 |
++ |
2633 |
+ if (ns_name) { |
2634 |
+ /* released below */ |
2635 |
+ ns = aa_find_namespace(profile->ns, ns_name); |
2636 |
diff --git a/security/apparmor/include/apparmorfs.h b/security/apparmor/include/apparmorfs.h |
2637 |
index cb1e93a..14f955c 100644 |
2638 |
--- a/security/apparmor/include/apparmorfs.h |
2639 |
@@ -98574,7 +100004,7 @@ index 741dd13..ee8043e 100644 |
2640 |
profile->file.dfa = unpack_dfa(e); |
2641 |
if (IS_ERR(profile->file.dfa)) { |
2642 |
diff --git a/security/commoncap.c b/security/commoncap.c |
2643 |
-index 12440ee..e16cba1 100644 |
2644 |
+index 12440ee..2ec6d88 100644 |
2645 |
--- a/security/commoncap.c |
2646 |
+++ b/security/commoncap.c |
2647 |
@@ -29,6 +29,7 @@ |
2648 |
@@ -98640,7 +100070,27 @@ index 12440ee..e16cba1 100644 |
2649 |
/* |
2650 |
* Attempt to get the on-exec apply capability sets for an executable file from |
2651 |
* its xattrs and, if present, apply them to the proposed credentials being |
2652 |
-@@ -585,6 +625,9 @@ int cap_bprm_secureexec(struct linux_binprm *bprm) |
2653 |
+@@ -521,14 +561,17 @@ skip: |
2654 |
+ |
2655 |
+ |
2656 |
+ /* Don't let someone trace a set[ug]id/setpcap binary with the revised |
2657 |
+- * credentials unless they have the appropriate permit |
2658 |
++ * credentials unless they have the appropriate permit. |
2659 |
++ * |
2660 |
++ * In addition, if NO_NEW_PRIVS, then ensure we get no new privs. |
2661 |
+ */ |
2662 |
+ if ((new->euid != old->uid || |
2663 |
+ new->egid != old->gid || |
2664 |
+ !cap_issubset(new->cap_permitted, old->cap_permitted)) && |
2665 |
+ bprm->unsafe & ~LSM_UNSAFE_PTRACE_CAP) { |
2666 |
+ /* downgrade; they get no more than they had, and maybe less */ |
2667 |
+- if (!capable(CAP_SETUID)) { |
2668 |
++ if (!capable(CAP_SETUID) || |
2669 |
++ (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)) { |
2670 |
+ new->euid = new->uid; |
2671 |
+ new->egid = new->gid; |
2672 |
+ } |
2673 |
+@@ -585,6 +628,9 @@ int cap_bprm_secureexec(struct linux_binprm *bprm) |
2674 |
{ |
2675 |
const struct cred *cred = current_cred(); |
2676 |
|
2677 |
@@ -98981,7 +100431,7 @@ index dca1c22..4fa4591 100644 |
2678 |
lock = &avc_cache.slots_lock[hvalue]; |
2679 |
|
2680 |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c |
2681 |
-index 1126c10..3684fc7 100644 |
2682 |
+index 1126c10..e2dad6b 100644 |
2683 |
--- a/security/selinux/hooks.c |
2684 |
+++ b/security/selinux/hooks.c |
2685 |
@@ -94,8 +94,6 @@ |
2686 |
@@ -98993,7 +100443,31 @@ index 1126c10..3684fc7 100644 |
2687 |
/* SECMARK reference count */ |
2688 |
static atomic_t selinux_secmark_refcount = ATOMIC_INIT(0); |
2689 |
|
2690 |
-@@ -5449,7 +5447,7 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer) |
2691 |
+@@ -2000,6 +1998,13 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) |
2692 |
+ new_tsec->sid = old_tsec->exec_sid; |
2693 |
+ /* Reset exec SID on execve. */ |
2694 |
+ new_tsec->exec_sid = 0; |
2695 |
++ |
2696 |
++ /* |
2697 |
++ * Minimize confusion: if no_new_privs and a transition is |
2698 |
++ * explicitly requested, then fail the exec. |
2699 |
++ */ |
2700 |
++ if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) |
2701 |
++ return -EPERM; |
2702 |
+ } else { |
2703 |
+ /* Check for a default transition on this program. */ |
2704 |
+ rc = security_transition_sid(old_tsec->sid, isec->sid, |
2705 |
+@@ -2012,7 +2017,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) |
2706 |
+ COMMON_AUDIT_DATA_INIT(&ad, PATH); |
2707 |
+ ad.u.path = bprm->file->f_path; |
2708 |
+ |
2709 |
+- if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) |
2710 |
++ if ((bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) || |
2711 |
++ (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)) |
2712 |
+ new_tsec->sid = old_tsec->sid; |
2713 |
+ |
2714 |
+ if (new_tsec->sid == old_tsec->sid) { |
2715 |
+@@ -5449,7 +5455,7 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer) |
2716 |
|
2717 |
#endif |
2718 |
|
2719 |
@@ -99002,7 +100476,7 @@ index 1126c10..3684fc7 100644 |
2720 |
.name = "selinux", |
2721 |
|
2722 |
.ptrace_access_check = selinux_ptrace_access_check, |
2723 |
-@@ -5795,6 +5793,9 @@ static void selinux_nf_ip_exit(void) |
2724 |
+@@ -5795,6 +5801,9 @@ static void selinux_nf_ip_exit(void) |
2725 |
#ifdef CONFIG_SECURITY_SELINUX_DISABLE |
2726 |
static int selinux_disabled; |
2727 |
|
2728 |
@@ -99012,7 +100486,7 @@ index 1126c10..3684fc7 100644 |
2729 |
int selinux_disable(void) |
2730 |
{ |
2731 |
if (ss_initialized) { |
2732 |
-@@ -5812,7 +5813,9 @@ int selinux_disable(void) |
2733 |
+@@ -5812,7 +5821,9 @@ int selinux_disable(void) |
2734 |
selinux_disabled = 1; |
2735 |
selinux_enabled = 0; |