Commit 2e4a30983b0f9b19b59e38bbf7427d7fdd480d98

Authored by Daniel Borkmann
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 },