Skip to content

Commit 8c15bfb

Browse files
borkmanngregkh
authored andcommitted
bpf: Add kconfig knob for disabling unpriv bpf by default
commit 08389d8 upstream. Add a kconfig knob which allows for unprivileged bpf to be disabled by default. If set, the knob sets /proc/sys/kernel/unprivileged_bpf_disabled to value of 2. This still allows a transition of 2 -> {0,1} through an admin. Similarly, this also still keeps 1 -> {1} behavior intact, so that once set to permanently disabled, it cannot be undone aside from a reboot. We've also added extra2 with max of 2 for the procfs handler, so that an admin still has a chance to toggle between 0 <-> 2. Either way, as an additional alternative, applications can make use of CAP_BPF that we added a while ago. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://lore.kernel.org/bpf/74ec548079189e4e4dffaeb42b8987bb3c852eee.1620765074.git.daniel@iogearbox.net Cc: Salvatore Bonaccorso <carnil@debian.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent d8a5b13 commit 8c15bfb

4 files changed

Lines changed: 50 additions & 9 deletions

File tree

Documentation/admin-guide/sysctl/kernel.rst

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,11 +1457,22 @@ unprivileged_bpf_disabled
14571457
=========================
14581458

14591459
Writing 1 to this entry will disable unprivileged calls to ``bpf()``;
1460-
once disabled, calling ``bpf()`` without ``CAP_SYS_ADMIN`` will return
1461-
``-EPERM``.
1460+
once disabled, calling ``bpf()`` without ``CAP_SYS_ADMIN`` or ``CAP_BPF``
1461+
will return ``-EPERM``. Once set to 1, this can't be cleared from the
1462+
running kernel anymore.
14621463

1463-
Once set, this can't be cleared.
1464+
Writing 2 to this entry will also disable unprivileged calls to ``bpf()``,
1465+
however, an admin can still change this setting later on, if needed, by
1466+
writing 0 or 1 to this entry.
14641467

1468+
If ``BPF_UNPRIV_DEFAULT_OFF`` is enabled in the kernel config, then this
1469+
entry will default to 2 instead of 0.
1470+
1471+
= =============================================================
1472+
0 Unprivileged calls to ``bpf()`` are enabled
1473+
1 Unprivileged calls to ``bpf()`` are disabled without recovery
1474+
2 Unprivileged calls to ``bpf()`` are disabled
1475+
= =============================================================
14651476

14661477
watchdog
14671478
========

init/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1722,6 +1722,16 @@ config BPF_JIT_DEFAULT_ON
17221722
def_bool ARCH_WANT_DEFAULT_BPF_JIT || BPF_JIT_ALWAYS_ON
17231723
depends on HAVE_EBPF_JIT && BPF_JIT
17241724

1725+
config BPF_UNPRIV_DEFAULT_OFF
1726+
bool "Disable unprivileged BPF by default"
1727+
depends on BPF_SYSCALL
1728+
help
1729+
Disables unprivileged BPF by default by setting the corresponding
1730+
/proc/sys/kernel/unprivileged_bpf_disabled knob to 2. An admin can
1731+
still reenable it by setting it to 0 later on, or permanently
1732+
disable it by setting it to 1 (from which no other transition to
1733+
0 is possible anymore).
1734+
17251735
source "kernel/bpf/preload/Kconfig"
17261736

17271737
config USERFAULTFD

kernel/bpf/syscall.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ static DEFINE_SPINLOCK(map_idr_lock);
5050
static DEFINE_IDR(link_idr);
5151
static DEFINE_SPINLOCK(link_idr_lock);
5252

53-
int sysctl_unprivileged_bpf_disabled __read_mostly;
53+
int sysctl_unprivileged_bpf_disabled __read_mostly =
54+
IS_BUILTIN(CONFIG_BPF_UNPRIV_DEFAULT_OFF) ? 2 : 0;
5455

5556
static const struct bpf_map_ops * const bpf_map_types[] = {
5657
#define BPF_PROG_TYPE(_id, _name, prog_ctx_type, kern_ctx_type)

kernel/sysctl.c

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,27 @@ static int bpf_stats_handler(struct ctl_table *table, int write,
233233
mutex_unlock(&bpf_stats_enabled_mutex);
234234
return ret;
235235
}
236-
#endif
236+
237+
static int bpf_unpriv_handler(struct ctl_table *table, int write,
238+
void *buffer, size_t *lenp, loff_t *ppos)
239+
{
240+
int ret, unpriv_enable = *(int *)table->data;
241+
bool locked_state = unpriv_enable == 1;
242+
struct ctl_table tmp = *table;
243+
244+
if (write && !capable(CAP_SYS_ADMIN))
245+
return -EPERM;
246+
247+
tmp.data = &unpriv_enable;
248+
ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
249+
if (write && !ret) {
250+
if (locked_state && unpriv_enable != 1)
251+
return -EPERM;
252+
*(int *)table->data = unpriv_enable;
253+
}
254+
return ret;
255+
}
256+
#endif /* CONFIG_BPF_SYSCALL && CONFIG_SYSCTL */
237257

238258
/*
239259
* /proc/sys support
@@ -2626,10 +2646,9 @@ static struct ctl_table kern_table[] = {
26262646
.data = &sysctl_unprivileged_bpf_disabled,
26272647
.maxlen = sizeof(sysctl_unprivileged_bpf_disabled),
26282648
.mode = 0644,
2629-
/* only handle a transition from default "0" to "1" */
2630-
.proc_handler = proc_dointvec_minmax,
2631-
.extra1 = SYSCTL_ONE,
2632-
.extra2 = SYSCTL_ONE,
2649+
.proc_handler = bpf_unpriv_handler,
2650+
.extra1 = SYSCTL_ZERO,
2651+
.extra2 = &two,
26332652
},
26342653
{
26352654
.procname = "bpf_stats_enabled",

0 commit comments

Comments
 (0)