Commit 2e4a30983b0f9b19b59e38bbf7427d7fdd480d98
Committed by
Alexei Starovoitov
1 parent
fa9dd599b4
bpf: restrict access to core bpf sysctls
Given BPF reaches far beyond just networking these days, it was never intended to allow setting and in some cases reading those knobs out of a user namespace root running without CAP_SYS_ADMIN, thus tighten such access. Also the bpf_jit_enable = 2 debugging mode should only be allowed if kptr_restrict is not set since it otherwise can leak addresses to the kernel log. Dump a note to the kernel log that this is for debugging JITs only when enabled. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Showing 1 changed file with 43 additions and 3 deletions Side-by-side Diff
net/core/sysctl_net_core.c
... | ... | @@ -251,6 +251,46 @@ |
251 | 251 | return proc_dostring(&fake_table, write, buffer, lenp, ppos); |
252 | 252 | } |
253 | 253 | |
254 | +#ifdef CONFIG_BPF_JIT | |
255 | +static int proc_dointvec_minmax_bpf_enable(struct ctl_table *table, int write, | |
256 | + void __user *buffer, size_t *lenp, | |
257 | + loff_t *ppos) | |
258 | +{ | |
259 | + int ret, jit_enable = *(int *)table->data; | |
260 | + struct ctl_table tmp = *table; | |
261 | + | |
262 | + if (write && !capable(CAP_SYS_ADMIN)) | |
263 | + return -EPERM; | |
264 | + | |
265 | + tmp.data = &jit_enable; | |
266 | + ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos); | |
267 | + if (write && !ret) { | |
268 | + if (jit_enable < 2 || | |
269 | + (jit_enable == 2 && bpf_dump_raw_ok())) { | |
270 | + *(int *)table->data = jit_enable; | |
271 | + if (jit_enable == 2) | |
272 | + pr_warn("bpf_jit_enable = 2 was set! NEVER use this in production, only for JIT debugging!\n"); | |
273 | + } else { | |
274 | + ret = -EPERM; | |
275 | + } | |
276 | + } | |
277 | + return ret; | |
278 | +} | |
279 | + | |
280 | +# ifdef CONFIG_HAVE_EBPF_JIT | |
281 | +static int | |
282 | +proc_dointvec_minmax_bpf_restricted(struct ctl_table *table, int write, | |
283 | + void __user *buffer, size_t *lenp, | |
284 | + loff_t *ppos) | |
285 | +{ | |
286 | + if (!capable(CAP_SYS_ADMIN)) | |
287 | + return -EPERM; | |
288 | + | |
289 | + return proc_dointvec_minmax(table, write, buffer, lenp, ppos); | |
290 | +} | |
291 | +# endif | |
292 | +#endif | |
293 | + | |
254 | 294 | static struct ctl_table net_core_table[] = { |
255 | 295 | #ifdef CONFIG_NET |
256 | 296 | { |
... | ... | @@ -326,7 +366,7 @@ |
326 | 366 | .data = &bpf_jit_enable, |
327 | 367 | .maxlen = sizeof(int), |
328 | 368 | .mode = 0644, |
329 | - .proc_handler = proc_dointvec_minmax, | |
369 | + .proc_handler = proc_dointvec_minmax_bpf_enable, | |
330 | 370 | # ifdef CONFIG_BPF_JIT_ALWAYS_ON |
331 | 371 | .extra1 = &one, |
332 | 372 | .extra2 = &one, |
... | ... | @@ -341,7 +381,7 @@ |
341 | 381 | .data = &bpf_jit_harden, |
342 | 382 | .maxlen = sizeof(int), |
343 | 383 | .mode = 0600, |
344 | - .proc_handler = proc_dointvec_minmax, | |
384 | + .proc_handler = proc_dointvec_minmax_bpf_restricted, | |
345 | 385 | .extra1 = &zero, |
346 | 386 | .extra2 = &two, |
347 | 387 | }, |
... | ... | @@ -350,7 +390,7 @@ |
350 | 390 | .data = &bpf_jit_kallsyms, |
351 | 391 | .maxlen = sizeof(int), |
352 | 392 | .mode = 0600, |
353 | - .proc_handler = proc_dointvec_minmax, | |
393 | + .proc_handler = proc_dointvec_minmax_bpf_restricted, | |
354 | 394 | .extra1 = &zero, |
355 | 395 | .extra2 = &one, |
356 | 396 | }, |