mirror of
https://kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable.git
synced 2025-09-30 18:54:15 +10:00
selftests/bpf: Correctly handle optlen > 4096
Even though it's not relevant in selftests, the people might still copy-paste from them. So let's take care of optlen > 4096 cases explicitly. Signed-off-by: Stanislav Fomichev <sdf@google.com> Link: https://lore.kernel.org/r/20230511170456.1759459-4-sdf@google.com Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
This commit is contained in:
parent
989a4a7dbf
commit
e01b4a72f1
@ -25,6 +25,8 @@ static void test_setsockopt_set(int cgroup_fd, int sock_fd)
|
|||||||
if (!ASSERT_OK_PTR(obj, "skel-load"))
|
if (!ASSERT_OK_PTR(obj, "skel-load"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
obj->bss->page_size = sysconf(_SC_PAGESIZE);
|
||||||
|
|
||||||
/* Attach setsockopt that sets EUNATCH, assert that
|
/* Attach setsockopt that sets EUNATCH, assert that
|
||||||
* we actually get that error when we run setsockopt()
|
* we actually get that error when we run setsockopt()
|
||||||
*/
|
*/
|
||||||
@ -59,6 +61,8 @@ static void test_setsockopt_set_and_get(int cgroup_fd, int sock_fd)
|
|||||||
if (!ASSERT_OK_PTR(obj, "skel-load"))
|
if (!ASSERT_OK_PTR(obj, "skel-load"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
obj->bss->page_size = sysconf(_SC_PAGESIZE);
|
||||||
|
|
||||||
/* Attach setsockopt that sets EUNATCH, and one that gets the
|
/* Attach setsockopt that sets EUNATCH, and one that gets the
|
||||||
* previously set errno. Assert that we get the same errno back.
|
* previously set errno. Assert that we get the same errno back.
|
||||||
*/
|
*/
|
||||||
@ -100,6 +104,8 @@ static void test_setsockopt_default_zero(int cgroup_fd, int sock_fd)
|
|||||||
if (!ASSERT_OK_PTR(obj, "skel-load"))
|
if (!ASSERT_OK_PTR(obj, "skel-load"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
obj->bss->page_size = sysconf(_SC_PAGESIZE);
|
||||||
|
|
||||||
/* Attach setsockopt that gets the previously set errno.
|
/* Attach setsockopt that gets the previously set errno.
|
||||||
* Assert that, without anything setting one, we get 0.
|
* Assert that, without anything setting one, we get 0.
|
||||||
*/
|
*/
|
||||||
@ -134,6 +140,8 @@ static void test_setsockopt_default_zero_and_set(int cgroup_fd, int sock_fd)
|
|||||||
if (!ASSERT_OK_PTR(obj, "skel-load"))
|
if (!ASSERT_OK_PTR(obj, "skel-load"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
obj->bss->page_size = sysconf(_SC_PAGESIZE);
|
||||||
|
|
||||||
/* Attach setsockopt that gets the previously set errno, and then
|
/* Attach setsockopt that gets the previously set errno, and then
|
||||||
* one that sets the errno to EUNATCH. Assert that the get does not
|
* one that sets the errno to EUNATCH. Assert that the get does not
|
||||||
* see EUNATCH set later, and does not prevent EUNATCH from being set.
|
* see EUNATCH set later, and does not prevent EUNATCH from being set.
|
||||||
@ -177,6 +185,8 @@ static void test_setsockopt_override(int cgroup_fd, int sock_fd)
|
|||||||
if (!ASSERT_OK_PTR(obj, "skel-load"))
|
if (!ASSERT_OK_PTR(obj, "skel-load"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
obj->bss->page_size = sysconf(_SC_PAGESIZE);
|
||||||
|
|
||||||
/* Attach setsockopt that sets EUNATCH, then one that sets EISCONN,
|
/* Attach setsockopt that sets EUNATCH, then one that sets EISCONN,
|
||||||
* and then one that gets the exported errno. Assert both the syscall
|
* and then one that gets the exported errno. Assert both the syscall
|
||||||
* and the helper sees the last set errno.
|
* and the helper sees the last set errno.
|
||||||
@ -224,6 +234,8 @@ static void test_setsockopt_legacy_eperm(int cgroup_fd, int sock_fd)
|
|||||||
if (!ASSERT_OK_PTR(obj, "skel-load"))
|
if (!ASSERT_OK_PTR(obj, "skel-load"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
obj->bss->page_size = sysconf(_SC_PAGESIZE);
|
||||||
|
|
||||||
/* Attach setsockopt that return a reject without setting errno
|
/* Attach setsockopt that return a reject without setting errno
|
||||||
* (legacy reject), and one that gets the errno. Assert that for
|
* (legacy reject), and one that gets the errno. Assert that for
|
||||||
* backward compatibility the syscall result in EPERM, and this
|
* backward compatibility the syscall result in EPERM, and this
|
||||||
@ -268,6 +280,8 @@ static void test_setsockopt_legacy_no_override(int cgroup_fd, int sock_fd)
|
|||||||
if (!ASSERT_OK_PTR(obj, "skel-load"))
|
if (!ASSERT_OK_PTR(obj, "skel-load"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
obj->bss->page_size = sysconf(_SC_PAGESIZE);
|
||||||
|
|
||||||
/* Attach setsockopt that sets EUNATCH, then one that return a reject
|
/* Attach setsockopt that sets EUNATCH, then one that return a reject
|
||||||
* without setting errno, and then one that gets the exported errno.
|
* without setting errno, and then one that gets the exported errno.
|
||||||
* Assert both the syscall and the helper's errno are unaffected by
|
* Assert both the syscall and the helper's errno are unaffected by
|
||||||
@ -319,6 +333,8 @@ static void test_getsockopt_get(int cgroup_fd, int sock_fd)
|
|||||||
if (!ASSERT_OK_PTR(obj, "skel-load"))
|
if (!ASSERT_OK_PTR(obj, "skel-load"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
obj->bss->page_size = sysconf(_SC_PAGESIZE);
|
||||||
|
|
||||||
/* Attach getsockopt that gets previously set errno. Assert that the
|
/* Attach getsockopt that gets previously set errno. Assert that the
|
||||||
* error from kernel is in both ctx_retval_value and retval_value.
|
* error from kernel is in both ctx_retval_value and retval_value.
|
||||||
*/
|
*/
|
||||||
@ -359,6 +375,8 @@ static void test_getsockopt_override(int cgroup_fd, int sock_fd)
|
|||||||
if (!ASSERT_OK_PTR(obj, "skel-load"))
|
if (!ASSERT_OK_PTR(obj, "skel-load"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
obj->bss->page_size = sysconf(_SC_PAGESIZE);
|
||||||
|
|
||||||
/* Attach getsockopt that sets retval to -EISCONN. Assert that this
|
/* Attach getsockopt that sets retval to -EISCONN. Assert that this
|
||||||
* overrides the value from kernel.
|
* overrides the value from kernel.
|
||||||
*/
|
*/
|
||||||
@ -396,6 +414,8 @@ static void test_getsockopt_retval_sync(int cgroup_fd, int sock_fd)
|
|||||||
if (!ASSERT_OK_PTR(obj, "skel-load"))
|
if (!ASSERT_OK_PTR(obj, "skel-load"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
obj->bss->page_size = sysconf(_SC_PAGESIZE);
|
||||||
|
|
||||||
/* Attach getsockopt that sets retval to -EISCONN, and one that clears
|
/* Attach getsockopt that sets retval to -EISCONN, and one that clears
|
||||||
* ctx retval. Assert that the clearing ctx retval is synced to helper
|
* ctx retval. Assert that the clearing ctx retval is synced to helper
|
||||||
* and clears any errors both from kernel and BPF..
|
* and clears any errors both from kernel and BPF..
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
#include <test_progs.h>
|
#include <test_progs.h>
|
||||||
#include "cgroup_helpers.h"
|
#include "cgroup_helpers.h"
|
||||||
|
|
||||||
|
#include "sockopt_inherit.skel.h"
|
||||||
|
|
||||||
#define SOL_CUSTOM 0xdeadbeef
|
#define SOL_CUSTOM 0xdeadbeef
|
||||||
#define CUSTOM_INHERIT1 0
|
#define CUSTOM_INHERIT1 0
|
||||||
#define CUSTOM_INHERIT2 1
|
#define CUSTOM_INHERIT2 1
|
||||||
@ -132,58 +134,30 @@ static int start_server(void)
|
|||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title,
|
|
||||||
const char *prog_name)
|
|
||||||
{
|
|
||||||
enum bpf_attach_type attach_type;
|
|
||||||
enum bpf_prog_type prog_type;
|
|
||||||
struct bpf_program *prog;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = libbpf_prog_type_by_name(title, &prog_type, &attach_type);
|
|
||||||
if (err) {
|
|
||||||
log_err("Failed to deduct types for %s BPF program", prog_name);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
prog = bpf_object__find_program_by_name(obj, prog_name);
|
|
||||||
if (!prog) {
|
|
||||||
log_err("Failed to find %s BPF program", prog_name);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd,
|
|
||||||
attach_type, 0);
|
|
||||||
if (err) {
|
|
||||||
log_err("Failed to attach %s BPF program", prog_name);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void run_test(int cgroup_fd)
|
static void run_test(int cgroup_fd)
|
||||||
{
|
{
|
||||||
|
struct bpf_link *link_getsockopt = NULL;
|
||||||
|
struct bpf_link *link_setsockopt = NULL;
|
||||||
int server_fd = -1, client_fd;
|
int server_fd = -1, client_fd;
|
||||||
struct bpf_object *obj;
|
struct sockopt_inherit *obj;
|
||||||
void *server_err;
|
void *server_err;
|
||||||
pthread_t tid;
|
pthread_t tid;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
obj = bpf_object__open_file("sockopt_inherit.bpf.o", NULL);
|
obj = sockopt_inherit__open_and_load();
|
||||||
if (!ASSERT_OK_PTR(obj, "obj_open"))
|
if (!ASSERT_OK_PTR(obj, "skel-load"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
err = bpf_object__load(obj);
|
obj->bss->page_size = sysconf(_SC_PAGESIZE);
|
||||||
if (!ASSERT_OK(err, "obj_load"))
|
|
||||||
|
link_getsockopt = bpf_program__attach_cgroup(obj->progs._getsockopt,
|
||||||
|
cgroup_fd);
|
||||||
|
if (!ASSERT_OK_PTR(link_getsockopt, "cg-attach-getsockopt"))
|
||||||
goto close_bpf_object;
|
goto close_bpf_object;
|
||||||
|
|
||||||
err = prog_attach(obj, cgroup_fd, "cgroup/getsockopt", "_getsockopt");
|
link_setsockopt = bpf_program__attach_cgroup(obj->progs._setsockopt,
|
||||||
if (!ASSERT_OK(err, "prog_attach _getsockopt"))
|
cgroup_fd);
|
||||||
goto close_bpf_object;
|
if (!ASSERT_OK_PTR(link_setsockopt, "cg-attach-setsockopt"))
|
||||||
|
|
||||||
err = prog_attach(obj, cgroup_fd, "cgroup/setsockopt", "_setsockopt");
|
|
||||||
if (!ASSERT_OK(err, "prog_attach _setsockopt"))
|
|
||||||
goto close_bpf_object;
|
goto close_bpf_object;
|
||||||
|
|
||||||
server_fd = start_server();
|
server_fd = start_server();
|
||||||
@ -217,7 +191,10 @@ static void run_test(int cgroup_fd)
|
|||||||
close_server_fd:
|
close_server_fd:
|
||||||
close(server_fd);
|
close(server_fd);
|
||||||
close_bpf_object:
|
close_bpf_object:
|
||||||
bpf_object__close(obj);
|
bpf_link__destroy(link_getsockopt);
|
||||||
|
bpf_link__destroy(link_setsockopt);
|
||||||
|
|
||||||
|
sockopt_inherit__destroy(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_sockopt_inherit(void)
|
void test_sockopt_inherit(void)
|
||||||
|
@ -2,61 +2,13 @@
|
|||||||
#include <test_progs.h>
|
#include <test_progs.h>
|
||||||
#include "cgroup_helpers.h"
|
#include "cgroup_helpers.h"
|
||||||
|
|
||||||
static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title, const char *name)
|
#include "sockopt_multi.skel.h"
|
||||||
{
|
|
||||||
enum bpf_attach_type attach_type;
|
|
||||||
enum bpf_prog_type prog_type;
|
|
||||||
struct bpf_program *prog;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = libbpf_prog_type_by_name(title, &prog_type, &attach_type);
|
static int run_getsockopt_test(struct sockopt_multi *obj, int cg_parent,
|
||||||
if (err) {
|
|
||||||
log_err("Failed to deduct types for %s BPF program", title);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
prog = bpf_object__find_program_by_name(obj, name);
|
|
||||||
if (!prog) {
|
|
||||||
log_err("Failed to find %s BPF program", name);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd,
|
|
||||||
attach_type, BPF_F_ALLOW_MULTI);
|
|
||||||
if (err) {
|
|
||||||
log_err("Failed to attach %s BPF program", name);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int prog_detach(struct bpf_object *obj, int cgroup_fd, const char *title, const char *name)
|
|
||||||
{
|
|
||||||
enum bpf_attach_type attach_type;
|
|
||||||
enum bpf_prog_type prog_type;
|
|
||||||
struct bpf_program *prog;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = libbpf_prog_type_by_name(title, &prog_type, &attach_type);
|
|
||||||
if (err)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
prog = bpf_object__find_program_by_name(obj, name);
|
|
||||||
if (!prog)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
err = bpf_prog_detach2(bpf_program__fd(prog), cgroup_fd,
|
|
||||||
attach_type);
|
|
||||||
if (err)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int run_getsockopt_test(struct bpf_object *obj, int cg_parent,
|
|
||||||
int cg_child, int sock_fd)
|
int cg_child, int sock_fd)
|
||||||
{
|
{
|
||||||
|
struct bpf_link *link_parent = NULL;
|
||||||
|
struct bpf_link *link_child = NULL;
|
||||||
socklen_t optlen;
|
socklen_t optlen;
|
||||||
__u8 buf;
|
__u8 buf;
|
||||||
int err;
|
int err;
|
||||||
@ -89,8 +41,9 @@ static int run_getsockopt_test(struct bpf_object *obj, int cg_parent,
|
|||||||
* - child: 0x80 -> 0x90
|
* - child: 0x80 -> 0x90
|
||||||
*/
|
*/
|
||||||
|
|
||||||
err = prog_attach(obj, cg_child, "cgroup/getsockopt", "_getsockopt_child");
|
link_child = bpf_program__attach_cgroup(obj->progs._getsockopt_child,
|
||||||
if (err)
|
cg_child);
|
||||||
|
if (!ASSERT_OK_PTR(link_child, "cg-attach-getsockopt_child"))
|
||||||
goto detach;
|
goto detach;
|
||||||
|
|
||||||
buf = 0x00;
|
buf = 0x00;
|
||||||
@ -113,8 +66,9 @@ static int run_getsockopt_test(struct bpf_object *obj, int cg_parent,
|
|||||||
* - parent: 0x90 -> 0xA0
|
* - parent: 0x90 -> 0xA0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
err = prog_attach(obj, cg_parent, "cgroup/getsockopt", "_getsockopt_parent");
|
link_parent = bpf_program__attach_cgroup(obj->progs._getsockopt_parent,
|
||||||
if (err)
|
cg_parent);
|
||||||
|
if (!ASSERT_OK_PTR(link_parent, "cg-attach-getsockopt_parent"))
|
||||||
goto detach;
|
goto detach;
|
||||||
|
|
||||||
buf = 0x00;
|
buf = 0x00;
|
||||||
@ -157,11 +111,8 @@ static int run_getsockopt_test(struct bpf_object *obj, int cg_parent,
|
|||||||
* - parent: unexpected 0x40, EPERM
|
* - parent: unexpected 0x40, EPERM
|
||||||
*/
|
*/
|
||||||
|
|
||||||
err = prog_detach(obj, cg_child, "cgroup/getsockopt", "_getsockopt_child");
|
bpf_link__destroy(link_child);
|
||||||
if (err) {
|
link_child = NULL;
|
||||||
log_err("Failed to detach child program");
|
|
||||||
goto detach;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = 0x00;
|
buf = 0x00;
|
||||||
optlen = 1;
|
optlen = 1;
|
||||||
@ -198,15 +149,17 @@ static int run_getsockopt_test(struct bpf_object *obj, int cg_parent,
|
|||||||
}
|
}
|
||||||
|
|
||||||
detach:
|
detach:
|
||||||
prog_detach(obj, cg_child, "cgroup/getsockopt", "_getsockopt_child");
|
bpf_link__destroy(link_child);
|
||||||
prog_detach(obj, cg_parent, "cgroup/getsockopt", "_getsockopt_parent");
|
bpf_link__destroy(link_parent);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int run_setsockopt_test(struct bpf_object *obj, int cg_parent,
|
static int run_setsockopt_test(struct sockopt_multi *obj, int cg_parent,
|
||||||
int cg_child, int sock_fd)
|
int cg_child, int sock_fd)
|
||||||
{
|
{
|
||||||
|
struct bpf_link *link_parent = NULL;
|
||||||
|
struct bpf_link *link_child = NULL;
|
||||||
socklen_t optlen;
|
socklen_t optlen;
|
||||||
__u8 buf;
|
__u8 buf;
|
||||||
int err;
|
int err;
|
||||||
@ -236,8 +189,9 @@ static int run_setsockopt_test(struct bpf_object *obj, int cg_parent,
|
|||||||
|
|
||||||
/* Attach child program and make sure it adds 0x10. */
|
/* Attach child program and make sure it adds 0x10. */
|
||||||
|
|
||||||
err = prog_attach(obj, cg_child, "cgroup/setsockopt", "_setsockopt");
|
link_child = bpf_program__attach_cgroup(obj->progs._setsockopt,
|
||||||
if (err)
|
cg_child);
|
||||||
|
if (!ASSERT_OK_PTR(link_child, "cg-attach-setsockopt_child"))
|
||||||
goto detach;
|
goto detach;
|
||||||
|
|
||||||
buf = 0x80;
|
buf = 0x80;
|
||||||
@ -263,8 +217,9 @@ static int run_setsockopt_test(struct bpf_object *obj, int cg_parent,
|
|||||||
|
|
||||||
/* Attach parent program and make sure it adds another 0x10. */
|
/* Attach parent program and make sure it adds another 0x10. */
|
||||||
|
|
||||||
err = prog_attach(obj, cg_parent, "cgroup/setsockopt", "_setsockopt");
|
link_parent = bpf_program__attach_cgroup(obj->progs._setsockopt,
|
||||||
if (err)
|
cg_parent);
|
||||||
|
if (!ASSERT_OK_PTR(link_parent, "cg-attach-setsockopt_parent"))
|
||||||
goto detach;
|
goto detach;
|
||||||
|
|
||||||
buf = 0x80;
|
buf = 0x80;
|
||||||
@ -289,8 +244,8 @@ static int run_setsockopt_test(struct bpf_object *obj, int cg_parent,
|
|||||||
}
|
}
|
||||||
|
|
||||||
detach:
|
detach:
|
||||||
prog_detach(obj, cg_child, "cgroup/setsockopt", "_setsockopt");
|
bpf_link__destroy(link_child);
|
||||||
prog_detach(obj, cg_parent, "cgroup/setsockopt", "_setsockopt");
|
bpf_link__destroy(link_parent);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -298,9 +253,8 @@ detach:
|
|||||||
void test_sockopt_multi(void)
|
void test_sockopt_multi(void)
|
||||||
{
|
{
|
||||||
int cg_parent = -1, cg_child = -1;
|
int cg_parent = -1, cg_child = -1;
|
||||||
struct bpf_object *obj = NULL;
|
struct sockopt_multi *obj = NULL;
|
||||||
int sock_fd = -1;
|
int sock_fd = -1;
|
||||||
int err = -1;
|
|
||||||
|
|
||||||
cg_parent = test__join_cgroup("/parent");
|
cg_parent = test__join_cgroup("/parent");
|
||||||
if (!ASSERT_GE(cg_parent, 0, "join_cgroup /parent"))
|
if (!ASSERT_GE(cg_parent, 0, "join_cgroup /parent"))
|
||||||
@ -310,13 +264,11 @@ void test_sockopt_multi(void)
|
|||||||
if (!ASSERT_GE(cg_child, 0, "join_cgroup /parent/child"))
|
if (!ASSERT_GE(cg_child, 0, "join_cgroup /parent/child"))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
obj = bpf_object__open_file("sockopt_multi.bpf.o", NULL);
|
obj = sockopt_multi__open_and_load();
|
||||||
if (!ASSERT_OK_PTR(obj, "obj_load"))
|
if (!ASSERT_OK_PTR(obj, "skel-load"))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
err = bpf_object__load(obj);
|
obj->bss->page_size = sysconf(_SC_PAGESIZE);
|
||||||
if (!ASSERT_OK(err, "obj_load"))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
|
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
if (!ASSERT_GE(sock_fd, 0, "socket"))
|
if (!ASSERT_GE(sock_fd, 0, "socket"))
|
||||||
@ -327,7 +279,7 @@ void test_sockopt_multi(void)
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
close(sock_fd);
|
close(sock_fd);
|
||||||
bpf_object__close(obj);
|
sockopt_multi__destroy(obj);
|
||||||
close(cg_child);
|
close(cg_child);
|
||||||
close(cg_parent);
|
close(cg_parent);
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,8 @@ void test_sockopt_qos_to_cc(void)
|
|||||||
if (!ASSERT_OK_PTR(skel, "skel"))
|
if (!ASSERT_OK_PTR(skel, "skel"))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
skel->bss->page_size = sysconf(_SC_PAGESIZE);
|
||||||
|
|
||||||
sock_fd = socket(AF_INET6, SOCK_STREAM, 0);
|
sock_fd = socket(AF_INET6, SOCK_STREAM, 0);
|
||||||
if (!ASSERT_GE(sock_fd, 0, "v6 socket open"))
|
if (!ASSERT_GE(sock_fd, 0, "v6 socket open"))
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -12,6 +12,7 @@ __u32 invocations = 0;
|
|||||||
__u32 assertion_error = 0;
|
__u32 assertion_error = 0;
|
||||||
__u32 retval_value = 0;
|
__u32 retval_value = 0;
|
||||||
__u32 ctx_retval_value = 0;
|
__u32 ctx_retval_value = 0;
|
||||||
|
__u32 page_size = 0;
|
||||||
|
|
||||||
SEC("cgroup/getsockopt")
|
SEC("cgroup/getsockopt")
|
||||||
int get_retval(struct bpf_sockopt *ctx)
|
int get_retval(struct bpf_sockopt *ctx)
|
||||||
@ -20,6 +21,10 @@ int get_retval(struct bpf_sockopt *ctx)
|
|||||||
ctx_retval_value = ctx->retval;
|
ctx_retval_value = ctx->retval;
|
||||||
__sync_fetch_and_add(&invocations, 1);
|
__sync_fetch_and_add(&invocations, 1);
|
||||||
|
|
||||||
|
/* optval larger than PAGE_SIZE use kernel's buffer. */
|
||||||
|
if (ctx->optlen > page_size)
|
||||||
|
ctx->optlen = 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,6 +36,10 @@ int set_eisconn(struct bpf_sockopt *ctx)
|
|||||||
if (bpf_set_retval(-EISCONN))
|
if (bpf_set_retval(-EISCONN))
|
||||||
assertion_error = 1;
|
assertion_error = 1;
|
||||||
|
|
||||||
|
/* optval larger than PAGE_SIZE use kernel's buffer. */
|
||||||
|
if (ctx->optlen > page_size)
|
||||||
|
ctx->optlen = 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,5 +50,9 @@ int clear_retval(struct bpf_sockopt *ctx)
|
|||||||
|
|
||||||
ctx->retval = 0;
|
ctx->retval = 0;
|
||||||
|
|
||||||
|
/* optval larger than PAGE_SIZE use kernel's buffer. */
|
||||||
|
if (ctx->optlen > page_size)
|
||||||
|
ctx->optlen = 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
__u32 invocations = 0;
|
__u32 invocations = 0;
|
||||||
__u32 assertion_error = 0;
|
__u32 assertion_error = 0;
|
||||||
__u32 retval_value = 0;
|
__u32 retval_value = 0;
|
||||||
|
__u32 page_size = 0;
|
||||||
|
|
||||||
SEC("cgroup/setsockopt")
|
SEC("cgroup/setsockopt")
|
||||||
int get_retval(struct bpf_sockopt *ctx)
|
int get_retval(struct bpf_sockopt *ctx)
|
||||||
@ -18,6 +19,10 @@ int get_retval(struct bpf_sockopt *ctx)
|
|||||||
retval_value = bpf_get_retval();
|
retval_value = bpf_get_retval();
|
||||||
__sync_fetch_and_add(&invocations, 1);
|
__sync_fetch_and_add(&invocations, 1);
|
||||||
|
|
||||||
|
/* optval larger than PAGE_SIZE use kernel's buffer. */
|
||||||
|
if (ctx->optlen > page_size)
|
||||||
|
ctx->optlen = 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,6 +34,10 @@ int set_eunatch(struct bpf_sockopt *ctx)
|
|||||||
if (bpf_set_retval(-EUNATCH))
|
if (bpf_set_retval(-EUNATCH))
|
||||||
assertion_error = 1;
|
assertion_error = 1;
|
||||||
|
|
||||||
|
/* optval larger than PAGE_SIZE use kernel's buffer. */
|
||||||
|
if (ctx->optlen > page_size)
|
||||||
|
ctx->optlen = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,6 +49,10 @@ int set_eisconn(struct bpf_sockopt *ctx)
|
|||||||
if (bpf_set_retval(-EISCONN))
|
if (bpf_set_retval(-EISCONN))
|
||||||
assertion_error = 1;
|
assertion_error = 1;
|
||||||
|
|
||||||
|
/* optval larger than PAGE_SIZE use kernel's buffer. */
|
||||||
|
if (ctx->optlen > page_size)
|
||||||
|
ctx->optlen = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,5 +61,9 @@ int legacy_eperm(struct bpf_sockopt *ctx)
|
|||||||
{
|
{
|
||||||
__sync_fetch_and_add(&invocations, 1);
|
__sync_fetch_and_add(&invocations, 1);
|
||||||
|
|
||||||
|
/* optval larger than PAGE_SIZE use kernel's buffer. */
|
||||||
|
if (ctx->optlen > page_size)
|
||||||
|
ctx->optlen = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@ char _license[] SEC("license") = "GPL";
|
|||||||
#define CUSTOM_INHERIT2 1
|
#define CUSTOM_INHERIT2 1
|
||||||
#define CUSTOM_LISTENER 2
|
#define CUSTOM_LISTENER 2
|
||||||
|
|
||||||
|
__u32 page_size = 0;
|
||||||
|
|
||||||
struct sockopt_inherit {
|
struct sockopt_inherit {
|
||||||
__u8 val;
|
__u8 val;
|
||||||
};
|
};
|
||||||
@ -55,7 +57,7 @@ int _getsockopt(struct bpf_sockopt *ctx)
|
|||||||
__u8 *optval = ctx->optval;
|
__u8 *optval = ctx->optval;
|
||||||
|
|
||||||
if (ctx->level != SOL_CUSTOM)
|
if (ctx->level != SOL_CUSTOM)
|
||||||
return 1; /* only interested in SOL_CUSTOM */
|
goto out; /* only interested in SOL_CUSTOM */
|
||||||
|
|
||||||
if (optval + 1 > optval_end)
|
if (optval + 1 > optval_end)
|
||||||
return 0; /* EPERM, bounds check */
|
return 0; /* EPERM, bounds check */
|
||||||
@ -70,6 +72,12 @@ int _getsockopt(struct bpf_sockopt *ctx)
|
|||||||
ctx->optlen = 1;
|
ctx->optlen = 1;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
out:
|
||||||
|
/* optval larger than PAGE_SIZE use kernel's buffer. */
|
||||||
|
if (ctx->optlen > page_size)
|
||||||
|
ctx->optlen = 0;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SEC("cgroup/setsockopt")
|
SEC("cgroup/setsockopt")
|
||||||
@ -80,7 +88,7 @@ int _setsockopt(struct bpf_sockopt *ctx)
|
|||||||
__u8 *optval = ctx->optval;
|
__u8 *optval = ctx->optval;
|
||||||
|
|
||||||
if (ctx->level != SOL_CUSTOM)
|
if (ctx->level != SOL_CUSTOM)
|
||||||
return 1; /* only interested in SOL_CUSTOM */
|
goto out; /* only interested in SOL_CUSTOM */
|
||||||
|
|
||||||
if (optval + 1 > optval_end)
|
if (optval + 1 > optval_end)
|
||||||
return 0; /* EPERM, bounds check */
|
return 0; /* EPERM, bounds check */
|
||||||
@ -93,4 +101,10 @@ int _setsockopt(struct bpf_sockopt *ctx)
|
|||||||
ctx->optlen = -1;
|
ctx->optlen = -1;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
out:
|
||||||
|
/* optval larger than PAGE_SIZE use kernel's buffer. */
|
||||||
|
if (ctx->optlen > page_size)
|
||||||
|
ctx->optlen = 0;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
char _license[] SEC("license") = "GPL";
|
char _license[] SEC("license") = "GPL";
|
||||||
|
|
||||||
|
__u32 page_size = 0;
|
||||||
|
|
||||||
SEC("cgroup/getsockopt")
|
SEC("cgroup/getsockopt")
|
||||||
int _getsockopt_child(struct bpf_sockopt *ctx)
|
int _getsockopt_child(struct bpf_sockopt *ctx)
|
||||||
{
|
{
|
||||||
@ -12,7 +14,7 @@ int _getsockopt_child(struct bpf_sockopt *ctx)
|
|||||||
__u8 *optval = ctx->optval;
|
__u8 *optval = ctx->optval;
|
||||||
|
|
||||||
if (ctx->level != SOL_IP || ctx->optname != IP_TOS)
|
if (ctx->level != SOL_IP || ctx->optname != IP_TOS)
|
||||||
return 1;
|
goto out;
|
||||||
|
|
||||||
if (optval + 1 > optval_end)
|
if (optval + 1 > optval_end)
|
||||||
return 0; /* EPERM, bounds check */
|
return 0; /* EPERM, bounds check */
|
||||||
@ -26,6 +28,12 @@ int _getsockopt_child(struct bpf_sockopt *ctx)
|
|||||||
ctx->optlen = 1;
|
ctx->optlen = 1;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
out:
|
||||||
|
/* optval larger than PAGE_SIZE use kernel's buffer. */
|
||||||
|
if (ctx->optlen > page_size)
|
||||||
|
ctx->optlen = 0;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SEC("cgroup/getsockopt")
|
SEC("cgroup/getsockopt")
|
||||||
@ -35,7 +43,7 @@ int _getsockopt_parent(struct bpf_sockopt *ctx)
|
|||||||
__u8 *optval = ctx->optval;
|
__u8 *optval = ctx->optval;
|
||||||
|
|
||||||
if (ctx->level != SOL_IP || ctx->optname != IP_TOS)
|
if (ctx->level != SOL_IP || ctx->optname != IP_TOS)
|
||||||
return 1;
|
goto out;
|
||||||
|
|
||||||
if (optval + 1 > optval_end)
|
if (optval + 1 > optval_end)
|
||||||
return 0; /* EPERM, bounds check */
|
return 0; /* EPERM, bounds check */
|
||||||
@ -49,6 +57,12 @@ int _getsockopt_parent(struct bpf_sockopt *ctx)
|
|||||||
ctx->optlen = 1;
|
ctx->optlen = 1;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
out:
|
||||||
|
/* optval larger than PAGE_SIZE use kernel's buffer. */
|
||||||
|
if (ctx->optlen > page_size)
|
||||||
|
ctx->optlen = 0;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SEC("cgroup/setsockopt")
|
SEC("cgroup/setsockopt")
|
||||||
@ -58,7 +72,7 @@ int _setsockopt(struct bpf_sockopt *ctx)
|
|||||||
__u8 *optval = ctx->optval;
|
__u8 *optval = ctx->optval;
|
||||||
|
|
||||||
if (ctx->level != SOL_IP || ctx->optname != IP_TOS)
|
if (ctx->level != SOL_IP || ctx->optname != IP_TOS)
|
||||||
return 1;
|
goto out;
|
||||||
|
|
||||||
if (optval + 1 > optval_end)
|
if (optval + 1 > optval_end)
|
||||||
return 0; /* EPERM, bounds check */
|
return 0; /* EPERM, bounds check */
|
||||||
@ -67,4 +81,10 @@ int _setsockopt(struct bpf_sockopt *ctx)
|
|||||||
ctx->optlen = 1;
|
ctx->optlen = 1;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
out:
|
||||||
|
/* optval larger than PAGE_SIZE use kernel's buffer. */
|
||||||
|
if (ctx->optlen > page_size)
|
||||||
|
ctx->optlen = 0;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
char _license[] SEC("license") = "GPL";
|
char _license[] SEC("license") = "GPL";
|
||||||
|
|
||||||
|
__u32 page_size = 0;
|
||||||
|
|
||||||
SEC("cgroup/setsockopt")
|
SEC("cgroup/setsockopt")
|
||||||
int sockopt_qos_to_cc(struct bpf_sockopt *ctx)
|
int sockopt_qos_to_cc(struct bpf_sockopt *ctx)
|
||||||
{
|
{
|
||||||
@ -19,7 +21,7 @@ int sockopt_qos_to_cc(struct bpf_sockopt *ctx)
|
|||||||
char cc_cubic[TCP_CA_NAME_MAX] = "cubic";
|
char cc_cubic[TCP_CA_NAME_MAX] = "cubic";
|
||||||
|
|
||||||
if (ctx->level != SOL_IPV6 || ctx->optname != IPV6_TCLASS)
|
if (ctx->level != SOL_IPV6 || ctx->optname != IPV6_TCLASS)
|
||||||
return 1;
|
goto out;
|
||||||
|
|
||||||
if (optval + 1 > optval_end)
|
if (optval + 1 > optval_end)
|
||||||
return 0; /* EPERM, bounds check */
|
return 0; /* EPERM, bounds check */
|
||||||
@ -36,4 +38,10 @@ int sockopt_qos_to_cc(struct bpf_sockopt *ctx)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
out:
|
||||||
|
/* optval larger than PAGE_SIZE use kernel's buffer. */
|
||||||
|
if (ctx->optlen > page_size)
|
||||||
|
ctx->optlen = 0;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ int _getsockopt(struct bpf_sockopt *ctx)
|
|||||||
/* Bypass AF_NETLINK. */
|
/* Bypass AF_NETLINK. */
|
||||||
sk = ctx->sk;
|
sk = ctx->sk;
|
||||||
if (sk && sk->family == AF_NETLINK)
|
if (sk && sk->family == AF_NETLINK)
|
||||||
return 1;
|
goto out;
|
||||||
|
|
||||||
/* Make sure bpf_get_netns_cookie is callable.
|
/* Make sure bpf_get_netns_cookie is callable.
|
||||||
*/
|
*/
|
||||||
@ -52,8 +52,7 @@ int _getsockopt(struct bpf_sockopt *ctx)
|
|||||||
* let next BPF program in the cgroup chain or kernel
|
* let next BPF program in the cgroup chain or kernel
|
||||||
* handle it.
|
* handle it.
|
||||||
*/
|
*/
|
||||||
ctx->optlen = 0; /* bypass optval>PAGE_SIZE */
|
goto out;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->level == SOL_SOCKET && ctx->optname == SO_SNDBUF) {
|
if (ctx->level == SOL_SOCKET && ctx->optname == SO_SNDBUF) {
|
||||||
@ -61,7 +60,7 @@ int _getsockopt(struct bpf_sockopt *ctx)
|
|||||||
* let next BPF program in the cgroup chain or kernel
|
* let next BPF program in the cgroup chain or kernel
|
||||||
* handle it.
|
* handle it.
|
||||||
*/
|
*/
|
||||||
return 1;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->level == SOL_TCP && ctx->optname == TCP_CONGESTION) {
|
if (ctx->level == SOL_TCP && ctx->optname == TCP_CONGESTION) {
|
||||||
@ -69,7 +68,7 @@ int _getsockopt(struct bpf_sockopt *ctx)
|
|||||||
* let next BPF program in the cgroup chain or kernel
|
* let next BPF program in the cgroup chain or kernel
|
||||||
* handle it.
|
* handle it.
|
||||||
*/
|
*/
|
||||||
return 1;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->level == SOL_TCP && ctx->optname == TCP_ZEROCOPY_RECEIVE) {
|
if (ctx->level == SOL_TCP && ctx->optname == TCP_ZEROCOPY_RECEIVE) {
|
||||||
@ -85,7 +84,7 @@ int _getsockopt(struct bpf_sockopt *ctx)
|
|||||||
if (((struct tcp_zerocopy_receive *)optval)->address != 0)
|
if (((struct tcp_zerocopy_receive *)optval)->address != 0)
|
||||||
return 0; /* unexpected data */
|
return 0; /* unexpected data */
|
||||||
|
|
||||||
return 1;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->level == SOL_IP && ctx->optname == IP_FREEBIND) {
|
if (ctx->level == SOL_IP && ctx->optname == IP_FREEBIND) {
|
||||||
@ -129,6 +128,12 @@ int _getsockopt(struct bpf_sockopt *ctx)
|
|||||||
ctx->optlen = 1;
|
ctx->optlen = 1;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
out:
|
||||||
|
/* optval larger than PAGE_SIZE use kernel's buffer. */
|
||||||
|
if (ctx->optlen > page_size)
|
||||||
|
ctx->optlen = 0;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SEC("cgroup/setsockopt")
|
SEC("cgroup/setsockopt")
|
||||||
@ -142,7 +147,7 @@ int _setsockopt(struct bpf_sockopt *ctx)
|
|||||||
/* Bypass AF_NETLINK. */
|
/* Bypass AF_NETLINK. */
|
||||||
sk = ctx->sk;
|
sk = ctx->sk;
|
||||||
if (sk && sk->family == AF_NETLINK)
|
if (sk && sk->family == AF_NETLINK)
|
||||||
return 1;
|
goto out;
|
||||||
|
|
||||||
/* Make sure bpf_get_netns_cookie is callable.
|
/* Make sure bpf_get_netns_cookie is callable.
|
||||||
*/
|
*/
|
||||||
@ -224,4 +229,10 @@ int _setsockopt(struct bpf_sockopt *ctx)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
out:
|
||||||
|
/* optval larger than PAGE_SIZE use kernel's buffer. */
|
||||||
|
if (ctx->optlen > page_size)
|
||||||
|
ctx->optlen = 0;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user