cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sockopt_multi.c (7348B)


      1// SPDX-License-Identifier: GPL-2.0
      2#include <test_progs.h>
      3#include "cgroup_helpers.h"
      4
      5static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title, const char *name)
      6{
      7	enum bpf_attach_type attach_type;
      8	enum bpf_prog_type prog_type;
      9	struct bpf_program *prog;
     10	int err;
     11
     12	err = libbpf_prog_type_by_name(title, &prog_type, &attach_type);
     13	if (err) {
     14		log_err("Failed to deduct types for %s BPF program", title);
     15		return -1;
     16	}
     17
     18	prog = bpf_object__find_program_by_name(obj, name);
     19	if (!prog) {
     20		log_err("Failed to find %s BPF program", name);
     21		return -1;
     22	}
     23
     24	err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd,
     25			      attach_type, BPF_F_ALLOW_MULTI);
     26	if (err) {
     27		log_err("Failed to attach %s BPF program", name);
     28		return -1;
     29	}
     30
     31	return 0;
     32}
     33
     34static int prog_detach(struct bpf_object *obj, int cgroup_fd, const char *title, const char *name)
     35{
     36	enum bpf_attach_type attach_type;
     37	enum bpf_prog_type prog_type;
     38	struct bpf_program *prog;
     39	int err;
     40
     41	err = libbpf_prog_type_by_name(title, &prog_type, &attach_type);
     42	if (err)
     43		return -1;
     44
     45	prog = bpf_object__find_program_by_name(obj, name);
     46	if (!prog)
     47		return -1;
     48
     49	err = bpf_prog_detach2(bpf_program__fd(prog), cgroup_fd,
     50			       attach_type);
     51	if (err)
     52		return -1;
     53
     54	return 0;
     55}
     56
     57static int run_getsockopt_test(struct bpf_object *obj, int cg_parent,
     58			       int cg_child, int sock_fd)
     59{
     60	socklen_t optlen;
     61	__u8 buf;
     62	int err;
     63
     64	/* Set IP_TOS to the expected value (0x80). */
     65
     66	buf = 0x80;
     67	err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1);
     68	if (err < 0) {
     69		log_err("Failed to call setsockopt(IP_TOS)");
     70		goto detach;
     71	}
     72
     73	buf = 0x00;
     74	optlen = 1;
     75	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
     76	if (err) {
     77		log_err("Failed to call getsockopt(IP_TOS)");
     78		goto detach;
     79	}
     80
     81	if (buf != 0x80) {
     82		log_err("Unexpected getsockopt 0x%x != 0x80 without BPF", buf);
     83		err = -1;
     84		goto detach;
     85	}
     86
     87	/* Attach child program and make sure it returns new value:
     88	 * - kernel:      -> 0x80
     89	 * - child:  0x80 -> 0x90
     90	 */
     91
     92	err = prog_attach(obj, cg_child, "cgroup/getsockopt", "_getsockopt_child");
     93	if (err)
     94		goto detach;
     95
     96	buf = 0x00;
     97	optlen = 1;
     98	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
     99	if (err) {
    100		log_err("Failed to call getsockopt(IP_TOS)");
    101		goto detach;
    102	}
    103
    104	if (buf != 0x90) {
    105		log_err("Unexpected getsockopt 0x%x != 0x90", buf);
    106		err = -1;
    107		goto detach;
    108	}
    109
    110	/* Attach parent program and make sure it returns new value:
    111	 * - kernel:      -> 0x80
    112	 * - child:  0x80 -> 0x90
    113	 * - parent: 0x90 -> 0xA0
    114	 */
    115
    116	err = prog_attach(obj, cg_parent, "cgroup/getsockopt", "_getsockopt_parent");
    117	if (err)
    118		goto detach;
    119
    120	buf = 0x00;
    121	optlen = 1;
    122	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
    123	if (err) {
    124		log_err("Failed to call getsockopt(IP_TOS)");
    125		goto detach;
    126	}
    127
    128	if (buf != 0xA0) {
    129		log_err("Unexpected getsockopt 0x%x != 0xA0", buf);
    130		err = -1;
    131		goto detach;
    132	}
    133
    134	/* Setting unexpected initial sockopt should return EPERM:
    135	 * - kernel: -> 0x40
    136	 * - child:  unexpected 0x40, EPERM
    137	 * - parent: unexpected 0x40, EPERM
    138	 */
    139
    140	buf = 0x40;
    141	err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1);
    142	if (err < 0) {
    143		log_err("Failed to call setsockopt(IP_TOS)");
    144		goto detach;
    145	}
    146
    147	buf = 0x00;
    148	optlen = 1;
    149	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
    150	if (!err) {
    151		log_err("Unexpected success from getsockopt(IP_TOS)");
    152		goto detach;
    153	}
    154
    155	/* Detach child program and make sure we still get EPERM:
    156	 * - kernel: -> 0x40
    157	 * - parent: unexpected 0x40, EPERM
    158	 */
    159
    160	err = prog_detach(obj, cg_child, "cgroup/getsockopt", "_getsockopt_child");
    161	if (err) {
    162		log_err("Failed to detach child program");
    163		goto detach;
    164	}
    165
    166	buf = 0x00;
    167	optlen = 1;
    168	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
    169	if (!err) {
    170		log_err("Unexpected success from getsockopt(IP_TOS)");
    171		goto detach;
    172	}
    173
    174	/* Set initial value to the one the parent program expects:
    175	 * - kernel:      -> 0x90
    176	 * - parent: 0x90 -> 0xA0
    177	 */
    178
    179	buf = 0x90;
    180	err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1);
    181	if (err < 0) {
    182		log_err("Failed to call setsockopt(IP_TOS)");
    183		goto detach;
    184	}
    185
    186	buf = 0x00;
    187	optlen = 1;
    188	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
    189	if (err) {
    190		log_err("Failed to call getsockopt(IP_TOS)");
    191		goto detach;
    192	}
    193
    194	if (buf != 0xA0) {
    195		log_err("Unexpected getsockopt 0x%x != 0xA0", buf);
    196		err = -1;
    197		goto detach;
    198	}
    199
    200detach:
    201	prog_detach(obj, cg_child, "cgroup/getsockopt", "_getsockopt_child");
    202	prog_detach(obj, cg_parent, "cgroup/getsockopt", "_getsockopt_parent");
    203
    204	return err;
    205}
    206
    207static int run_setsockopt_test(struct bpf_object *obj, int cg_parent,
    208			       int cg_child, int sock_fd)
    209{
    210	socklen_t optlen;
    211	__u8 buf;
    212	int err;
    213
    214	/* Set IP_TOS to the expected value (0x80). */
    215
    216	buf = 0x80;
    217	err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1);
    218	if (err < 0) {
    219		log_err("Failed to call setsockopt(IP_TOS)");
    220		goto detach;
    221	}
    222
    223	buf = 0x00;
    224	optlen = 1;
    225	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
    226	if (err) {
    227		log_err("Failed to call getsockopt(IP_TOS)");
    228		goto detach;
    229	}
    230
    231	if (buf != 0x80) {
    232		log_err("Unexpected getsockopt 0x%x != 0x80 without BPF", buf);
    233		err = -1;
    234		goto detach;
    235	}
    236
    237	/* Attach child program and make sure it adds 0x10. */
    238
    239	err = prog_attach(obj, cg_child, "cgroup/setsockopt", "_setsockopt");
    240	if (err)
    241		goto detach;
    242
    243	buf = 0x80;
    244	err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1);
    245	if (err < 0) {
    246		log_err("Failed to call setsockopt(IP_TOS)");
    247		goto detach;
    248	}
    249
    250	buf = 0x00;
    251	optlen = 1;
    252	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
    253	if (err) {
    254		log_err("Failed to call getsockopt(IP_TOS)");
    255		goto detach;
    256	}
    257
    258	if (buf != 0x80 + 0x10) {
    259		log_err("Unexpected getsockopt 0x%x != 0x80 + 0x10", buf);
    260		err = -1;
    261		goto detach;
    262	}
    263
    264	/* Attach parent program and make sure it adds another 0x10. */
    265
    266	err = prog_attach(obj, cg_parent, "cgroup/setsockopt", "_setsockopt");
    267	if (err)
    268		goto detach;
    269
    270	buf = 0x80;
    271	err = setsockopt(sock_fd, SOL_IP, IP_TOS, &buf, 1);
    272	if (err < 0) {
    273		log_err("Failed to call setsockopt(IP_TOS)");
    274		goto detach;
    275	}
    276
    277	buf = 0x00;
    278	optlen = 1;
    279	err = getsockopt(sock_fd, SOL_IP, IP_TOS, &buf, &optlen);
    280	if (err) {
    281		log_err("Failed to call getsockopt(IP_TOS)");
    282		goto detach;
    283	}
    284
    285	if (buf != 0x80 + 2 * 0x10) {
    286		log_err("Unexpected getsockopt 0x%x != 0x80 + 2 * 0x10", buf);
    287		err = -1;
    288		goto detach;
    289	}
    290
    291detach:
    292	prog_detach(obj, cg_child, "cgroup/setsockopt", "_setsockopt");
    293	prog_detach(obj, cg_parent, "cgroup/setsockopt", "_setsockopt");
    294
    295	return err;
    296}
    297
    298void test_sockopt_multi(void)
    299{
    300	int cg_parent = -1, cg_child = -1;
    301	struct bpf_object *obj = NULL;
    302	int sock_fd = -1;
    303	int err = -1;
    304
    305	cg_parent = test__join_cgroup("/parent");
    306	if (CHECK_FAIL(cg_parent < 0))
    307		goto out;
    308
    309	cg_child = test__join_cgroup("/parent/child");
    310	if (CHECK_FAIL(cg_child < 0))
    311		goto out;
    312
    313	obj = bpf_object__open_file("sockopt_multi.o", NULL);
    314	if (!ASSERT_OK_PTR(obj, "obj_load"))
    315		goto out;
    316
    317	err = bpf_object__load(obj);
    318	if (!ASSERT_OK(err, "obj_load"))
    319		goto out;
    320
    321	sock_fd = socket(AF_INET, SOCK_STREAM, 0);
    322	if (CHECK_FAIL(sock_fd < 0))
    323		goto out;
    324
    325	CHECK_FAIL(run_getsockopt_test(obj, cg_parent, cg_child, sock_fd));
    326	CHECK_FAIL(run_setsockopt_test(obj, cg_parent, cg_child, sock_fd));
    327
    328out:
    329	close(sock_fd);
    330	bpf_object__close(obj);
    331	close(cg_child);
    332	close(cg_parent);
    333}