Re: [PATCH] mm: don't clobber partially overlapping VMA with MAP_FIXED_NOREPLACE

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Oct 10, 2018 at 8:27 AM, Jann Horn <jannh@xxxxxxxxxx> wrote:
> Daniel Micay reports that attempting to use MAP_FIXED_NOREPLACE in an
> application causes that application to randomly crash. The existing check
> for handling MAP_FIXED_NOREPLACE looks up the first VMA that either
> overlaps or follows the requested region, and then bails out if that VMA
> overlaps *the start* of the requested region. It does not bail out if the
> VMA only overlaps another part of the requested region.
>
> Fix it by checking that the found VMA only starts at or after the end of
> the requested region, in which case there is no overlap.
>
> Reported-by: Daniel Micay <danielmicay@xxxxxxxxx>
> Fixes: a4ff8e8620d3 ("mm: introduce MAP_FIXED_NOREPLACE")
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Jann Horn <jannh@xxxxxxxxxx>

Acked-by: Kees Cook <keescook@xxxxxxxxxxxx>

Thanks for forwarding this!

Andrew, any chance we can get this into 4.19? (It'll end up in -stable
anyway, but it'd be nice to get it fixed now too.)

-Kees

> ---
>  mm/mmap.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/mm/mmap.c b/mm/mmap.c
> index 5f2b2b184c60..f7cd9cb966c0 100644
> --- a/mm/mmap.c
> +++ b/mm/mmap.c
> @@ -1410,7 +1410,7 @@ unsigned long do_mmap(struct file *file, unsigned long addr,
>         if (flags & MAP_FIXED_NOREPLACE) {
>                 struct vm_area_struct *vma = find_vma(mm, addr);
>
> -               if (vma && vma->vm_start <= addr)
> +               if (vma && vma->vm_start < addr + len)
>                         return -EEXIST;
>         }
>
> --
> 2.19.0.605.g01d371f741-goog
>



-- 
Kees Cook
Pixel Security




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux