]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: pin restrict-fsaccess initramfs_s_dev store width to skeleton field 42705/head
authortunaichao <tunaichao@uniontech.com>
Wed, 24 Jun 2026 06:01:06 +0000 (14:01 +0800)
committertunaichao <tunaichao@uniontech.com>
Wed, 24 Jun 2026 06:01:06 +0000 (14:01 +0800)
The clear-store in restrict_fsaccess_clear_initramfs_trust() writes a fixed
4 bytes (*(uint32_t *)(p + INITRAMFS_S_DEV_OFF) = 0). INITRAMFS_S_DEV_OFF is
derived from the skeleton, so the offset tracks any field widening, but the
store width does not: were initramfs_s_dev widened (e.g. __u32 -> __u64) in
the BPF program, the store would clear only the low 4 bytes and silently
leave the initramfs trust window partially open. That is exactly the class
of bug the mirror-struct asserts (removed earlier in this branch) guarded
against.

Add a compile-time assert pinning the store width to the skeleton field
width (sizeof_field(typeof_field(struct restrict_fsaccess_bpf, bss[0]),
initramfs_s_dev) == sizeof(uint32_t)), so widening the field fails the build
instead of clearing half of it.

src/core/bpf-restrict-fsaccess.c

index 318cec39076bf59df1197e09539a44e5d1bbd7bd..d132c34164df5868c23beb47501d66fc1cadc440 100644 (file)
@@ -60,6 +60,10 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(struct restrict_fsaccess_bpf *, restrict_fsaccess_bp
 /* The single aligned 32-bit store in restrict_fsaccess_clear_initramfs_trust()
  * is only atomic if the field is 4-byte aligned. */
 assert_cc(INITRAMFS_S_DEV_OFF % sizeof(uint32_t) == 0);
+/* The store is a fixed 4-byte write; pin its width to the skeleton's field
+ * width so widening initramfs_s_dev fails the build instead of silently
+ * clearing only the low bytes. */
+assert_cc(sizeof_field(typeof_field(struct restrict_fsaccess_bpf, bss[0]), initramfs_s_dev) == sizeof(uint32_t));
 
 /* Build the skeleton links array indexed by the link enum.
  * For BDEV_SETINTEGRITY, use whichever variant was loaded (full or compat).