I am trying to implement LSM BPF programs and I want to use BPF_MAP_TYPE_HASH_OF_MAPS to store information for each super block as the sb_alloc_security LSM hook is triggered. For example, I want to define the map as:
struct bpf_map_def SEC("SBMap") outer_map = {
.type = BPF_MAP_TYPE_HASH_OF_MAPS,
.key_size = sizeof(uuid_t), // super block unique identifier
.value_size = sizeof(__u32), // must be u32 because it is inner map id
.max_entries = 1024, // for now, let's assume we care about only 1024 super blocks
};
I want to use the super block's UUID as the key to the outer_map and every time a new super block is allocated, I would like to create a new inner map, something like:
SEC("lsm/sb_alloc_security")
int BPF_PROG(sb_alloc_security, struct super_block *sb) {
uuid_t key = sb->s_uuid; // use super block UUID as key to the outer_map
// If key does not exist in outer_map,
// create a new inner map and insert it
// into the outer_map with the key
}
But it seems like maps can be created only in user space. Is there any workaround?
That is correct, BPF maps can only be created from userspace, including inner maps of maps-in-maps structures. If you could create maps from the BPF programs, it would essentially enable dynamic memory allocation.