Commit cef0638
Uninitialized Stack Variable / NULL Pointer Dereference in __sys_socket_create via BPF LSM hooks
> Our fuzzing found an Uninitialized Stack Variable vulnerability in the
> Linux Socket Subsystem. The issue is triggered when a
> `BPF_PROG_TYPE_LSM` attached to the `bpf_lsm_socket_create` cgroup hook
> uses the `bpf_set_retval()` helper to return a value greater than 0
> (e.g., `1`). This bypasses the actual `socket_create` execution but
> returns a success status back to `__sys_socket_create`, which then
> accesses the uninitialized stack variable `sock` leading to a NULL
> pointer dereference or potential privilege escalation.
>
> Reported-by: Quan Sun <2022090917019@std.uestc.edu.cn>
> Reported-by: Yinhao Hu <dddddd@hust.edu.cn>
> Reported-by: Kaiyan Mei <M202472210@hust.edu.cn>
> Reviewed-by: Dongliang Mu <dzm91@hust.edu.cn>
>
> ## Root Cause
>
> This vulnerability is caused by treating a manipulated return value from
> an LSM hook as complete success in `__sys_socket_create` without
> ensuring that the underlying object has been fully initialized.
>
> 1. `__sys_socket_create()` in `net/socket.c` reserves a pointer variable
> `struct socket *sock;` on the kernel stack without zero-initializing it.
> 2. It calls `sock_create(family, type, protocol, &sock);` to allocate
> and initialize the socket object.
> 3. `sock_create` proceeds to allocate the socket internally and invokes
> the `security_socket_create` LSM hook (which triggers
> `bpf_lsm_socket_create`).
> 4. If a BPF program is attached to the cgroup LSM hook for
> `bpf_lsm_socket_create`, it can call `bpf_set_retval(1)` and return `1`.
> 5. Because the BPF hook completes without an error code (< 0),
> `sock_create` interprets this bypass as success and promptly returns `1`
> (or a positive bypass value) back to `__sys_socket_create()`. However,
> the critical variable `sock` is never populated.
> 6. The caller `__sys_socket_create()` checks if `sock_create()`'s return
> value is `< 0`. Since `1` is not less than `0`, it assumes the `sock`
> pointer is valid.
> 7. Subsequent socket operations inside `__sys_socket_create()`, such as
> `sock_map_fd(sock, ...)`, attempt to dereference the uninitialized
> `sock` stack pointer.
>
> #### Execution Flow Visualization
>
> ```text
> Vulnerability Execution Flow
> |
> |--- 1. `__sys_socket_create(...)`
> | |\
> | | `-- struct socket *sock; (Uninitialized pointer on stack)
> | |
> |--- 2. `sock_create(...)` -> `security_socket_create(...)`
> | |\
> | | `-- BPF LSM CGROUP hook for `bpf_lsm_socket_create` triggered.
> | | |
> | | `-- bpf_set_retval(1); return 1;
> | |
> |--- 3. Context switches back to `sock_create`
> | |\
> | | `-- LSM hook returns `1`. `sock_create` skips allocation and
> returns `1`.
> | |
> |--- 4. Context switches back to `__sys_socket_create`
> | |\
> | | `-- Check return value (1 < 0 is False). Treated as SUCCESS.
> | | |
> | | `-- `sock_map_fd(sock, ...)`
> | | |
> | | `-- Dereferences `sock` leading to KERNEL PANIC or Hijack.
> ```
>
> ## Reproduction Steps
>
> 1. Load a `BPF_PROG_TYPE_LSM` BPF program that:
> - Sets the target BTF ID to `bpf_lsm_socket_create`.
> - Calls the `bpf_set_retval(1)` helper inside the hook.
> 2. Attach the loaded program to a chosen cgroup directory using
> `BPF_LSM_CGROUP`.
> 3. Add the current process to the targeted cgroup.
> 4. Trigger the creation of a socket by invoking the `socket(AF_INET,
> SOCK_STREAM, 0)` system call from within the cgroup.
> 5. The `sock_create` function skips allocation, returns 1, and
> `__sys_socket_create` dereferences the uninitialized stack pointer.
Thanks for the report.
Maybe we could fix like below.
I guess all (most?) places suppose LSM to return 0 or
a negative value, and the btf_id_set_contains() check
would be unnecessary ?
---8<---
---8<---1 parent c82410a commit cef0638
1 file changed
Lines changed: 32 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
87 | 87 | | |
88 | 88 | | |
89 | 89 | | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
90 | 97 | | |
91 | 98 | | |
92 | 99 | | |
| |||
221 | 228 | | |
222 | 229 | | |
223 | 230 | | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
224 | 251 | | |
225 | 252 | | |
226 | 253 | | |
227 | 254 | | |
228 | 255 | | |
229 | 256 | | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
230 | 262 | | |
231 | 263 | | |
232 | 264 | | |
| |||
0 commit comments