From: Yongzhen Zhang zhangyongzhen@kylinos.cn
[ Upstream commit 523b84dc7ccea9c4d79126d6ed1cf9033cf83b05 ]
The current implementation may lead to buffer overflow when: 1. Unregistration creates NULL gaps in registered_fb[] 2. All array slots become occupied despite num_registered_fb < FB_MAX 3. The registration loop exceeds array bounds
Add boundary check to prevent registered_fb[FB_MAX] access.
Signed-off-by: Yongzhen Zhang zhangyongzhen@kylinos.cn Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
**Backport Status: YES**
This commit should be backported to stable kernel trees for the following reasons:
## Critical Bug Fix The patch fixes a legitimate **buffer overflow vulnerability** in the framebuffer registration code. The vulnerability occurs when:
1. **Array bounds violation**: After the loop at lines 448-450 searches for an empty slot in `registered_fb[]`, the variable `i` could equal `FB_MAX` (32) if no empty slot is found 2. **Out-of-bounds access**: Without the added check, line 460 (`fb_info->node = i`) and line 499 (`registered_fb[i] = fb_info`) would access `registered_fb[FB_MAX]`, which is beyond the array bounds (array indices are 0-31)
## Security Impact This is a **security-relevant fix** that prevents potential kernel memory corruption: - Writing to `registered_fb[FB_MAX]` at line 499 would corrupt memory beyond the array - This could lead to system crashes, unpredictable behavior, or potentially be exploited for privilege escalation
## Meets Stable Criteria The fix perfectly aligns with stable tree requirements: - **Small and contained**: Only 3 lines added (the check and return statement) - **No feature changes**: Pure bug fix with no functional changes - **Minimal regression risk**: The added check is defensive and cannot break existing functionality - **Clear bug fix**: Addresses a specific, well-defined issue
## Code Analysis The vulnerability scenario is real and can occur when: 1. The system has gaps in `registered_fb[]` due to framebuffer unregistration (line 545 in `do_unregister_framebuffer` sets slots to NULL) 2. The condition `num_registered_fb < FB_MAX` passes (line 445) but all 32 slots happen to be occupied with non-contiguous registrations 3. The loop finds no empty slot, leaving `i = FB_MAX`
The fix adds a crucial boundary check at the right location, immediately after the search loop, preventing any possibility of out-of-bounds access.
This is exactly the type of fix that should be backported to stable kernels - it addresses a real security vulnerability with minimal code change and zero risk of introducing new issues.
drivers/video/fbdev/core/fbmem.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index dfcf5e4d1d4c..53f1719b1ae1 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -449,6 +449,9 @@ static int do_register_framebuffer(struct fb_info *fb_info) if (!registered_fb[i]) break;
+ if (i >= FB_MAX) + return -ENXIO; + if (!fb_info->modelist.prev || !fb_info->modelist.next) INIT_LIST_HEAD(&fb_info->modelist);