Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (c) 2026 Christian Brauner <brauner@kernel.org> */
3
4/*
5 * BPF LSM block device integrity tracker for dm-verity.
6 *
7 * Tracks block devices in a hashmap keyed by bd_dev. When dm-verity
8 * calls security_bdev_setintegrity() during verity_preresume(), the
9 * setintegrity hook records the roothash and signature-validity data.
10 * The free hook cleans up when the device goes away. The alloc hook
11 * counts allocations for test validation.
12 *
13 * The sleepable hooks exercise bpf_copy_from_user() to verify that
14 * the sleepable classification actually permits sleepable helpers.
15 */
16
17#include "vmlinux.h"
18#include <bpf/bpf_helpers.h>
19#include <bpf/bpf_tracing.h>
20
21struct verity_info {
22 __u8 has_roothash; /* LSM_INT_DMVERITY_ROOTHASH seen */
23 __u8 sig_valid; /* LSM_INT_DMVERITY_SIG_VALID value (non-NULL = valid) */
24 __u32 setintegrity_cnt; /* total setintegrity calls for this dev */
25};
26
27struct {
28 __uint(type, BPF_MAP_TYPE_HASH);
29 __uint(max_entries, 64);
30 __type(key, __u32); /* dev_t from bdev->bd_dev */
31 __type(value, struct verity_info);
32} verity_devices SEC(".maps");
33
34/* Global counters exposed to userspace via skeleton bss. */
35int alloc_count;
36
37char _license[] SEC("license") = "GPL";
38
39SEC("lsm.s/bdev_setintegrity")
40int BPF_PROG(bdev_setintegrity, struct block_device *bdev,
41 enum lsm_integrity_type type, const void *value, size_t size)
42{
43 struct verity_info zero = {};
44 struct verity_info *info;
45 __u32 dev;
46 char buf;
47
48 /*
49 * Exercise a sleepable helper to confirm the verifier
50 * allows it in this sleepable hook.
51 */
52 (void)bpf_copy_from_user(&buf, sizeof(buf), NULL);
53
54 dev = bdev->bd_dev;
55
56 info = bpf_map_lookup_elem(&verity_devices, &dev);
57 if (!info) {
58 bpf_map_update_elem(&verity_devices, &dev, &zero, BPF_NOEXIST);
59 info = bpf_map_lookup_elem(&verity_devices, &dev);
60 if (!info)
61 return 0;
62 }
63
64 if (type == LSM_INT_DMVERITY_ROOTHASH)
65 info->has_roothash = 1;
66 else if (type == LSM_INT_DMVERITY_SIG_VALID)
67 info->sig_valid = (value != NULL);
68
69 __sync_fetch_and_add(&info->setintegrity_cnt, 1);
70
71 return 0;
72}
73
74SEC("lsm/bdev_free_security")
75void BPF_PROG(bdev_free_security, struct block_device *bdev)
76{
77 __u32 dev = bdev->bd_dev;
78
79 bpf_map_delete_elem(&verity_devices, &dev);
80}
81
82SEC("lsm.s/bdev_alloc_security")
83int BPF_PROG(bdev_alloc_security, struct block_device *bdev)
84{
85 char buf;
86
87 /*
88 * Exercise a sleepable helper to confirm the verifier
89 * allows it in this sleepable hook.
90 */
91 (void)bpf_copy_from_user(&buf, sizeof(buf), NULL);
92
93 __sync_fetch_and_add(&alloc_count, 1);
94
95 return 0;
96}