Similar to bpf_local_storage for sockets, add local storage for inodes. The life-cycle of storage is managed with the life-cycle of the inode. i.e. the storage is destroyed along with the owning inode. The BPF LSM allocates an __rcu pointer to the bpf_local_storage in the security blob which are now stackable and can co-exist with other LSMs.
Showing the changes to include/uapi (1 of 13 files). Show all
Unified · Split
| @@ -155,6 +155,7 @@ enum bpf_map_type { · 154 unmodified lines | ||
| 155 | 155 | BPF_MAP_TYPE_DEVMAP_HASH, |
| 156 | 156 | BPF_MAP_TYPE_STRUCT_OPS, |
| 157 | 157 | BPF_MAP_TYPE_RINGBUF, |
| 158 | + BPF_MAP_TYPE_INODE_STORAGE, | |
| 158 | 159 | }; |
| 159 | 160 | |
| 160 | 161 | /* Note that tracing related programs such as |
| @@ -3509,6 +3510,41 @@ union bpf_attr { · 3348 unmodified lines | ||
| 3509 | 3510 | * |
| 3510 | 3511 | * **-EPERM** This helper cannot be used under the |
| 3511 | 3512 | * current sock_ops->op. |
| 3513 | + * void *bpf_inode_storage_get(struct bpf_map *map, void *inode, void *value, u64 flags) | |
| 3514 | + * Description | |
| 3515 | + * Get a bpf_local_storage from an *inode*. | |
| 3516 | + * | |
| 3517 | + * Logically, it could be thought of as getting the value from | |
| 3518 | + * a *map* with *inode* as the **key**. From this | |
| 3519 | + * perspective, the usage is not much different from | |
| 3520 | + * **bpf_map_lookup_elem**\ (*map*, **&**\ *inode*) except this | |
| 3521 | + * helper enforces the key must be an inode and the map must also | |
| 3522 | + * be a **BPF_MAP_TYPE_INODE_STORAGE**. | |
| 3523 | + * | |
| 3524 | + * Underneath, the value is stored locally at *inode* instead of | |
| 3525 | + * the *map*. The *map* is used as the bpf-local-storage | |
| 3526 | + * "type". The bpf-local-storage "type" (i.e. the *map*) is | |
| 3527 | + * searched against all bpf_local_storage residing at *inode*. | |
| 3528 | + * | |
| 3529 | + * An optional *flags* (**BPF_LOCAL_STORAGE_GET_F_CREATE**) can be | |
| 3530 | + * used such that a new bpf_local_storage will be | |
| 3531 | + * created if one does not exist. *value* can be used | |
| 3532 | + * together with **BPF_LOCAL_STORAGE_GET_F_CREATE** to specify | |
| 3533 | + * the initial value of a bpf_local_storage. If *value* is | |
| 3534 | + * **NULL**, the new bpf_local_storage will be zero initialized. | |
| 3535 | + * Return | |
| 3536 | + * A bpf_local_storage pointer is returned on success. | |
| 3537 | + * | |
| 3538 | + * **NULL** if not found or there was an error in adding | |
| 3539 | + * a new bpf_local_storage. | |
| 3540 | + * | |
| 3541 | + * int bpf_inode_storage_delete(struct bpf_map *map, void *inode) | |
| 3542 | + * Description | |
| 3543 | + * Delete a bpf_local_storage from an *inode*. | |
| 3544 | + * Return | |
| 3545 | + * 0 on success. | |
| 3546 | + * | |
| 3547 | + * **-ENOENT** if the bpf_local_storage cannot be found. | |
| 3512 | 3548 | */ |
| 3513 | 3549 | #define __BPF_FUNC_MAPPER(FN) \ |
| 3514 | 3550 | FN(unspec), \ |
| @@ -3655,7 +3691,9 @@ union bpf_attr { · 140 unmodified lines | ||
| 3655 | 3691 | FN(get_task_stack), \ |
| 3656 | 3692 | FN(load_hdr_opt), \ |
| 3657 | 3693 | FN(store_hdr_opt), \ |
| 3658 | − FN(reserve_hdr_opt), | |
| 3694 | + FN(reserve_hdr_opt), \ | |
| 3695 | + FN(inode_storage_get), \ | |
| 3696 | + FN(inode_storage_delete), \ | |
| 3659 | 3697 | /* */ |
| 3660 | 3698 | |
| 3661 | 3699 | /* integer value in 'imm' field of BPF_CALL instruction selects which helper |