[PATCH] mm/bpf_memcontrol: fix signed enum bounds check bypass via negative values

chenyuan_fl@163.com posted 1 patch 1 month ago
mm/bpf_memcontrol.c | 2 +-
mm/memcontrol.c     | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
[PATCH] mm/bpf_memcontrol: fix signed enum bounds check bypass via negative values
Posted by chenyuan_fl@163.com 1 month ago
From: Yuan Chen <chenyuan@kylinos.cn>

bpf_mem_cgroup_memory_events() and memcg_vm_event_item_valid() use signed
>= comparisons on enum-typed arguments, so a BPF program passing a
negative value evades the upper-bound check and is then used as a
negative array index, causing out-of-bounds reads.

Cast the input to u32 before the comparison, matching the pattern
already used in memcg_stat_item_valid().

Fixes: 99430ab8b804c26b ("mm: introduce BPF kfuncs to access memcg statistics and events")
Cc: stable@vger.kernel.org
Signed-off-by: Yuan Chen <chenyuan@kylinos.cn>
---
 mm/bpf_memcontrol.c | 2 +-
 mm/memcontrol.c     | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/mm/bpf_memcontrol.c b/mm/bpf_memcontrol.c
index 716df49d7647..5e8107f240ba 100644
--- a/mm/bpf_memcontrol.c
+++ b/mm/bpf_memcontrol.c
@@ -125,7 +125,7 @@ __bpf_kfunc unsigned long bpf_mem_cgroup_usage(struct mem_cgroup *memcg)
 __bpf_kfunc unsigned long bpf_mem_cgroup_memory_events(struct mem_cgroup *memcg,
 						       enum memcg_memory_event event)
 {
-	if (unlikely(event >= MEMCG_NR_MEMORY_EVENTS))
+	if (unlikely((u32)event >= MEMCG_NR_MEMORY_EVENTS))
 		return (unsigned long)-1;
 
 	return atomic_long_read(&memcg->memory_events[event]);
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 6dc4888a90f3..42a1b855bb75 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1058,7 +1058,7 @@ unsigned long memcg_events(struct mem_cgroup *memcg, int event)
 
 bool memcg_vm_event_item_valid(enum vm_event_item idx)
 {
-	if (idx >= NR_VM_EVENT_ITEMS)
+	if ((u32)idx >= NR_VM_EVENT_ITEMS)
 		return false;
 
 	return !BAD_STAT_IDX(memcg_events_index(idx));
-- 
2.54.0