1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <sys/stat.h> 4 #include <sys/sysmacros.h> 5 #include <errno.h> 6 #include "test_progs.h" 7 #include "cgroup_helpers.h" 8 #include "dev_cgroup.skel.h" 9 10 #define TEST_CGROUP "/test-bpf-based-device-cgroup/" 11 #define TEST_BUFFER_SIZE 64 12 13 static void test_mknod(const char *path, mode_t mode, int dev_major, 14 int dev_minor, int expected_ret, int expected_errno) 15 { 16 int ret; 17 18 unlink(path); 19 ret = mknod(path, mode, makedev(dev_major, dev_minor)); 20 ASSERT_EQ(ret, expected_ret, "mknod"); 21 if (expected_ret) 22 ASSERT_EQ(errno, expected_errno, "mknod errno"); 23 else 24 unlink(path); 25 } 26 27 static void test_read(const char *path, char *buf, int buf_size, 28 int expected_ret, int expected_errno) 29 { 30 int ret, fd; 31 32 fd = open(path, O_RDONLY); 33 34 /* A bare open on unauthorized device should fail */ 35 if (expected_ret < 0) { 36 ASSERT_EQ(fd, expected_ret, "open ret for read"); 37 ASSERT_EQ(errno, expected_errno, "open errno for read"); 38 if (fd >= 0) 39 close(fd); 40 return; 41 } 42 43 if (!ASSERT_OK_FD(fd, "open ret for read")) 44 return; 45 46 ret = read(fd, buf, buf_size); 47 ASSERT_EQ(ret, expected_ret, "read"); 48 49 close(fd); 50 } 51 52 static void test_write(const char *path, char *buf, int buf_size, 53 int expected_ret, int expected_errno) 54 { 55 int ret, fd; 56 57 fd = open(path, O_WRONLY); 58 59 /* A bare open on unauthorized device should fail */ 60 if (expected_ret < 0) { 61 ASSERT_EQ(fd, expected_ret, "open ret for write"); 62 ASSERT_EQ(errno, expected_errno, "open errno for write"); 63 if (fd >= 0) 64 close(fd); 65 return; 66 } 67 68 if (!ASSERT_OK_FD(fd, "open ret for write")) 69 return; 70 71 ret = write(fd, buf, buf_size); 72 ASSERT_EQ(ret, expected_ret, "write"); 73 74 close(fd); 75 } 76 77 void test_cgroup_dev(void) 78 { 79 char buf[TEST_BUFFER_SIZE] = "some random test data"; 80 struct dev_cgroup *skel; 81 int cgroup_fd; 82 83 cgroup_fd = cgroup_setup_and_join(TEST_CGROUP); 84 if (!ASSERT_OK_FD(cgroup_fd, "cgroup switch")) 85 return; 86 87 skel = dev_cgroup__open_and_load(); 88 if (!ASSERT_OK_PTR(skel, "load program")) 89 goto cleanup_cgroup; 90 91 skel->links.bpf_prog1 = 92 bpf_program__attach_cgroup(skel->progs.bpf_prog1, cgroup_fd); 93 if (!ASSERT_OK_PTR(skel->links.bpf_prog1, "attach_program")) 94 goto cleanup_progs; 95 96 if (test__start_subtest("allow-mknod")) 97 test_mknod("/dev/test_dev_cgroup_null", S_IFCHR, 1, 3, 0, 0); 98 99 if (test__start_subtest("allow-read")) 100 test_read("/dev/urandom", buf, TEST_BUFFER_SIZE, 101 TEST_BUFFER_SIZE, 0); 102 103 if (test__start_subtest("allow-write")) 104 test_write("/dev/null", buf, TEST_BUFFER_SIZE, 105 TEST_BUFFER_SIZE, 0); 106 107 if (test__start_subtest("deny-mknod")) 108 test_mknod("/dev/test_dev_cgroup_zero", S_IFCHR, 1, 5, -1, 109 EPERM); 110 111 if (test__start_subtest("deny-read")) 112 test_read("/dev/random", buf, TEST_BUFFER_SIZE, -1, EPERM); 113 114 if (test__start_subtest("deny-write")) 115 test_write("/dev/zero", buf, TEST_BUFFER_SIZE, -1, EPERM); 116 117 if (test__start_subtest("deny-mknod-wrong-type")) 118 test_mknod("/dev/test_dev_cgroup_block", S_IFBLK, 1, 3, -1, 119 EPERM); 120 121 cleanup_progs: 122 dev_cgroup__destroy(skel); 123 cleanup_cgroup: 124 cleanup_cgroup_environment(); 125 } 126
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.