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

pinning.c (7993B)


      1// SPDX-License-Identifier: GPL-2.0
      2
      3#include <sys/types.h>
      4#include <sys/stat.h>
      5#include <unistd.h>
      6#include <test_progs.h>
      7
      8__u32 get_map_id(struct bpf_object *obj, const char *name)
      9{
     10	struct bpf_map_info map_info = {};
     11	__u32 map_info_len, duration = 0;
     12	struct bpf_map *map;
     13	int err;
     14
     15	map_info_len = sizeof(map_info);
     16
     17	map = bpf_object__find_map_by_name(obj, name);
     18	if (CHECK(!map, "find map", "NULL map"))
     19		return 0;
     20
     21	err = bpf_obj_get_info_by_fd(bpf_map__fd(map),
     22				     &map_info, &map_info_len);
     23	CHECK(err, "get map info", "err %d errno %d", err, errno);
     24	return map_info.id;
     25}
     26
     27void test_pinning(void)
     28{
     29	const char *file_invalid = "./test_pinning_invalid.o";
     30	const char *custpinpath = "/sys/fs/bpf/custom/pinmap";
     31	const char *nopinpath = "/sys/fs/bpf/nopinmap";
     32	const char *nopinpath2 = "/sys/fs/bpf/nopinmap2";
     33	const char *custpath = "/sys/fs/bpf/custom";
     34	const char *pinpath = "/sys/fs/bpf/pinmap";
     35	const char *file = "./test_pinning.o";
     36	__u32 map_id, map_id2, duration = 0;
     37	struct stat statbuf = {};
     38	struct bpf_object *obj;
     39	struct bpf_map *map;
     40	int err, map_fd;
     41	DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts,
     42		.pin_root_path = custpath,
     43	);
     44
     45	/* check that opening fails with invalid pinning value in map def */
     46	obj = bpf_object__open_file(file_invalid, NULL);
     47	err = libbpf_get_error(obj);
     48	if (CHECK(err != -EINVAL, "invalid open", "err %d errno %d\n", err, errno)) {
     49		obj = NULL;
     50		goto out;
     51	}
     52
     53	/* open the valid object file  */
     54	obj = bpf_object__open_file(file, NULL);
     55	err = libbpf_get_error(obj);
     56	if (CHECK(err, "default open", "err %d errno %d\n", err, errno)) {
     57		obj = NULL;
     58		goto out;
     59	}
     60
     61	err = bpf_object__load(obj);
     62	if (CHECK(err, "default load", "err %d errno %d\n", err, errno))
     63		goto out;
     64
     65	/* check that pinmap was pinned */
     66	err = stat(pinpath, &statbuf);
     67	if (CHECK(err, "stat pinpath", "err %d errno %d\n", err, errno))
     68		goto out;
     69
     70	/* check that nopinmap was *not* pinned */
     71	err = stat(nopinpath, &statbuf);
     72	if (CHECK(!err || errno != ENOENT, "stat nopinpath",
     73		  "err %d errno %d\n", err, errno))
     74		goto out;
     75
     76	/* check that nopinmap2 was *not* pinned */
     77	err = stat(nopinpath2, &statbuf);
     78	if (CHECK(!err || errno != ENOENT, "stat nopinpath2",
     79		  "err %d errno %d\n", err, errno))
     80		goto out;
     81
     82	map_id = get_map_id(obj, "pinmap");
     83	if (!map_id)
     84		goto out;
     85
     86	bpf_object__close(obj);
     87
     88	obj = bpf_object__open_file(file, NULL);
     89	if (CHECK_FAIL(libbpf_get_error(obj))) {
     90		obj = NULL;
     91		goto out;
     92	}
     93
     94	err = bpf_object__load(obj);
     95	if (CHECK(err, "default load", "err %d errno %d\n", err, errno))
     96		goto out;
     97
     98	/* check that same map ID was reused for second load */
     99	map_id2 = get_map_id(obj, "pinmap");
    100	if (CHECK(map_id != map_id2, "check reuse",
    101		  "err %d errno %d id %d id2 %d\n", err, errno, map_id, map_id2))
    102		goto out;
    103
    104	/* should be no-op to re-pin same map */
    105	map = bpf_object__find_map_by_name(obj, "pinmap");
    106	if (CHECK(!map, "find map", "NULL map"))
    107		goto out;
    108
    109	err = bpf_map__pin(map, NULL);
    110	if (CHECK(err, "re-pin map", "err %d errno %d\n", err, errno))
    111		goto out;
    112
    113	/* but error to pin at different location */
    114	err = bpf_map__pin(map, "/sys/fs/bpf/other");
    115	if (CHECK(!err, "pin map different", "err %d errno %d\n", err, errno))
    116		goto out;
    117
    118	/* unpin maps with a pin_path set */
    119	err = bpf_object__unpin_maps(obj, NULL);
    120	if (CHECK(err, "unpin maps", "err %d errno %d\n", err, errno))
    121		goto out;
    122
    123	/* and re-pin them... */
    124	err = bpf_object__pin_maps(obj, NULL);
    125	if (CHECK(err, "pin maps", "err %d errno %d\n", err, errno))
    126		goto out;
    127
    128	/* get pinning path */
    129	if (!ASSERT_STREQ(bpf_map__pin_path(map), pinpath, "get pin path"))
    130		goto out;
    131
    132	/* set pinning path of other map and re-pin all */
    133	map = bpf_object__find_map_by_name(obj, "nopinmap");
    134	if (CHECK(!map, "find map", "NULL map"))
    135		goto out;
    136
    137	err = bpf_map__set_pin_path(map, custpinpath);
    138	if (CHECK(err, "set pin path", "err %d errno %d\n", err, errno))
    139		goto out;
    140
    141	/* get pinning path after set */
    142	if (!ASSERT_STREQ(bpf_map__pin_path(map), custpinpath,
    143			  "get pin path after set"))
    144		goto out;
    145
    146	/* should only pin the one unpinned map */
    147	err = bpf_object__pin_maps(obj, NULL);
    148	if (CHECK(err, "pin maps", "err %d errno %d\n", err, errno))
    149		goto out;
    150
    151	/* check that nopinmap was pinned at the custom path */
    152	err = stat(custpinpath, &statbuf);
    153	if (CHECK(err, "stat custpinpath", "err %d errno %d\n", err, errno))
    154		goto out;
    155
    156	/* remove the custom pin path to re-test it with auto-pinning below */
    157	err = unlink(custpinpath);
    158	if (CHECK(err, "unlink custpinpath", "err %d errno %d\n", err, errno))
    159		goto out;
    160
    161	err = rmdir(custpath);
    162	if (CHECK(err, "rmdir custpindir", "err %d errno %d\n", err, errno))
    163		goto out;
    164
    165	bpf_object__close(obj);
    166
    167	/* open the valid object file again */
    168	obj = bpf_object__open_file(file, NULL);
    169	err = libbpf_get_error(obj);
    170	if (CHECK(err, "default open", "err %d errno %d\n", err, errno)) {
    171		obj = NULL;
    172		goto out;
    173	}
    174
    175	/* set pin paths so that nopinmap2 will attempt to reuse the map at
    176	 * pinpath (which will fail), but not before pinmap has already been
    177	 * reused
    178	 */
    179	bpf_object__for_each_map(map, obj) {
    180		if (!strcmp(bpf_map__name(map), "nopinmap"))
    181			err = bpf_map__set_pin_path(map, nopinpath2);
    182		else if (!strcmp(bpf_map__name(map), "nopinmap2"))
    183			err = bpf_map__set_pin_path(map, pinpath);
    184		else
    185			continue;
    186
    187		if (CHECK(err, "set pin path", "err %d errno %d\n", err, errno))
    188			goto out;
    189	}
    190
    191	/* should fail because of map parameter mismatch */
    192	err = bpf_object__load(obj);
    193	if (CHECK(err != -EINVAL, "param mismatch load", "err %d errno %d\n", err, errno))
    194		goto out;
    195
    196	/* nopinmap2 should have been pinned and cleaned up again */
    197	err = stat(nopinpath2, &statbuf);
    198	if (CHECK(!err || errno != ENOENT, "stat nopinpath2",
    199		  "err %d errno %d\n", err, errno))
    200		goto out;
    201
    202	/* pinmap should still be there */
    203	err = stat(pinpath, &statbuf);
    204	if (CHECK(err, "stat pinpath", "err %d errno %d\n", err, errno))
    205		goto out;
    206
    207	bpf_object__close(obj);
    208
    209	/* test auto-pinning at custom path with open opt */
    210	obj = bpf_object__open_file(file, &opts);
    211	if (CHECK_FAIL(libbpf_get_error(obj))) {
    212		obj = NULL;
    213		goto out;
    214	}
    215
    216	err = bpf_object__load(obj);
    217	if (CHECK(err, "custom load", "err %d errno %d\n", err, errno))
    218		goto out;
    219
    220	/* check that pinmap was pinned at the custom path */
    221	err = stat(custpinpath, &statbuf);
    222	if (CHECK(err, "stat custpinpath", "err %d errno %d\n", err, errno))
    223		goto out;
    224
    225	/* remove the custom pin path to re-test it with reuse fd below */
    226	err = unlink(custpinpath);
    227	if (CHECK(err, "unlink custpinpath", "err %d errno %d\n", err, errno))
    228		goto out;
    229
    230	err = rmdir(custpath);
    231	if (CHECK(err, "rmdir custpindir", "err %d errno %d\n", err, errno))
    232		goto out;
    233
    234	bpf_object__close(obj);
    235
    236	/* test pinning at custom path with reuse fd */
    237	obj = bpf_object__open_file(file, NULL);
    238	err = libbpf_get_error(obj);
    239	if (CHECK(err, "default open", "err %d errno %d\n", err, errno)) {
    240		obj = NULL;
    241		goto out;
    242	}
    243
    244	map_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, NULL, sizeof(__u32),
    245				sizeof(__u64), 1, NULL);
    246	if (CHECK(map_fd < 0, "create pinmap manually", "fd %d\n", map_fd))
    247		goto out;
    248
    249	map = bpf_object__find_map_by_name(obj, "pinmap");
    250	if (CHECK(!map, "find map", "NULL map"))
    251		goto close_map_fd;
    252
    253	err = bpf_map__reuse_fd(map, map_fd);
    254	if (CHECK(err, "reuse pinmap fd", "err %d errno %d\n", err, errno))
    255		goto close_map_fd;
    256
    257	err = bpf_map__set_pin_path(map, custpinpath);
    258	if (CHECK(err, "set pin path", "err %d errno %d\n", err, errno))
    259		goto close_map_fd;
    260
    261	err = bpf_object__load(obj);
    262	if (CHECK(err, "custom load", "err %d errno %d\n", err, errno))
    263		goto close_map_fd;
    264
    265	/* check that pinmap was pinned at the custom path */
    266	err = stat(custpinpath, &statbuf);
    267	if (CHECK(err, "stat custpinpath", "err %d errno %d\n", err, errno))
    268		goto close_map_fd;
    269
    270close_map_fd:
    271	close(map_fd);
    272out:
    273	unlink(pinpath);
    274	unlink(nopinpath);
    275	unlink(nopinpath2);
    276	unlink(custpinpath);
    277	rmdir(custpath);
    278	if (obj)
    279		bpf_object__close(obj);
    280}