bpf: make sure the kernel do not submit an invalid program if no pattern matched
It turns out that the kernel verifier would reject a program we would build if there was a whitelist, but no entries in the whitelist matched. The program would approximately like this: 0: (61) r2 = *(u32 *)(r1 +0) 1: (54) w2 &= 65535 2: (61) r3 = *(u32 *)(r1 +0) 3: (74) w3 >>= 16 4: (61) r4 = *(u32 *)(r1 +4) 5: (61) r5 = *(u32 *)(r1 +8) 48: (b7) r0 = 0 49: (05) goto pc+1 50: (b7) r0 = 1 51: (95) exit and insn 50 is unreachable, which is illegal. We would then either keep a previous version of the program or allow everything. Make sure we build a valid program that simply rejects everything.
This commit is contained in:
@@ -219,6 +219,37 @@ static void test_policy_whitelist_major_star(char type, const char *cgroup_path,
|
||||
assert_se(wrong == 0);
|
||||
}
|
||||
|
||||
static void test_policy_empty(bool add_mismatched, const char *cgroup_path, BPFProgram **installed_prog) {
|
||||
_cleanup_(bpf_program_unrefp) BPFProgram *prog = NULL;
|
||||
unsigned wrong = 0;
|
||||
int r;
|
||||
|
||||
log_info("/* %s(add_mismatched=%s) */", __func__, yes_no(add_mismatched));
|
||||
|
||||
r = bpf_devices_cgroup_init(&prog, CGROUP_DEVICE_POLICY_STRICT, add_mismatched);
|
||||
assert_se(r >= 0);
|
||||
|
||||
if (add_mismatched) {
|
||||
r = bpf_devices_whitelist_major(prog, cgroup_path, "foobarxxx", 'c', "rw");
|
||||
assert_se(r < 0);
|
||||
}
|
||||
|
||||
r = bpf_devices_apply_policy(prog, CGROUP_DEVICE_POLICY_STRICT, false, cgroup_path, installed_prog);
|
||||
assert_se(r >= 0);
|
||||
|
||||
{
|
||||
_cleanup_close_ int fd;
|
||||
const char *s = "/dev/null";
|
||||
|
||||
fd = open(s, O_CLOEXEC|O_RDWR|O_NOCTTY);
|
||||
log_debug("open(%s, \"r\") = %d/%s", s, fd, fd < 0 ? errno_to_name(errno) : "-");
|
||||
wrong += fd >= 0;
|
||||
}
|
||||
|
||||
assert_se(wrong == 0);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
_cleanup_free_ char *cgroup = NULL, *parent = NULL;
|
||||
_cleanup_(rmdir_and_freep) char *controller_path = NULL;
|
||||
@@ -258,6 +289,9 @@ int main(int argc, char *argv[]) {
|
||||
test_policy_whitelist_major_star('c', cgroup, &prog);
|
||||
test_policy_whitelist_major_star('b', cgroup, &prog);
|
||||
|
||||
test_policy_empty(false, cgroup, &prog);
|
||||
test_policy_empty(true, cgroup, &prog);
|
||||
|
||||
assert_se(parent = dirname_malloc(cgroup));
|
||||
|
||||
assert_se(cg_mask_supported(&supported) >= 0);
|
||||
|
||||
Reference in New Issue
Block a user