VYPR
Unrated severityNVD Advisory· Published May 27, 2026· Updated May 27, 2026

CVE-2026-45838

CVE-2026-45838

Description

In the Linux kernel, the following vulnerability has been resolved:

bpf: fix end-of-list detection in cgroup_storage_get_next_key()

list_next_entry() never returns NULL -- when the current element is the last entry it wraps to the list head via container_of(). The subsequent NULL check is therefore dead code and get_next_key() never returns -ENOENT for the last element, instead reading storage->key from a bogus pointer that aliases internal map fields and copying the result to userspace.

Replace it with list_entry_is_head() so the function correctly returns -ENOENT when there are no more entries.

Affected products

2

Patches

10
5828b9e5b272

bpf: fix end-of-list detection in cgroup_storage_get_next_key()

1 file changed · +1 2
  • kernel/bpf/local_storage.c+1 2 modified
    diff --git a/kernel/bpf/local_storage.c b/kernel/bpf/local_storage.c
    index 8fca0c64f7b1cd..23267213a17fb7 100644
    --- a/kernel/bpf/local_storage.c
    +++ b/kernel/bpf/local_storage.c
    @@ -270,7 +270,7 @@ static int cgroup_storage_get_next_key(struct bpf_map *_map, void *key,
     			goto enoent;
     
     		storage = list_next_entry(storage, list_map);
    -		if (!storage)
    +		if (list_entry_is_head(storage, &map->list, list_map))
     			goto enoent;
     	} else {
     		storage = list_first_entry(&map->list,
    -- 
    cgit 1.3-korg
    
    
    
b4b5a20bed82

bpf: fix end-of-list detection in cgroup_storage_get_next_key()

1 file changed · +1 2
  • kernel/bpf/local_storage.c+1 2 modified
    diff --git a/kernel/bpf/local_storage.c b/kernel/bpf/local_storage.c
    index a04f505aefe9b6..c8b8dcc37ed4a7 100644
    --- a/kernel/bpf/local_storage.c
    +++ b/kernel/bpf/local_storage.c
    @@ -259,7 +259,7 @@ static int cgroup_storage_get_next_key(struct bpf_map *_map, void *key,
     			goto enoent;
     
     		storage = list_next_entry(storage, list_map);
    -		if (!storage)
    +		if (list_entry_is_head(storage, &map->list, list_map))
     			goto enoent;
     	} else {
     		storage = list_first_entry(&map->list,
    -- 
    cgit 1.3-korg
    
    
    
85a2f30e40f7

bpf: fix end-of-list detection in cgroup_storage_get_next_key()

1 file changed · +1 2
  • kernel/bpf/local_storage.c+1 2 modified
    diff --git a/kernel/bpf/local_storage.c b/kernel/bpf/local_storage.c
    index 3969eb0382afba..cfb4ff26105186 100644
    --- a/kernel/bpf/local_storage.c
    +++ b/kernel/bpf/local_storage.c
    @@ -259,7 +259,7 @@ static int cgroup_storage_get_next_key(struct bpf_map *_map, void *key,
     			goto enoent;
     
     		storage = list_next_entry(storage, list_map);
    -		if (!storage)
    +		if (list_entry_is_head(storage, &map->list, list_map))
     			goto enoent;
     	} else {
     		storage = list_first_entry(&map->list,
    -- 
    cgit 1.3-korg
    
    
    
32ce55d42439

bpf: fix end-of-list detection in cgroup_storage_get_next_key()

1 file changed · +1 2
  • kernel/bpf/local_storage.c+1 2 modified
    diff --git a/kernel/bpf/local_storage.c b/kernel/bpf/local_storage.c
    index c93a756e035c02..b8db4fbd3bd2ae 100644
    --- a/kernel/bpf/local_storage.c
    +++ b/kernel/bpf/local_storage.c
    @@ -259,7 +259,7 @@ static int cgroup_storage_get_next_key(struct bpf_map *_map, void *key,
     			goto enoent;
     
     		storage = list_next_entry(storage, list_map);
    -		if (!storage)
    +		if (list_entry_is_head(storage, &map->list, list_map))
     			goto enoent;
     	} else {
     		storage = list_first_entry(&map->list,
    -- 
    cgit 1.3-korg
    
    
    
fc39753b7f92

bpf: fix end-of-list detection in cgroup_storage_get_next_key()

1 file changed · +1 2
  • kernel/bpf/local_storage.c+1 2 modified
    diff --git a/kernel/bpf/local_storage.c b/kernel/bpf/local_storage.c
    index 8fca0c64f7b1cd..23267213a17fb7 100644
    --- a/kernel/bpf/local_storage.c
    +++ b/kernel/bpf/local_storage.c
    @@ -270,7 +270,7 @@ static int cgroup_storage_get_next_key(struct bpf_map *_map, void *key,
     			goto enoent;
     
     		storage = list_next_entry(storage, list_map);
    -		if (!storage)
    +		if (list_entry_is_head(storage, &map->list, list_map))
     			goto enoent;
     	} else {
     		storage = list_first_entry(&map->list,
    -- 
    cgit 1.3-korg
    
    
    
32ce55d42439

bpf: fix end-of-list detection in cgroup_storage_get_next_key()

1 file changed · +1 2
  • kernel/bpf/local_storage.c+1 2 modified
    diff --git a/kernel/bpf/local_storage.c b/kernel/bpf/local_storage.c
    index c93a756e035c02..b8db4fbd3bd2ae 100644
    --- a/kernel/bpf/local_storage.c
    +++ b/kernel/bpf/local_storage.c
    @@ -259,7 +259,7 @@ static int cgroup_storage_get_next_key(struct bpf_map *_map, void *key,
     			goto enoent;
     
     		storage = list_next_entry(storage, list_map);
    -		if (!storage)
    +		if (list_entry_is_head(storage, &map->list, list_map))
     			goto enoent;
     	} else {
     		storage = list_first_entry(&map->list,
    -- 
    cgit 1.3-korg
    
    
    
5828b9e5b272

bpf: fix end-of-list detection in cgroup_storage_get_next_key()

1 file changed · +1 2
  • kernel/bpf/local_storage.c+1 2 modified
    diff --git a/kernel/bpf/local_storage.c b/kernel/bpf/local_storage.c
    index 8fca0c64f7b1cd..23267213a17fb7 100644
    --- a/kernel/bpf/local_storage.c
    +++ b/kernel/bpf/local_storage.c
    @@ -270,7 +270,7 @@ static int cgroup_storage_get_next_key(struct bpf_map *_map, void *key,
     			goto enoent;
     
     		storage = list_next_entry(storage, list_map);
    -		if (!storage)
    +		if (list_entry_is_head(storage, &map->list, list_map))
     			goto enoent;
     	} else {
     		storage = list_first_entry(&map->list,
    -- 
    cgit 1.3-korg
    
    
    
85a2f30e40f7

bpf: fix end-of-list detection in cgroup_storage_get_next_key()

1 file changed · +1 2
  • kernel/bpf/local_storage.c+1 2 modified
    diff --git a/kernel/bpf/local_storage.c b/kernel/bpf/local_storage.c
    index 3969eb0382afba..cfb4ff26105186 100644
    --- a/kernel/bpf/local_storage.c
    +++ b/kernel/bpf/local_storage.c
    @@ -259,7 +259,7 @@ static int cgroup_storage_get_next_key(struct bpf_map *_map, void *key,
     			goto enoent;
     
     		storage = list_next_entry(storage, list_map);
    -		if (!storage)
    +		if (list_entry_is_head(storage, &map->list, list_map))
     			goto enoent;
     	} else {
     		storage = list_first_entry(&map->list,
    -- 
    cgit 1.3-korg
    
    
    
b4b5a20bed82

bpf: fix end-of-list detection in cgroup_storage_get_next_key()

1 file changed · +1 2
  • kernel/bpf/local_storage.c+1 2 modified
    diff --git a/kernel/bpf/local_storage.c b/kernel/bpf/local_storage.c
    index a04f505aefe9b6..c8b8dcc37ed4a7 100644
    --- a/kernel/bpf/local_storage.c
    +++ b/kernel/bpf/local_storage.c
    @@ -259,7 +259,7 @@ static int cgroup_storage_get_next_key(struct bpf_map *_map, void *key,
     			goto enoent;
     
     		storage = list_next_entry(storage, list_map);
    -		if (!storage)
    +		if (list_entry_is_head(storage, &map->list, list_map))
     			goto enoent;
     	} else {
     		storage = list_first_entry(&map->list,
    -- 
    cgit 1.3-korg
    
    
    
fc39753b7f92

bpf: fix end-of-list detection in cgroup_storage_get_next_key()

1 file changed · +1 2
  • kernel/bpf/local_storage.c+1 2 modified
    diff --git a/kernel/bpf/local_storage.c b/kernel/bpf/local_storage.c
    index 8fca0c64f7b1cd..23267213a17fb7 100644
    --- a/kernel/bpf/local_storage.c
    +++ b/kernel/bpf/local_storage.c
    @@ -270,7 +270,7 @@ static int cgroup_storage_get_next_key(struct bpf_map *_map, void *key,
     			goto enoent;
     
     		storage = list_next_entry(storage, list_map);
    -		if (!storage)
    +		if (list_entry_is_head(storage, &map->list, list_map))
     			goto enoent;
     	} else {
     		storage = list_first_entry(&map->list,
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Incorrect end-of-list detection: list_next_entry() never returns NULL, so the NULL check is dead code and the function reads from a bogus pointer when iterating past the last entry."

Attack vector

An attacker with the ability to iterate BPF cgroup storage map keys (e.g., via `bpf_map_get_next_key()` from userspace) can trigger this bug. When the last valid storage entry is reached, `list_next_entry()` wraps to the list head instead of returning NULL, so the dead NULL check is skipped. The function then reads `storage->key` from a bogus pointer that aliases internal map fields and copies that data to userspace, leaking kernel memory [patch_id=2654231]. No special privileges beyond the ability to iterate the map are required.

Affected code

The vulnerability is in `cgroup_storage_get_next_key()` in `kernel/bpf/local_storage.c` [patch_id=2654231]. The function uses `list_next_entry()` to advance through the cgroup storage map's linked list, but then checks `if (!storage)` to detect the end of the list — a check that can never be true because `list_next_entry()` wraps to the list head rather than returning NULL.

What the fix does

The patch replaces the dead `if (!storage)` check with `if (list_entry_is_head(storage, &map->list, list_map))` [patch_id=2654231]. The `list_entry_is_head()` macro correctly detects when the pointer has wrapped back to the list head, causing the function to return `-ENOENT` as intended. This closes the information leak by ensuring no out-of-bounds read occurs when iterating past the last entry.

Preconditions

  • authThe attacker must be able to invoke bpf_map_get_next_key() on a BPF_MAP_TYPE_CGROUP_STORAGE map from userspace.
  • inputThe cgroup storage map must have at least one entry so that iteration reaches the last element.

Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.