Skip to content

Commit a569c2e

Browse files
committed
cgroup, systemd: improved "same bpf" check
It appears that some architectures other than x86_64 (ppc64 and s390) do modify in-kernel bpf program while it's being loaded into the kernel. On those platforms, the check for bpf being the same (added in commit edf6678) doesn't work, and the attempt to run "crun update" with the same device access list fails with "updating device access list not supported when using BPFProgram" error. A workaround is to actually load the new program into the kernel, read it back, and compare. Signed-off-by: Kir Kolyshkin <[email protected]>
1 parent 1042e3f commit a569c2e

File tree

1 file changed

+36
-4
lines changed

1 file changed

+36
-4
lines changed

src/libcrun/cgroup-systemd.c

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1431,6 +1431,10 @@ add_bpf_program (sd_bus_message *m,
14311431
if (UNLIKELY (ret < 0))
14321432
return ret;
14331433

1434+
ret = mkdir (CRUN_BPF_DIR, 0700);
1435+
if (UNLIKELY (ret < 0 && errno != EEXIST))
1436+
return crun_make_error (err, errno, "mkdir " CRUN_BPF_DIR);
1437+
14341438
if (is_update)
14351439
{
14361440
cleanup_free struct bpf_program *program_loaded = NULL;
@@ -1452,13 +1456,41 @@ add_bpf_program (sd_bus_message *m,
14521456
return 0;
14531457
}
14541458

1459+
/* Some platforms (e.g. ppc64) modify an EBPF program as it is
1460+
* loaded into the kernel, so in order to compare we actually
1461+
* have to load the new program and read it back. Seems ugly,
1462+
* but all this comes from the inability of systemd to modify
1463+
* the BPFProgram property.
1464+
*/
1465+
{
1466+
cleanup_free struct bpf_program *program_new = NULL;
1467+
char tmp[64];
1468+
int len;
1469+
1470+
/* A unique name, as container name can't start with a digit. */
1471+
len = snprintf (tmp, sizeof (tmp), "%s/%d", CRUN_BPF_DIR, getpid ());
1472+
if (UNLIKELY (len >= (int) sizeof (tmp)))
1473+
return crun_make_error (err, 0, "internal error: static buffer too small");
1474+
1475+
ret = libcrun_ebpf_load (program, -1, tmp, err);
1476+
if (UNLIKELY (ret < 0))
1477+
return ret;
1478+
1479+
ret = libcrun_ebpf_read_program (&program_new, tmp, err);
1480+
unlink (tmp);
1481+
if (UNLIKELY (ret < 0))
1482+
return ret;
1483+
1484+
if (libcrun_ebpf_cmp_programs (program_new, program_loaded))
1485+
{
1486+
*devices_set = true;
1487+
return 0;
1488+
}
1489+
}
1490+
14551491
return crun_make_error (err, 0, "updating device access list not supported when using BPFProgram");
14561492
}
14571493

1458-
ret = mkdir (CRUN_BPF_DIR, 0700);
1459-
if (UNLIKELY (ret < 0 && errno != EEXIST))
1460-
return crun_make_error (err, errno, "mkdir " CRUN_BPF_DIR);
1461-
14621494
ret = libcrun_ebpf_load (program, -1, path, err);
14631495
if (UNLIKELY (ret < 0))
14641496
return ret;

0 commit comments

Comments
 (0)