This patch introduces two configuration options,
UNPRIVILEGED_BPF_BOOTPARAM and UNPRIVILEGED_BPF_BOOTPARAM_VALUE, that
allow configuring the initial value of kernel.unprivileged_bpf_disabled
sysctl knob, which is useful for the cases when disabling unprivileged
bpf() access during the early boot is desirable.

Signed-off-by: Eugene Syromiatnikov <e...@redhat.com>
---
 Documentation/admin-guide/kernel-parameters.txt |  8 +++++++
 init/Kconfig                                    | 31 +++++++++++++++++++++++++
 kernel/bpf/syscall.c                            | 16 +++++++++++++
 3 files changed, 55 insertions(+)

diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index 11fc28e..aa8e831 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -4355,6 +4355,14 @@
        unknown_nmi_panic
                        [X86] Cause panic on unknown NMI.
 
+       unprivileged_bpf_disabled=
+                       Format: { "0" | "1" }
+                       Sets initial value of kernel.unprivileged_bpf_disabled
+                       sysctl knob.
+                       0 - unprivileged bpf() syscall access enabled.
+                       1 - unprivileged bpf() syscall access disabled.
+                       Default value is set via kernel config option.
+
        usbcore.authorized_default=
                        [USB] Default USB device authorization:
                        (default -1 = authorized except for wireless USB,
diff --git a/init/Kconfig b/init/Kconfig
index 480a4f2..1403a3e 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1404,6 +1404,37 @@ config BPF_JIT_ALWAYS_ON
          Enables BPF JIT and removes BPF interpreter to avoid
          speculative execution of BPF instructions by the interpreter
 
+config UNPRIVILEGED_BPF_BOOTPARAM
+       bool "Unprivileged bpf() boot parameter"
+       depends on BPF_SYSCALL
+       default n
+       help
+         This option adds a kernel parameter 'unprivileged_bpf_disabled'
+         that allows configuring default state of the
+         kernel.unprivileged_bpf_disabled sysctl knob.
+         If this option is selected, unprivileged access to the bpf() syscall
+         can be disabled with unprivileged_bpf_disabled=1 on the kernel command
+         line.  The purpose of this option is to allow disabling unprivileged
+         bpf() syscall access during the early boot.
+
+         If you are unsure how to answer this question, answer N.
+
+config UNPRIVILEGED_BPF_BOOTPARAM_VALUE
+       int "Unprivileged bpf() boot parameter default value"
+       depends on UNPRIVILEGED_BPF_BOOTPARAM
+       range 0 1
+       default 0
+       help
+         This option sets the default value for the kernel parameter
+         'unprivileged_bpf_disabled', which allows disabling unprivileged bpf()
+         syscall access at boot.  If this option is set to 0 (zero), the
+         unprivileged bpf() boot kernel parameter will default to 0, allowing
+         unprivileged bpf() syscall access at bootup.  If this option is
+         set to 1 (one), the unprivileged bpf() kernel parameter will default
+         to 1, disabling unprivileged bpf() syscall access at bootup.
+
+         If you are unsure how to answer this question, answer 0.
+
 config USERFAULTFD
        bool "Enable userfaultfd() system call"
        select ANON_INODES
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index bfcde94..fdc5fd9 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -29,6 +29,7 @@
 #include <linux/ctype.h>
 #include <linux/btf.h>
 #include <linux/nospec.h>
+#include <linux/init.h>
 
 #define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PROG_ARRAY || \
                           (map)->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || \
@@ -45,7 +46,22 @@ static DEFINE_SPINLOCK(prog_idr_lock);
 static DEFINE_IDR(map_idr);
 static DEFINE_SPINLOCK(map_idr_lock);
 
+#ifdef CONFIG_UNPRIVILEGED_BPF_BOOTPARAM
+int sysctl_unprivileged_bpf_disabled __read_mostly =
+       CONFIG_UNPRIVILEGED_BPF_BOOTPARAM_VALUE;
+
+static int __init unprivileged_bpf_setup(char *str)
+{
+       unsigned long disabled;
+
+       if (!kstrtoul(str, 0, &disabled))
+               sysctl_unprivileged_bpf_disabled = !!disabled;
+       return 1;
+}
+__setup("unprivileged_bpf_disabled=", unprivileged_bpf_setup);
+#else /* !CONFIG_UNPRIVILEGED_BPF_BOOTPARAM */
 int sysctl_unprivileged_bpf_disabled __read_mostly;
+#endif /* CONFIG_UNPRIVILEGED_BPF_BOOTPARAM */
 
 static const struct bpf_map_ops * const bpf_map_types[] = {
 #define BPF_PROG_TYPE(_id, _ops)
-- 
2.1.4

Reply via email to