All of lore.kernel.org
 help / color / mirror / Atom feed
From: Edwin Peer <epeer@juniper.net>
To: "netdev@vger.kernel.org" <netdev@vger.kernel.org>
Cc: "ast@kernel.org" <ast@kernel.org>,
	"daniel@iogearbox.net" <daniel@iogearbox.net>,
	Edwin Peer <epeer@juniper.net>
Subject: [RFC PATCH bpf-next 1/2] bpf: defer capability checks until program attach
Date: Thu, 19 Dec 2019 01:36:27 +0000	[thread overview]
Message-ID: <20191219013534.125342-2-epeer@juniper.net> (raw)
In-Reply-To: <20191219013534.125342-1-epeer@juniper.net>

The intent of this patch is not to change the effective permissions
required to run a BPF program of a given type in the kernel. The
actual check, however, is now deferred until attach time. For
example, an XDP program will fail to bind to a device with EPERM if
the program was not originally loaded under CAP_SYS_ADMIN.

This is achieved by remembering whether the program was loaded by a
privileged user within the BPF program's context. The upshot of this
is that BPF_PROG_LOAD is no longer a privileged operation, thereby
exposing access to the verifier to normal users for all program
types.

Signed-off-by: Edwin Peer <epeer@juniper.net>
---
 include/linux/filter.h |  3 ++-
 kernel/bpf/syscall.c   | 11 +++++++----
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/include/linux/filter.h b/include/linux/filter.h
index a141cb07e76a..1957eea62bed 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -534,7 +534,8 @@ struct bpf_prog {
 				is_func:1,	/* program is a bpf function */
 				kprobe_override:1, /* Do we override a kprobe? */
 				has_callchain_buf:1, /* callchain buffer allocated? */
-				enforce_expected_attach_type:1; /* Enforce expected_attach_type checking at attach time */
+				enforce_expected_attach_type:1, /* Enforce expected_attach_type checking at attach time */
+				privileged_load:1; /* Loaded with CAP_SYS_ADMIN */
 	enum bpf_prog_type	type;		/* Type of BPF program */
 	enum bpf_attach_type	expected_attach_type; /* For some prog types */
 	u32			len;		/* Number of filter blocks */
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index e3461ec59570..8e56768ebc06 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -1586,6 +1586,11 @@ static struct bpf_prog *__bpf_prog_get(u32 ufd, enum bpf_prog_type *attach_type,
 	prog = ____bpf_prog_get(f);
 	if (IS_ERR(prog))
 		return prog;
+	if (prog->type != BPF_PROG_TYPE_SOCKET_FILTER &&
+	    prog->type != BPF_PROG_TYPE_CGROUP_SKB && !prog->privileged_load) {
+		prog = ERR_PTR(-EPERM);
+		goto out;
+	}
 	if (!bpf_prog_get_ok(prog, attach_type, attach_drv)) {
 		prog = ERR_PTR(-EINVAL);
 		goto out;
@@ -1733,10 +1738,6 @@ static int bpf_prog_load(union bpf_attr *attr, union bpf_attr __user *uattr)
 	if (attr->insn_cnt == 0 ||
 	    attr->insn_cnt > (capable(CAP_SYS_ADMIN) ? BPF_COMPLEXITY_LIMIT_INSNS : BPF_MAXINSNS))
 		return -E2BIG;
-	if (type != BPF_PROG_TYPE_SOCKET_FILTER &&
-	    type != BPF_PROG_TYPE_CGROUP_SKB &&
-	    !capable(CAP_SYS_ADMIN))
-		return -EPERM;
 
 	bpf_prog_load_fixup_attach_type(attr);
 	if (bpf_prog_load_check_attach(type, attr->expected_attach_type,
@@ -1749,6 +1750,8 @@ static int bpf_prog_load(union bpf_attr *attr, union bpf_attr __user *uattr)
 	if (!prog)
 		return -ENOMEM;
 
+	prog->privileged_load = capable(CAP_SYS_ADMIN);
+
 	prog->expected_attach_type = attr->expected_attach_type;
 	prog->aux->attach_btf_id = attr->attach_btf_id;
 	if (attr->attach_prog_fd) {
-- 
2.24.1

  reply	other threads:[~2019-12-19  2:24 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-19  1:36 [RFC PATCH bpf-next 0/2] unprivileged BPF_PROG_TEST_RUN Edwin Peer
2019-12-19  1:36 ` Edwin Peer [this message]
2019-12-19  1:36 ` [RFC PATCH bpf-next 2/2] bpf: relax CAP_SYS_ADMIN requirement for BPF_PROG_TEST_RUN Edwin Peer
2019-12-19  7:19 ` [RFC PATCH bpf-next 0/2] unprivileged BPF_PROG_TEST_RUN Y Song
2019-12-19 14:50   ` Edwin Peer
2019-12-19 15:47     ` Daniel Borkmann
2019-12-19 17:05       ` Edwin Peer
2019-12-19 19:26         ` Alexei Starovoitov
2019-12-19 20:06           ` Edwin Peer
2019-12-19 21:52             ` Alexei Starovoitov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191219013534.125342-2-epeer@juniper.net \
    --to=epeer@juniper.net \
    --cc=ast@kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.