[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210126165104.891536-2-sdf@google.com>
Date: Tue, 26 Jan 2021 08:51:04 -0800
From: Stanislav Fomichev <sdf@...gle.com>
To: netdev@...r.kernel.org, bpf@...r.kernel.org
Cc: ast@...nel.org, daniel@...earbox.net,
Stanislav Fomichev <sdf@...gle.com>,
Andrey Ignatov <rdna@...com>, Martin KaFai Lau <kafai@...com>
Subject: [PATCH bpf-next v3 2/2] selftests/bpf: verify that rebinding to port
< 1024 from BPF works
Return 3 to indicate that permission check for port 111
should be skipped.
Cc: Andrey Ignatov <rdna@...com>
Cc: Martin KaFai Lau <kafai@...com>
Signed-off-by: Stanislav Fomichev <sdf@...gle.com>
---
.../selftests/bpf/prog_tests/bind_perm.c | 80 +++++++++++++++++++
tools/testing/selftests/bpf/progs/bind_perm.c | 36 +++++++++
2 files changed, 116 insertions(+)
create mode 100644 tools/testing/selftests/bpf/prog_tests/bind_perm.c
create mode 100644 tools/testing/selftests/bpf/progs/bind_perm.c
diff --git a/tools/testing/selftests/bpf/prog_tests/bind_perm.c b/tools/testing/selftests/bpf/prog_tests/bind_perm.c
new file mode 100644
index 000000000000..763de148e511
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/bind_perm.c
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <test_progs.h>
+#include "bind_perm.skel.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/capability.h>
+
+static int duration;
+
+void try_bind(int port, int expected_errno)
+{
+ struct sockaddr_in sin = {};
+ int fd = -1;
+
+ fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (CHECK(fd < 0, "fd", "errno %d", errno))
+ goto close_socket;
+
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(port);
+
+ errno = 0;
+ bind(fd, (struct sockaddr *)&sin, sizeof(sin));
+ ASSERT_EQ(errno, expected_errno, "bind");
+
+close_socket:
+ if (fd >= 0)
+ close(fd);
+}
+
+void cap_net_bind_service(cap_flag_value_t flag)
+{
+ const cap_value_t cap_net_bind_service = CAP_NET_BIND_SERVICE;
+ cap_t caps;
+
+ caps = cap_get_proc();
+ if (CHECK(!caps, "cap_get_proc", "errno %d", errno))
+ goto free_caps;
+
+ if (CHECK(cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_net_bind_service,
+ flag),
+ "cap_set_flag", "errno %d", errno))
+ goto free_caps;
+
+ if (CHECK(cap_set_proc(caps), "cap_set_proc", "errno %d", errno))
+ goto free_caps;
+
+free_caps:
+ if (CHECK(cap_free(caps), "cap_free", "errno %d", errno))
+ goto free_caps;
+}
+
+void test_bind_perm(void)
+{
+ struct bind_perm *skel;
+ int cgroup_fd;
+
+ cgroup_fd = test__join_cgroup("/bind_perm");
+ if (CHECK(cgroup_fd < 0, "cg-join", "errno %d", errno))
+ return;
+
+ skel = bind_perm__open_and_load();
+ if (!ASSERT_OK_PTR(skel, "skel"))
+ goto close_cgroup_fd;
+
+ skel->links.bind_v4_prog = bpf_program__attach_cgroup(skel->progs.bind_v4_prog, cgroup_fd);
+ if (!ASSERT_OK_PTR(skel, "bind_v4_prog"))
+ goto close_skeleton;
+
+ cap_net_bind_service(CAP_CLEAR);
+ try_bind(110, EACCES);
+ try_bind(111, 0);
+ cap_net_bind_service(CAP_SET);
+
+close_skeleton:
+ bind_perm__destroy(skel);
+close_cgroup_fd:
+ close(cgroup_fd);
+}
diff --git a/tools/testing/selftests/bpf/progs/bind_perm.c b/tools/testing/selftests/bpf/progs/bind_perm.c
new file mode 100644
index 000000000000..e89bd264ed26
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/bind_perm.c
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/stddef.h>
+#include <linux/bpf.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_endian.h>
+
+SEC("cgroup/bind4")
+int bind_v4_prog(struct bpf_sock_addr *ctx)
+{
+ struct bpf_sock *sk;
+ __u32 user_ip4;
+ __u16 user_port;
+
+ sk = ctx->sk;
+ if (!sk)
+ return 0;
+
+ if (sk->family != AF_INET)
+ return 0;
+
+ if (ctx->type != SOCK_STREAM)
+ return 0;
+
+ /* Return 1 OR'ed with the first bit set to indicate
+ * that CAP_NET_BIND_SERVICE should be bypassed.
+ */
+ if (ctx->user_port == bpf_htons(111))
+ return (1 | 2);
+
+ return 1;
+}
+
+char _license[] SEC("license") = "GPL";
--
2.30.0.280.ga3ce27912f-goog
Powered by blists - more mailing lists