Similar to bpf_local_storage for sockets and inodes add local storage for task_struct. The life-cycle of storage is managed with the life-cycle of the task_struct. i.e. the storage is destroyed along with the owning task with a callback to the bpf_task_storage_free from the task_free LSM hook. 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. The userspace map operations can be done by using a pid fd as a key passed to the lookup, update and delete operations.
Showing the changes to include/uapi/linux (1 of 10 files). Show all
Unified · Split
| @@ -157,6 +157,7 @@ enum bpf_map_type { · 156 unmodified lines | ||
| 157 | 157 | BPF_MAP_TYPE_STRUCT_OPS, |
| 158 | 158 | BPF_MAP_TYPE_RINGBUF, |
| 159 | 159 | BPF_MAP_TYPE_INODE_STORAGE, |
| 160 | + BPF_MAP_TYPE_TASK_STORAGE, | |
| 160 | 161 | }; |
| 161 | 162 | |
| 162 | 163 | /* Note that tracing related programs such as |
| @@ -3742,6 +3743,42 @@ union bpf_attr { · 3579 unmodified lines | ||
| 3742 | 3743 | * Return |
| 3743 | 3744 | * The helper returns **TC_ACT_REDIRECT** on success or |
| 3744 | 3745 | * **TC_ACT_SHOT** on error. |
| 3746 | + * | |
| 3747 | + * void *bpf_task_storage_get(struct bpf_map *map, struct task_struct *task, void *value, u64 flags) | |
| 3748 | + * Description | |
| 3749 | + * Get a bpf_local_storage from the *task*. | |
| 3750 | + * | |
| 3751 | + * Logically, it could be thought of as getting the value from | |
| 3752 | + * a *map* with *task* as the **key**. From this | |
| 3753 | + * perspective, the usage is not much different from | |
| 3754 | + * **bpf_map_lookup_elem**\ (*map*, **&**\ *task*) except this | |
| 3755 | + * helper enforces the key must be an task_struct and the map must also | |
| 3756 | + * be a **BPF_MAP_TYPE_TASK_STORAGE**. | |
| 3757 | + * | |
| 3758 | + * Underneath, the value is stored locally at *task* instead of | |
| 3759 | + * the *map*. The *map* is used as the bpf-local-storage | |
| 3760 | + * "type". The bpf-local-storage "type" (i.e. the *map*) is | |
| 3761 | + * searched against all bpf_local_storage residing at *task*. | |
| 3762 | + * | |
| 3763 | + * An optional *flags* (**BPF_LOCAL_STORAGE_GET_F_CREATE**) can be | |
| 3764 | + * used such that a new bpf_local_storage will be | |
| 3765 | + * created if one does not exist. *value* can be used | |
| 3766 | + * together with **BPF_LOCAL_STORAGE_GET_F_CREATE** to specify | |
| 3767 | + * the initial value of a bpf_local_storage. If *value* is | |
| 3768 | + * **NULL**, the new bpf_local_storage will be zero initialized. | |
| 3769 | + * Return | |
| 3770 | + * A bpf_local_storage pointer is returned on success. | |
| 3771 | + * | |
| 3772 | + * **NULL** if not found or there was an error in adding | |
| 3773 | + * a new bpf_local_storage. | |
| 3774 | + * | |
| 3775 | + * long bpf_task_storage_delete(struct bpf_map *map, struct task_struct *task) | |
| 3776 | + * Description | |
| 3777 | + * Delete a bpf_local_storage from a *task*. | |
| 3778 | + * Return | |
| 3779 | + * 0 on success. | |
| 3780 | + * | |
| 3781 | + * **-ENOENT** if the bpf_local_storage cannot be found. | |
| 3745 | 3782 | */ |
| 3746 | 3783 | #define __BPF_FUNC_MAPPER(FN) \ |
| 3747 | 3784 | FN(unspec), \ |
| @@ -3900,6 +3937,8 @@ union bpf_attr { · 152 unmodified lines | ||
| 3900 | 3937 | FN(bpf_per_cpu_ptr), \ |
| 3901 | 3938 | FN(bpf_this_cpu_ptr), \ |
| 3902 | 3939 | FN(redirect_peer), \ |
| 3940 | + FN(task_storage_get), \ | |
| 3941 | + FN(task_storage_delete), \ | |
| 3903 | 3942 | /* */ |
| 3904 | 3943 | |
| 3905 | 3944 | /* integer value in 'imm' field of BPF_CALL instruction selects which helper |