Re: [PATCH v2] fbdev: omap2: fix use-after-free in omapfb_mmap

Helge Deller <[email protected]>
Newsgroups org.kernel.vger.linux-omap,org.freedesktop.lists.dri-devel,org.kernel.vger.linux-fbdev,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On 6/2/26 10:54, Hongling Zeng wrote:
> omapfb_mmap() has a race condition with OMAPFB_SETUP_PLANE ioctl that
> can lead to use-after-free:
> 
> The fb_mmap() entry point holds mm_lock but not lock (fb_info->lock),
> while ioctl handlers like OMAPFB_SETUP_PLANE hold lock but not mm_lock.
> This allows concurrent execution.
> 
> In omapfb_mmap():
> 1. rg = omapfb_get_mem_region(ofbi->region);      // Get old region ref
> 2. start = omapfb_get_region_paddr(ofbi);          // Read from NEW region
> 3. len = fix->smem_len;                             // Read from NEW region
> 4. vm_iomap_memory(vma, start, len);               // Map NEW region memory
> 5. atomic_inc(&rg->map_count);                      // Increment OLD region!
> 
> Concurrently, OMAPFB_SETUP_PLANE can:
> - Reassign ofbi->region = new_rg
> - Update fix->smem_len
> - OMAPFB_SETUP_MEM then checks NEW region's map_count (0!) and frees it
> 
> This leaves userspace with a mapping to freed physical memory.
> 
> The fix is to read all required values (start, len) from the same
> region reference (rg) that will have its map_count incremented,
> preventing the region from being freed while still mapped.
> 
> Cc: [email protected]
> Signed-off-by: Hongling Zeng <[email protected]>
> 
> ---
>   Change in V2:
>    -Restore fix->smem_len to maintain VRFB sparse mapping.
>    -Increment map_count before mapping to prevent use-after-free
>     on driver unload
>    -Add proper error handling for map_count
> ---
>   drivers/video/fbdev/omap2/omapfb/omapfb-main.c | 9 ++++++++-
>   1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c
> index d70deb6a9150..046892682fc6 100644
> --- a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c
> +++ b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c
> @@ -1099,7 +1099,11 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
>   
>   	rg = omapfb_get_mem_region(ofbi->region);
>   
> -	start = omapfb_get_region_paddr(ofbi);
> +	if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
> +		start = rg->vrfb.paddr[0];
> +	else
> +		start = rg->paddr;
> +
>   	len = fix->smem_len;
>   
>   	DBG("user mmap region start %lx, len %d, off %lx\n", start, len,
> @@ -1109,6 +1113,8 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
>   	vma->vm_ops = &mmap_user_ops;
>   	vma->vm_private_data = rg;
>   
> +	atomic_inc(&rg->map_count);
> +
>   	r = vm_iomap_memory(vma, start, len);
>   	if (r)
>   		goto error;
In the code there is another atomic_inc() here....
With your patch, map_count is incremented twice.
Is this right?

Helge
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.