diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/lib/bpf/README.rst | 14 | ||||
-rw-r--r-- | tools/testing/selftests/bpf/cgroup_helpers.c | 6 | ||||
-rw-r--r-- | tools/testing/selftests/bpf/test_cgroup_storage.c | 2 | ||||
-rw-r--r-- | tools/testing/selftests/bpf/test_dev_cgroup.c | 2 | ||||
-rw-r--r-- | tools/testing/selftests/bpf/test_netcnt.c | 2 | ||||
-rw-r--r-- | tools/testing/selftests/bpf/test_skb_cgroup_id_user.c | 2 | ||||
-rw-r--r-- | tools/testing/selftests/bpf/test_sock.c | 2 | ||||
-rw-r--r-- | tools/testing/selftests/bpf/test_sock_addr.c | 55 | ||||
-rw-r--r-- | tools/testing/selftests/bpf/test_socket_cookie.c | 2 | ||||
-rw-r--r-- | tools/testing/selftests/bpf/test_tcpbpf_user.c | 2 | ||||
-rw-r--r-- | tools/testing/selftests/bpf/test_tcpnotify_user.c | 2 | ||||
-rw-r--r-- | tools/testing/selftests/bpf/test_verifier.c | 120 |
12 files changed, 196 insertions, 15 deletions
diff --git a/tools/lib/bpf/README.rst b/tools/lib/bpf/README.rst index 056f38310722..607aae40f4ed 100644 --- a/tools/lib/bpf/README.rst +++ b/tools/lib/bpf/README.rst @@ -132,6 +132,20 @@ For example, if current state of ``libbpf.map`` is: Format of version script and ways to handle ABI changes, including incompatible ones, described in details in [1]. +Stand-alone build +================= + +Under https://github.com/libbpf/libbpf there is a (semi-)automated +mirror of the mainline's version of libbpf for a stand-alone build. + +However, all changes to libbpf's code base must be upstreamed through +the mainline kernel tree. + +License +======= + +libbpf is dual-licensed under LGPL 2.1 and BSD 2-Clause. + Links ===== diff --git a/tools/testing/selftests/bpf/cgroup_helpers.c b/tools/testing/selftests/bpf/cgroup_helpers.c index cf16948aad4a..6692a40a6979 100644 --- a/tools/testing/selftests/bpf/cgroup_helpers.c +++ b/tools/testing/selftests/bpf/cgroup_helpers.c @@ -155,7 +155,7 @@ void cleanup_cgroup_environment(void) * This function creates a cgroup under the top level workdir and returns the * file descriptor. It is idempotent. * - * On success, it returns the file descriptor. On failure it returns 0. + * On success, it returns the file descriptor. On failure it returns -1. * If there is a failure, it prints the error to stderr. */ int create_and_get_cgroup(const char *path) @@ -166,13 +166,13 @@ int create_and_get_cgroup(const char *path) format_cgroup_path(cgroup_path, path); if (mkdir(cgroup_path, 0777) && errno != EEXIST) { log_err("mkdiring cgroup %s .. %s", path, cgroup_path); - return 0; + return -1; } fd = open(cgroup_path, O_RDONLY); if (fd < 0) { log_err("Opening Cgroup"); - return 0; + return -1; } return fd; diff --git a/tools/testing/selftests/bpf/test_cgroup_storage.c b/tools/testing/selftests/bpf/test_cgroup_storage.c index f44834155f25..2fc4625c1a15 100644 --- a/tools/testing/selftests/bpf/test_cgroup_storage.c +++ b/tools/testing/selftests/bpf/test_cgroup_storage.c @@ -81,7 +81,7 @@ int main(int argc, char **argv) /* Create a cgroup, get fd, and join it */ cgroup_fd = create_and_get_cgroup(TEST_CGROUP); - if (!cgroup_fd) { + if (cgroup_fd < 0) { printf("Failed to create test cgroup\n"); goto err; } diff --git a/tools/testing/selftests/bpf/test_dev_cgroup.c b/tools/testing/selftests/bpf/test_dev_cgroup.c index 9c8b50bac7e0..76e4993b7c16 100644 --- a/tools/testing/selftests/bpf/test_dev_cgroup.c +++ b/tools/testing/selftests/bpf/test_dev_cgroup.c @@ -43,7 +43,7 @@ int main(int argc, char **argv) /* Create a cgroup, get fd, and join it */ cgroup_fd = create_and_get_cgroup(TEST_CGROUP); - if (!cgroup_fd) { + if (cgroup_fd < 0) { printf("Failed to create test cgroup\n"); goto err; } diff --git a/tools/testing/selftests/bpf/test_netcnt.c b/tools/testing/selftests/bpf/test_netcnt.c index 44ed7f29f8ab..c1da5404454a 100644 --- a/tools/testing/selftests/bpf/test_netcnt.c +++ b/tools/testing/selftests/bpf/test_netcnt.c @@ -65,7 +65,7 @@ int main(int argc, char **argv) /* Create a cgroup, get fd, and join it */ cgroup_fd = create_and_get_cgroup(TEST_CGROUP); - if (!cgroup_fd) { + if (cgroup_fd < 0) { printf("Failed to create test cgroup\n"); goto err; } diff --git a/tools/testing/selftests/bpf/test_skb_cgroup_id_user.c b/tools/testing/selftests/bpf/test_skb_cgroup_id_user.c index c121cc59f314..9220747c069d 100644 --- a/tools/testing/selftests/bpf/test_skb_cgroup_id_user.c +++ b/tools/testing/selftests/bpf/test_skb_cgroup_id_user.c @@ -164,7 +164,7 @@ int main(int argc, char **argv) goto err; cgfd = create_and_get_cgroup(CGROUP_PATH); - if (!cgfd) + if (cgfd < 0) goto err; if (join_cgroup(CGROUP_PATH)) diff --git a/tools/testing/selftests/bpf/test_sock.c b/tools/testing/selftests/bpf/test_sock.c index b8ebe2f58074..561ffb6d6433 100644 --- a/tools/testing/selftests/bpf/test_sock.c +++ b/tools/testing/selftests/bpf/test_sock.c @@ -458,7 +458,7 @@ int main(int argc, char **argv) goto err; cgfd = create_and_get_cgroup(CG_PATH); - if (!cgfd) + if (cgfd < 0) goto err; if (join_cgroup(CG_PATH)) diff --git a/tools/testing/selftests/bpf/test_sock_addr.c b/tools/testing/selftests/bpf/test_sock_addr.c index 73b7493d4120..3f110eaaf29c 100644 --- a/tools/testing/selftests/bpf/test_sock_addr.c +++ b/tools/testing/selftests/bpf/test_sock_addr.c @@ -44,6 +44,7 @@ #define SERV6_V4MAPPED_IP "::ffff:192.168.0.4" #define SRC6_IP "::1" #define SRC6_REWRITE_IP "::6" +#define WILDCARD6_IP "::" #define SERV6_PORT 6060 #define SERV6_REWRITE_PORT 6666 @@ -85,12 +86,14 @@ static int bind4_prog_load(const struct sock_addr_test *test); static int bind6_prog_load(const struct sock_addr_test *test); static int connect4_prog_load(const struct sock_addr_test *test); static int connect6_prog_load(const struct sock_addr_test *test); +static int sendmsg_allow_prog_load(const struct sock_addr_test *test); static int sendmsg_deny_prog_load(const struct sock_addr_test *test); static int sendmsg4_rw_asm_prog_load(const struct sock_addr_test *test); static int sendmsg4_rw_c_prog_load(const struct sock_addr_test *test); static int sendmsg6_rw_asm_prog_load(const struct sock_addr_test *test); static int sendmsg6_rw_c_prog_load(const struct sock_addr_test *test); static int sendmsg6_rw_v4mapped_prog_load(const struct sock_addr_test *test); +static int sendmsg6_rw_wildcard_prog_load(const struct sock_addr_test *test); static struct sock_addr_test tests[] = { /* bind */ @@ -463,6 +466,34 @@ static struct sock_addr_test tests[] = { SYSCALL_ENOTSUPP, }, { + "sendmsg6: set dst IP = [::] (BSD'ism)", + sendmsg6_rw_wildcard_prog_load, + BPF_CGROUP_UDP6_SENDMSG, + BPF_CGROUP_UDP6_SENDMSG, + AF_INET6, + SOCK_DGRAM, + SERV6_IP, + SERV6_PORT, + SERV6_REWRITE_IP, + SERV6_REWRITE_PORT, + SRC6_REWRITE_IP, + SUCCESS, + }, + { + "sendmsg6: preserve dst IP = [::] (BSD'ism)", + sendmsg_allow_prog_load, + BPF_CGROUP_UDP6_SENDMSG, + BPF_CGROUP_UDP6_SENDMSG, + AF_INET6, + SOCK_DGRAM, + WILDCARD6_IP, + SERV6_PORT, + SERV6_REWRITE_IP, + SERV6_PORT, + SRC6_IP, + SUCCESS, + }, + { "sendmsg6: deny call", sendmsg_deny_prog_load, BPF_CGROUP_UDP6_SENDMSG, @@ -734,16 +765,27 @@ static int connect6_prog_load(const struct sock_addr_test *test) return load_path(test, CONNECT6_PROG_PATH); } -static int sendmsg_deny_prog_load(const struct sock_addr_test *test) +static int sendmsg_ret_only_prog_load(const struct sock_addr_test *test, + int32_t rc) { struct bpf_insn insns[] = { - /* return 0 */ - BPF_MOV64_IMM(BPF_REG_0, 0), + /* return rc */ + BPF_MOV64_IMM(BPF_REG_0, rc), BPF_EXIT_INSN(), }; return load_insns(test, insns, sizeof(insns) / sizeof(struct bpf_insn)); } +static int sendmsg_allow_prog_load(const struct sock_addr_test *test) +{ + return sendmsg_ret_only_prog_load(test, /*rc*/ 1); +} + +static int sendmsg_deny_prog_load(const struct sock_addr_test *test) +{ + return sendmsg_ret_only_prog_load(test, /*rc*/ 0); +} + static int sendmsg4_rw_asm_prog_load(const struct sock_addr_test *test) { struct sockaddr_in dst4_rw_addr; @@ -864,6 +906,11 @@ static int sendmsg6_rw_v4mapped_prog_load(const struct sock_addr_test *test) return sendmsg6_rw_dst_asm_prog_load(test, SERV6_V4MAPPED_IP); } +static int sendmsg6_rw_wildcard_prog_load(const struct sock_addr_test *test) +{ + return sendmsg6_rw_dst_asm_prog_load(test, WILDCARD6_IP); +} + static int sendmsg6_rw_c_prog_load(const struct sock_addr_test *test) { return load_path(test, SENDMSG6_PROG_PATH); @@ -1395,7 +1442,7 @@ int main(int argc, char **argv) goto err; cgfd = create_and_get_cgroup(CG_PATH); - if (!cgfd) + if (cgfd < 0) goto err; if (join_cgroup(CG_PATH)) diff --git a/tools/testing/selftests/bpf/test_socket_cookie.c b/tools/testing/selftests/bpf/test_socket_cookie.c index b6c2c605d8c0..fc7832ee566b 100644 --- a/tools/testing/selftests/bpf/test_socket_cookie.c +++ b/tools/testing/selftests/bpf/test_socket_cookie.c @@ -202,7 +202,7 @@ int main(int argc, char **argv) goto err; cgfd = create_and_get_cgroup(CG_PATH); - if (!cgfd) + if (cgfd < 0) goto err; if (join_cgroup(CG_PATH)) diff --git a/tools/testing/selftests/bpf/test_tcpbpf_user.c b/tools/testing/selftests/bpf/test_tcpbpf_user.c index e6eebda7d112..716b4e3be581 100644 --- a/tools/testing/selftests/bpf/test_tcpbpf_user.c +++ b/tools/testing/selftests/bpf/test_tcpbpf_user.c @@ -103,7 +103,7 @@ int main(int argc, char **argv) goto err; cg_fd = create_and_get_cgroup(cg_path); - if (!cg_fd) + if (cg_fd < 0) goto err; if (join_cgroup(cg_path)) diff --git a/tools/testing/selftests/bpf/test_tcpnotify_user.c b/tools/testing/selftests/bpf/test_tcpnotify_user.c index ff3c4522aed6..4e4353711a86 100644 --- a/tools/testing/selftests/bpf/test_tcpnotify_user.c +++ b/tools/testing/selftests/bpf/test_tcpnotify_user.c @@ -115,7 +115,7 @@ int main(int argc, char **argv) goto err; cg_fd = create_and_get_cgroup(cg_path); - if (!cg_fd) + if (cg_fd < 0) goto err; if (join_cgroup(cg_path)) diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c index 10d44446e801..2fd90d456892 100644 --- a/tools/testing/selftests/bpf/test_verifier.c +++ b/tools/testing/selftests/bpf/test_verifier.c @@ -6934,6 +6934,126 @@ static struct bpf_test tests[] = { .retval = 1, }, { + "map access: mixing value pointer and scalar, 1", + .insns = { + // load map value pointer into r0 and r2 + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_LD_MAP_FD(BPF_REG_ARG1, 0), + BPF_MOV64_REG(BPF_REG_ARG2, BPF_REG_FP), + BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG2, -16), + BPF_ST_MEM(BPF_DW, BPF_REG_FP, -16, 0), + BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), + BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), + BPF_EXIT_INSN(), + // load some number from the map into r1 + BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0), + // depending on r1, branch: + BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 3), + // branch A + BPF_MOV64_REG(BPF_REG_2, BPF_REG_0), + BPF_MOV64_IMM(BPF_REG_3, 0), + BPF_JMP_A(2), + // branch B + BPF_MOV64_IMM(BPF_REG_2, 0), + BPF_MOV64_IMM(BPF_REG_3, 0x100000), + // common instruction + BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3), + // depending on r1, branch: + BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1), + // branch A + BPF_JMP_A(4), + // branch B + BPF_MOV64_IMM(BPF_REG_0, 0x13371337), + // verifier follows fall-through + BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0x100000, 2), + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + // fake-dead code; targeted from branch A to + // prevent dead code sanitization + BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0), + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, + .fixup_map_array_48b = { 1 }, + .result = ACCEPT, + .result_unpriv = REJECT, + .errstr_unpriv = "R2 tried to add from different pointers or scalars", + .retval = 0, + }, + { + "map access: mixing value pointer and scalar, 2", + .insns = { + // load map value pointer into r0 and r2 + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_LD_MAP_FD(BPF_REG_ARG1, 0), + BPF_MOV64_REG(BPF_REG_ARG2, BPF_REG_FP), + BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG2, -16), + BPF_ST_MEM(BPF_DW, BPF_REG_FP, -16, 0), + BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), + BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), + BPF_EXIT_INSN(), + // load some number from the map into r1 + BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0), + // depending on r1, branch: + BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3), + // branch A + BPF_MOV64_IMM(BPF_REG_2, 0), + BPF_MOV64_IMM(BPF_REG_3, 0x100000), + BPF_JMP_A(2), + // branch B + BPF_MOV64_REG(BPF_REG_2, BPF_REG_0), + BPF_MOV64_IMM(BPF_REG_3, 0), + // common instruction + BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3), + // depending on r1, branch: + BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1), + // branch A + BPF_JMP_A(4), + // branch B + BPF_MOV64_IMM(BPF_REG_0, 0x13371337), + // verifier follows fall-through + BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0x100000, 2), + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + // fake-dead code; targeted from branch A to + // prevent dead code sanitization + BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0), + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, + .fixup_map_array_48b = { 1 }, + .result = ACCEPT, + .result_unpriv = REJECT, + .errstr_unpriv = "R2 tried to add from different maps or paths", + .retval = 0, + }, + { + "sanitation: alu with different scalars", + .insns = { + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_LD_MAP_FD(BPF_REG_ARG1, 0), + BPF_MOV64_REG(BPF_REG_ARG2, BPF_REG_FP), + BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG2, -16), + BPF_ST_MEM(BPF_DW, BPF_REG_FP, -16, 0), + BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), + BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), + BPF_EXIT_INSN(), + BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0), + BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3), + BPF_MOV64_IMM(BPF_REG_2, 0), + BPF_MOV64_IMM(BPF_REG_3, 0x100000), + BPF_JMP_A(2), + BPF_MOV64_IMM(BPF_REG_2, 42), + BPF_MOV64_IMM(BPF_REG_3, 0x100001), + BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3), + BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), + BPF_EXIT_INSN(), + }, + .fixup_map_array_48b = { 1 }, + .result = ACCEPT, + .retval = 0x100000, + }, + { "map access: value_ptr += known scalar, upper oob arith, test 1", .insns = { BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |