qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] linux-user/elfload: do not assume MAP_FIXED_NOREPLACE kernel support
@ 2021-01-31  6:19 Vincent Fazio
  2021-02-13 21:44 ` Laurent Vivier
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Vincent Fazio @ 2021-01-31  6:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-trivial, laurent, Vincent Fazio

From: Vincent Fazio <vfazio@gmail.com>

Previously, pgd_find_hole_fallback assumed that if the build host's libc
had MAP_FIXED_NOREPLACE defined that the address returned by mmap would
match the requested address. This is not a safe assumption for Linux
kernels prior to 4.17

Now, we always compare mmap's resultant address with the requested
address and no longer short-circuit based on MAP_FIXED_NOREPLACE.

Fixes: 2667e069e7b5 ("linux-user: don't use MAP_FIXED in pgd_find_hole_fallback")
Signed-off-by: Vincent Fazio <vfazio@gmail.com>
---
 linux-user/elfload.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 5f5f23d2e5..8d425f9ed0 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -2217,8 +2217,7 @@ static uintptr_t pgd_find_hole_fallback(uintptr_t guest_size, uintptr_t brk,
                                      PROT_NONE, flags, -1, 0);
             if (mmap_start != MAP_FAILED) {
                 munmap(mmap_start, guest_size);
-                if (MAP_FIXED_NOREPLACE != 0 ||
-                    mmap_start == (void *) align_start) {
+                if (mmap_start == (void *) align_start) {
                     return (uintptr_t) mmap_start + offset;
                 }
             }
-- 
2.30.0



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] linux-user/elfload: do not assume MAP_FIXED_NOREPLACE kernel support
  2021-01-31  6:19 [PATCH] linux-user/elfload: do not assume MAP_FIXED_NOREPLACE kernel support Vincent Fazio
@ 2021-02-13 21:44 ` Laurent Vivier
  2021-02-14 11:24 ` Alex Bennée
  2021-03-09 20:36 ` Laurent Vivier
  2 siblings, 0 replies; 8+ messages in thread
From: Laurent Vivier @ 2021-02-13 21:44 UTC (permalink / raw)
  To: Vincent Fazio, qemu-devel; +Cc: qemu-trivial, Alex Bennée, Vincent Fazio

Le 31/01/2021 à 07:19, Vincent Fazio a écrit :
> From: Vincent Fazio <vfazio@gmail.com>
> 
> Previously, pgd_find_hole_fallback assumed that if the build host's libc
> had MAP_FIXED_NOREPLACE defined that the address returned by mmap would
> match the requested address. This is not a safe assumption for Linux
> kernels prior to 4.17
> 
> Now, we always compare mmap's resultant address with the requested
> address and no longer short-circuit based on MAP_FIXED_NOREPLACE.
> 
> Fixes: 2667e069e7b5 ("linux-user: don't use MAP_FIXED in pgd_find_hole_fallback")
> Signed-off-by: Vincent Fazio <vfazio@gmail.com>
> ---
>  linux-user/elfload.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/linux-user/elfload.c b/linux-user/elfload.c
> index 5f5f23d2e5..8d425f9ed0 100644
> --- a/linux-user/elfload.c
> +++ b/linux-user/elfload.c
> @@ -2217,8 +2217,7 @@ static uintptr_t pgd_find_hole_fallback(uintptr_t guest_size, uintptr_t brk,
>                                       PROT_NONE, flags, -1, 0);
>              if (mmap_start != MAP_FAILED) {
>                  munmap(mmap_start, guest_size);
> -                if (MAP_FIXED_NOREPLACE != 0 ||
> -                    mmap_start == (void *) align_start) {
> +                if (mmap_start == (void *) align_start) {
>                      return (uintptr_t) mmap_start + offset;
>                  }
>              }
> 

Reviewed-by: Laurent Vivier <laurent@vivier.eu>

CC: Alex

Why did you put this checking in first place?

Thanks,
Laurent


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] linux-user/elfload: do not assume MAP_FIXED_NOREPLACE kernel support
  2021-01-31  6:19 [PATCH] linux-user/elfload: do not assume MAP_FIXED_NOREPLACE kernel support Vincent Fazio
  2021-02-13 21:44 ` Laurent Vivier
@ 2021-02-14 11:24 ` Alex Bennée
  2021-02-14 12:50   ` Laurent Vivier
  2021-03-09 20:36 ` Laurent Vivier
  2 siblings, 1 reply; 8+ messages in thread
From: Alex Bennée @ 2021-02-14 11:24 UTC (permalink / raw)
  To: Vincent Fazio; +Cc: qemu-trivial, laurent, Vincent Fazio, qemu-devel


Vincent Fazio <vfazio@xes-inc.com> writes:

> From: Vincent Fazio <vfazio@gmail.com>
>
> Previously, pgd_find_hole_fallback assumed that if the build host's libc
> had MAP_FIXED_NOREPLACE defined that the address returned by mmap would
> match the requested address. This is not a safe assumption for Linux
> kernels prior to 4.17

It doesn't as we have in osdep.h:

  #ifndef MAP_FIXED_NOREPLACE
  #define MAP_FIXED_NOREPLACE 0
  #endif

which is to say to assume if MAP_FIXED_NOREPLACE is defined the kernel
should have given us what we want otherwise we do the check.

>
> Now, we always compare mmap's resultant address with the requested
> address and no longer short-circuit based on MAP_FIXED_NOREPLACE.
>
> Fixes: 2667e069e7b5 ("linux-user: don't use MAP_FIXED in pgd_find_hole_fallback")
> Signed-off-by: Vincent Fazio <vfazio@gmail.com>
> ---
>  linux-user/elfload.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/linux-user/elfload.c b/linux-user/elfload.c
> index 5f5f23d2e5..8d425f9ed0 100644
> --- a/linux-user/elfload.c
> +++ b/linux-user/elfload.c
> @@ -2217,8 +2217,7 @@ static uintptr_t pgd_find_hole_fallback(uintptr_t guest_size, uintptr_t brk,
>                                       PROT_NONE, flags, -1, 0);
>              if (mmap_start != MAP_FAILED) {
>                  munmap(mmap_start, guest_size);
> -                if (MAP_FIXED_NOREPLACE != 0 ||
> -                    mmap_start == (void *) align_start) {
> +                if (mmap_start == (void *) align_start) {
>                      return (uintptr_t) mmap_start + offset;
>                  }
>              }


-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] linux-user/elfload: do not assume MAP_FIXED_NOREPLACE kernel support
  2021-02-14 11:24 ` Alex Bennée
@ 2021-02-14 12:50   ` Laurent Vivier
  2021-02-14 14:20     ` Vincent Fazio
  0 siblings, 1 reply; 8+ messages in thread
From: Laurent Vivier @ 2021-02-14 12:50 UTC (permalink / raw)
  To: Alex Bennée, Vincent Fazio; +Cc: qemu-trivial, qemu-devel, Vincent Fazio

Le 14/02/2021 à 12:24, Alex Bennée a écrit :
> 
> Vincent Fazio <vfazio@xes-inc.com> writes:
> 
>> From: Vincent Fazio <vfazio@gmail.com>
>>
>> Previously, pgd_find_hole_fallback assumed that if the build host's libc
>> had MAP_FIXED_NOREPLACE defined that the address returned by mmap would
>> match the requested address. This is not a safe assumption for Linux
>> kernels prior to 4.17
> 
> It doesn't as we have in osdep.h:
> 
>   #ifndef MAP_FIXED_NOREPLACE
>   #define MAP_FIXED_NOREPLACE 0
>   #endif
> 
> which is to say to assume if MAP_FIXED_NOREPLACE is defined the kernel
> should have given us what we want otherwise we do the check.


But what is the purpose of the "if (MAP_FIXED_NOREPLACE != 0 ||"?
Can't we rely only on "mmap_start == (void *) align_start"?

Thanks,
Laurent

>>
>> Now, we always compare mmap's resultant address with the requested
>> address and no longer short-circuit based on MAP_FIXED_NOREPLACE.
>>
>> Fixes: 2667e069e7b5 ("linux-user: don't use MAP_FIXED in pgd_find_hole_fallback")
>> Signed-off-by: Vincent Fazio <vfazio@gmail.com>
>> ---
>>  linux-user/elfload.c | 3 +--
>>  1 file changed, 1 insertion(+), 2 deletions(-)
>>
>> diff --git a/linux-user/elfload.c b/linux-user/elfload.c
>> index 5f5f23d2e5..8d425f9ed0 100644
>> --- a/linux-user/elfload.c
>> +++ b/linux-user/elfload.c
>> @@ -2217,8 +2217,7 @@ static uintptr_t pgd_find_hole_fallback(uintptr_t guest_size, uintptr_t brk,
>>                                       PROT_NONE, flags, -1, 0);
>>              if (mmap_start != MAP_FAILED) {
>>                  munmap(mmap_start, guest_size);
>> -                if (MAP_FIXED_NOREPLACE != 0 ||
>> -                    mmap_start == (void *) align_start) {
>> +                if (mmap_start == (void *) align_start) {
>>                      return (uintptr_t) mmap_start + offset;
>>                  }
>>              }
> 
> 



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] linux-user/elfload: do not assume MAP_FIXED_NOREPLACE kernel support
  2021-02-14 12:50   ` Laurent Vivier
@ 2021-02-14 14:20     ` Vincent Fazio
  2021-02-15  9:52       ` Alex Bennée
  0 siblings, 1 reply; 8+ messages in thread
From: Vincent Fazio @ 2021-02-14 14:20 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: qemu-trivial, Alex Bennée, Vincent Fazio, qemu-devel

On Sun, Feb 14, 2021 at 6:50 AM Laurent Vivier <laurent@vivier.eu> wrote:
>
> Le 14/02/2021 à 12:24, Alex Bennée a écrit :
> >
> > Vincent Fazio <vfazio@xes-inc.com> writes:
> >
> >> From: Vincent Fazio <vfazio@gmail.com>
> >>
> >> Previously, pgd_find_hole_fallback assumed that if the build host's libc
> >> had MAP_FIXED_NOREPLACE defined that the address returned by mmap would
> >> match the requested address. This is not a safe assumption for Linux
> >> kernels prior to 4.17
> >
> > It doesn't as we have in osdep.h:
> >
> >   #ifndef MAP_FIXED_NOREPLACE
> >   #define MAP_FIXED_NOREPLACE 0
> >   #endif
> >
> > which is to say to assume if MAP_FIXED_NOREPLACE is defined the kernel
> > should have given us what we want otherwise we do the check.
>
>
> But what is the purpose of the "if (MAP_FIXED_NOREPLACE != 0 ||"?
> Can't we rely only on "mmap_start == (void *) align_start"?
>
> Thanks,
> Laurent
>

I think we have to rely on address matching. The problem is
specifically when MAP_FIXED_NOREPLACE is defined and is passed to mmap
but the running kernel doesn't know what to do with the flag so
returns a value that is not what was hinted at. Previously the code
assumed that if MAP_FIXED_NOREPLACE was defined that the returned
address would match, but that isn't always the case if the kernel
doesn't have support for the flag. The 4.4, 4.9 and 4.14 LTS kernels
are still in use and could run into this problem.

-Vincent


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] linux-user/elfload: do not assume MAP_FIXED_NOREPLACE kernel support
  2021-02-14 14:20     ` Vincent Fazio
@ 2021-02-15  9:52       ` Alex Bennée
  2021-02-25 14:26         ` Vincent Fazio
  0 siblings, 1 reply; 8+ messages in thread
From: Alex Bennée @ 2021-02-15  9:52 UTC (permalink / raw)
  To: Vincent Fazio; +Cc: qemu-trivial, qemu-devel, Laurent Vivier, Vincent Fazio


Vincent Fazio <vfazio@gmail.com> writes:

> On Sun, Feb 14, 2021 at 6:50 AM Laurent Vivier <laurent@vivier.eu> wrote:
>>
>> Le 14/02/2021 à 12:24, Alex Bennée a écrit :
>> >
>> > Vincent Fazio <vfazio@xes-inc.com> writes:
>> >
>> >> From: Vincent Fazio <vfazio@gmail.com>
>> >>
>> >> Previously, pgd_find_hole_fallback assumed that if the build host's libc
>> >> had MAP_FIXED_NOREPLACE defined that the address returned by mmap would
>> >> match the requested address. This is not a safe assumption for Linux
>> >> kernels prior to 4.17
>> >
>> > It doesn't as we have in osdep.h:
>> >
>> >   #ifndef MAP_FIXED_NOREPLACE
>> >   #define MAP_FIXED_NOREPLACE 0
>> >   #endif
>> >
>> > which is to say to assume if MAP_FIXED_NOREPLACE is defined the kernel
>> > should have given us what we want otherwise we do the check.
>>
>>
>> But what is the purpose of the "if (MAP_FIXED_NOREPLACE != 0 ||"?
>> Can't we rely only on "mmap_start == (void *) align_start"?
>>
>> Thanks,
>> Laurent
>>
>
> I think we have to rely on address matching. The problem is
> specifically when MAP_FIXED_NOREPLACE is defined and is passed to mmap
> but the running kernel doesn't know what to do with the flag so
> returns a value that is not what was hinted at. Previously the code
> assumed that if MAP_FIXED_NOREPLACE was defined that the returned
> address would match, but that isn't always the case if the kernel
> doesn't have support for the flag. The 4.4, 4.9 and 4.14 LTS kernels
> are still in use and could run into this problem.

Ahh right so I think this is a case of binaries being built on a
different platform than kernel they are running on. In which case the
flag would be defined but the underlying kernel fails to identify it. Is
this a container like case by any chance?

If I'd read the man page closer:

   Note   that   older   kernels   which   do   not  recognize  the
   MAP_FIXED_NOREPLACE flag will typically (upon detecting a colli‐
   sion  with a preexisting mapping) fall back to a "non-MAP_FIXED"
   type of behavior: they will return an address that is  different
   from  the  requested  address.   Therefore,  backward-compatible
   software should check the returned address against the requested
   address.

so yes we should avoid short circuiting the return address check.

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>

-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] linux-user/elfload: do not assume MAP_FIXED_NOREPLACE kernel support
  2021-02-15  9:52       ` Alex Bennée
@ 2021-02-25 14:26         ` Vincent Fazio
  0 siblings, 0 replies; 8+ messages in thread
From: Vincent Fazio @ 2021-02-25 14:26 UTC (permalink / raw)
  To: Alex Bennée, Vincent Fazio; +Cc: qemu-trivial, Laurent Vivier, qemu-devel




On 2/15/21 3:52 AM, Alex Bennée wrote:
> 
> Vincent Fazio <vfazio@gmail.com> writes:
> 
> 
> Ahh right so I think this is a case of binaries being built on a
> different platform than kernel they are running on. In which case the
> flag would be defined but the underlying kernel fails to identify it. Is
> this a container like case by any chance?
Yes, my builds were happening in a container to eventually have the statically built binaries run in another container. 
I discovered this issue (and the two others reviewed) while trying to debootstrap Debian Bullseye in a container.
> 
> If I'd read the man page closer:
> 
>     Note   that   older   kernels   which   do   not  recognize  the
>     MAP_FIXED_NOREPLACE flag will typically (upon detecting a colli‐
>     sion  with a preexisting mapping) fall back to a "non-MAP_FIXED"
>     type of behavior: they will return an address that is  different
>     from  the  requested  address.   Therefore,  backward-compatible
>     software should check the returned address against the requested
>     address.
> 
> so yes we should avoid short circuiting the return address check.
> 
> Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
> 


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] linux-user/elfload: do not assume MAP_FIXED_NOREPLACE kernel support
  2021-01-31  6:19 [PATCH] linux-user/elfload: do not assume MAP_FIXED_NOREPLACE kernel support Vincent Fazio
  2021-02-13 21:44 ` Laurent Vivier
  2021-02-14 11:24 ` Alex Bennée
@ 2021-03-09 20:36 ` Laurent Vivier
  2 siblings, 0 replies; 8+ messages in thread
From: Laurent Vivier @ 2021-03-09 20:36 UTC (permalink / raw)
  To: Vincent Fazio, qemu-devel; +Cc: qemu-trivial, Vincent Fazio

Le 31/01/2021 à 07:19, Vincent Fazio a écrit :
> From: Vincent Fazio <vfazio@gmail.com>
> 
> Previously, pgd_find_hole_fallback assumed that if the build host's libc
> had MAP_FIXED_NOREPLACE defined that the address returned by mmap would
> match the requested address. This is not a safe assumption for Linux
> kernels prior to 4.17
> 
> Now, we always compare mmap's resultant address with the requested
> address and no longer short-circuit based on MAP_FIXED_NOREPLACE.
> 
> Fixes: 2667e069e7b5 ("linux-user: don't use MAP_FIXED in pgd_find_hole_fallback")
> Signed-off-by: Vincent Fazio <vfazio@gmail.com>
> ---
>  linux-user/elfload.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/linux-user/elfload.c b/linux-user/elfload.c
> index 5f5f23d2e5..8d425f9ed0 100644
> --- a/linux-user/elfload.c
> +++ b/linux-user/elfload.c
> @@ -2217,8 +2217,7 @@ static uintptr_t pgd_find_hole_fallback(uintptr_t guest_size, uintptr_t brk,
>                                       PROT_NONE, flags, -1, 0);
>              if (mmap_start != MAP_FAILED) {
>                  munmap(mmap_start, guest_size);
> -                if (MAP_FIXED_NOREPLACE != 0 ||
> -                    mmap_start == (void *) align_start) {
> +                if (mmap_start == (void *) align_start) {
>                      return (uintptr_t) mmap_start + offset;
>                  }
>              }
> 

Applied to my linux-user-for-6.0 branch.

Thanks,
Laurent



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-03-09 21:07 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-31  6:19 [PATCH] linux-user/elfload: do not assume MAP_FIXED_NOREPLACE kernel support Vincent Fazio
2021-02-13 21:44 ` Laurent Vivier
2021-02-14 11:24 ` Alex Bennée
2021-02-14 12:50   ` Laurent Vivier
2021-02-14 14:20     ` Vincent Fazio
2021-02-15  9:52       ` Alex Bennée
2021-02-25 14:26         ` Vincent Fazio
2021-03-09 20:36 ` Laurent Vivier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).