unofficial mirror of libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097]
@ 2019-01-17 16:53 H.J. Lu
  2019-01-18 10:50 ` Florian Weimer
  0 siblings, 1 reply; 25+ messages in thread
From: H.J. Lu @ 2019-01-17 16:53 UTC (permalink / raw)
  To: libc-alpha

On x32, the size_t parameter may be passed in the lower 32 bits of a
64-bit register with the non-zero upper 32 bits.  The string/memory
functions written in assembly can only use the lower 32 bits of a
64-bit register as length or must clear the upper 32 bits before using
the full 64-bit register for length.

This pach fixes string/memory functions written in assembly for x32.
Tested on x86-64 and x32.  On x86-64, libc.so is the same with and
withou the fix.

H.J. Lu (8):
  x86-64 memchr/wmemchr: Properly handle the length parameter [BZ#
    24097]
  x86-64 memcmp/wmemcmp: Properly handle the length parameter [BZ#
    24097]
  x86-64 memcpy: Properly handle the length parameter [BZ# 24097]
  x86-64 memrchr: Properly handle the length parameter [BZ# 24097]
  x86-64 memset/wmemset: Properly handle the length parameter [BZ#
    24097]
  x86-64 strncmp family: Properly handle the length parameter [BZ#
    24097]
  x86-64 strncpy: Properly handle the length parameter [BZ# 24097]
  x86-64 strnlen/wcsnlen: Properly handle the length parameter [BZ#
    24097]

 sysdeps/x86_64/memchr.S                       |  10 +-
 sysdeps/x86_64/memrchr.S                      |   4 +-
 sysdeps/x86_64/multiarch/memchr-avx2.S        |   8 +-
 sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S  |   7 +-
 sysdeps/x86_64/multiarch/memcmp-sse4.S        |   9 +-
 sysdeps/x86_64/multiarch/memcmp-ssse3.S       |   7 +-
 sysdeps/x86_64/multiarch/memcpy-ssse3-back.S  |  17 +-
 sysdeps/x86_64/multiarch/memcpy-ssse3.S       |  17 +-
 .../multiarch/memmove-avx512-no-vzeroupper.S  |  16 +-
 .../multiarch/memmove-vec-unaligned-erms.S    |  54 +++---
 sysdeps/x86_64/multiarch/memrchr-avx2.S       |   4 +-
 .../multiarch/memset-avx512-no-vzeroupper.S   |   6 +-
 .../multiarch/memset-vec-unaligned-erms.S     |  34 ++--
 sysdeps/x86_64/multiarch/strcmp-avx2.S        |   6 +-
 sysdeps/x86_64/multiarch/strcmp-sse42.S       |   6 +-
 sysdeps/x86_64/multiarch/strcpy-avx2.S        |   4 +-
 .../x86_64/multiarch/strcpy-sse2-unaligned.S  |   4 +-
 sysdeps/x86_64/multiarch/strcpy-ssse3.S       |   6 +-
 sysdeps/x86_64/multiarch/strlen-avx2.S        |   9 +-
 sysdeps/x86_64/strcmp.S                       |   6 +-
 sysdeps/x86_64/strlen.S                       |  12 +-
 sysdeps/x86_64/x32/Makefile                   |  11 ++
 sysdeps/x86_64/x32/test-size_t.h              | 170 ++++++++++++++++++
 sysdeps/x86_64/x32/tst-size_t-memchr.c        |  72 ++++++++
 sysdeps/x86_64/x32/tst-size_t-memcmp.c        |  76 ++++++++
 sysdeps/x86_64/x32/tst-size_t-memcpy.c        |  58 ++++++
 sysdeps/x86_64/x32/tst-size_t-memrchr.c       |  57 ++++++
 sysdeps/x86_64/x32/tst-size_t-memset.c        |  73 ++++++++
 sysdeps/x86_64/x32/tst-size_t-strncasecmp.c   |  59 ++++++
 sysdeps/x86_64/x32/tst-size_t-strncmp.c       |  78 ++++++++
 sysdeps/x86_64/x32/tst-size_t-strncpy.c       |  58 ++++++
 sysdeps/x86_64/x32/tst-size_t-strnlen.c       |  72 ++++++++
 sysdeps/x86_64/x32/tst-size_t-wcsncmp.c       |  20 +++
 sysdeps/x86_64/x32/tst-size_t-wcsnlen.c       |  20 +++
 sysdeps/x86_64/x32/tst-size_t-wmemchr.c       |  20 +++
 sysdeps/x86_64/x32/tst-size_t-wmemcmp.c       |  20 +++
 sysdeps/x86_64/x32/tst-size_t-wmemset.c       |  20 +++
 37 files changed, 1034 insertions(+), 96 deletions(-)
 create mode 100644 sysdeps/x86_64/x32/test-size_t.h
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-memchr.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-memcmp.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-memcpy.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-memrchr.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-memset.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-strncasecmp.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-strncmp.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-strncpy.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-strnlen.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-wcsncmp.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-wcsnlen.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-wmemchr.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-wmemcmp.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-wmemset.c

-- 
2.20.1


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

* Re: [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097]
  2019-01-17 16:53 [PATCH 0/8] x86-64: " H.J. Lu
@ 2019-01-18 10:50 ` Florian Weimer
  2019-01-18 13:14   ` H.J. Lu
  0 siblings, 1 reply; 25+ messages in thread
From: Florian Weimer @ 2019-01-18 10:50 UTC (permalink / raw)
  To: H.J. Lu; +Cc: libc-alpha

* H. J. Lu:

> On x32, the size_t parameter may be passed in the lower 32 bits of a
> 64-bit register with the non-zero upper 32 bits.  The string/memory
> functions written in assembly can only use the lower 32 bits of a
> 64-bit register as length or must clear the upper 32 bits before using
> the full 64-bit register for length.
>
> This pach fixes string/memory functions written in assembly for x32.
> Tested on x86-64 and x32.  On x86-64, libc.so is the same with and
> withou the fix.

Can this bug result in buffer overflows?  Should we obtain a CVE
identifier?

Thanks,
Florian

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

* Re: [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097]
  2019-01-18 10:50 ` Florian Weimer
@ 2019-01-18 13:14   ` H.J. Lu
  2019-01-18 13:31     ` Florian Weimer
  2019-01-18 19:56     ` Florian Weimer
  0 siblings, 2 replies; 25+ messages in thread
From: H.J. Lu @ 2019-01-18 13:14 UTC (permalink / raw)
  To: Florian Weimer; +Cc: GNU C Library

On Fri, Jan 18, 2019 at 2:50 AM Florian Weimer <fweimer@redhat.com> wrote:
>
> * H. J. Lu:
>
> > On x32, the size_t parameter may be passed in the lower 32 bits of a
> > 64-bit register with the non-zero upper 32 bits.  The string/memory
> > functions written in assembly can only use the lower 32 bits of a
> > 64-bit register as length or must clear the upper 32 bits before using
> > the full 64-bit register for length.
> >
> > This pach fixes string/memory functions written in assembly for x32.
> > Tested on x86-64 and x32.  On x86-64, libc.so is the same with and
> > withou the fix.
>
> Can this bug result in buffer overflows?  Should we obtain a CVE

Yes, definitely.

> identifier?
>

Yes, please.  Can you do that for me?

Thanks.

-- 
H.J.

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

* Re: [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097]
  2019-01-18 13:14   ` H.J. Lu
@ 2019-01-18 13:31     ` Florian Weimer
  2019-01-18 13:32       ` H.J. Lu
  2019-01-18 19:56     ` Florian Weimer
  1 sibling, 1 reply; 25+ messages in thread
From: Florian Weimer @ 2019-01-18 13:31 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GNU C Library

* H. J. Lu:

> On Fri, Jan 18, 2019 at 2:50 AM Florian Weimer <fweimer@redhat.com> wrote:
>>
>> * H. J. Lu:
>>
>> > On x32, the size_t parameter may be passed in the lower 32 bits of a
>> > 64-bit register with the non-zero upper 32 bits.  The string/memory
>> > functions written in assembly can only use the lower 32 bits of a
>> > 64-bit register as length or must clear the upper 32 bits before using
>> > the full 64-bit register for length.
>> >
>> > This pach fixes string/memory functions written in assembly for x32.
>> > Tested on x86-64 and x32.  On x86-64, libc.so is the same with and
>> > withou the fix.
>>
>> Can this bug result in buffer overflows?  Should we obtain a CVE
>
> Yes, definitely.

Yuck.

>> identifier?
>>
>
> Yes, please.  Can you do that for me?

Working on it.

The issue existed since the port was introduced, correct?

Thanks,
Florian

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

* Re: [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097]
  2019-01-18 13:31     ` Florian Weimer
@ 2019-01-18 13:32       ` H.J. Lu
  0 siblings, 0 replies; 25+ messages in thread
From: H.J. Lu @ 2019-01-18 13:32 UTC (permalink / raw)
  To: Florian Weimer; +Cc: GNU C Library

On Fri, Jan 18, 2019 at 5:31 AM Florian Weimer <fweimer@redhat.com> wrote:
>
> * H. J. Lu:
>
> > On Fri, Jan 18, 2019 at 2:50 AM Florian Weimer <fweimer@redhat.com> wrote:
> >>
> >> * H. J. Lu:
> >>
> >> > On x32, the size_t parameter may be passed in the lower 32 bits of a
> >> > 64-bit register with the non-zero upper 32 bits.  The string/memory
> >> > functions written in assembly can only use the lower 32 bits of a
> >> > 64-bit register as length or must clear the upper 32 bits before using
> >> > the full 64-bit register for length.
> >> >
> >> > This pach fixes string/memory functions written in assembly for x32.
> >> > Tested on x86-64 and x32.  On x86-64, libc.so is the same with and
> >> > withou the fix.
> >>
> >> Can this bug result in buffer overflows?  Should we obtain a CVE
> >
> > Yes, definitely.
>
> Yuck.
>
> >> identifier?
> >>
> >
> > Yes, please.  Can you do that for me?
>
> Working on it.
>
> The issue existed since the port was introduced, correct?
>

Yes.

-- 
H.J.

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

* Re: [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097]
  2019-01-18 13:14   ` H.J. Lu
  2019-01-18 13:31     ` Florian Weimer
@ 2019-01-18 19:56     ` Florian Weimer
  2019-01-18 20:15       ` H.J. Lu
  2019-01-18 20:15       ` Florian Weimer
  1 sibling, 2 replies; 25+ messages in thread
From: Florian Weimer @ 2019-01-18 19:56 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GNU C Library

* H. J. Lu:

> On Fri, Jan 18, 2019 at 2:50 AM Florian Weimer <fweimer@redhat.com> wrote:
>>
>> * H. J. Lu:
>>
>> > On x32, the size_t parameter may be passed in the lower 32 bits of a
>> > 64-bit register with the non-zero upper 32 bits.  The string/memory
>> > functions written in assembly can only use the lower 32 bits of a
>> > 64-bit register as length or must clear the upper 32 bits before using
>> > the full 64-bit register for length.
>> >
>> > This pach fixes string/memory functions written in assembly for x32.
>> > Tested on x86-64 and x32.  On x86-64, libc.so is the same with and
>> > withou the fix.
>>
>> Can this bug result in buffer overflows?  Should we obtain a CVE
>
> Yes, definitely.
>
>> identifier?
>>
>
> Yes, please.  Can you do that for me?

Done, MITRE gave us CVE-2019-6488.  Please reference this in the
ChangeLog and the commit message if you have not done so.  Please also
add short NEWS entry in the security section.  Thanks.

Florian

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

* [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097]
@ 2019-01-18 20:12 H.J. Lu
  2019-01-18 20:12 ` [PATCH 1/8] x86-64 memchr/wmemchr: " H.J. Lu
                   ` (7 more replies)
  0 siblings, 8 replies; 25+ messages in thread
From: H.J. Lu @ 2019-01-18 20:12 UTC (permalink / raw)
  To: libc-alpha

On x32, the size_t parameter may be passed in the lower 32 bits of a
64-bit register with the non-zero upper 32 bits.  The string/memory
functions written in assembly can only use the lower 32 bits of a
64-bit register as length or must clear the upper 32 bits before using
the full 64-bit register for length.

This pach fixes string/memory functions written in assembly for x32.
Tested on x86-64 and x32.  On x86-64, libc.so is the same with and
withou the fix.

This fixes CVE-2019-6488.

H.J. Lu (8):
  x86-64 memchr/wmemchr: Properly handle the length parameter [BZ#
    24097]
  x86-64 memcmp/wmemcmp: Properly handle the length parameter [BZ#
    24097]
  x86-64 memcpy: Properly handle the length parameter [BZ# 24097]
  x86-64 memrchr: Properly handle the length parameter [BZ# 24097]
  x86-64 memset/wmemset: Properly handle the length parameter [BZ#
    24097]
  x86-64 strncmp family: Properly handle the length parameter [BZ#
    24097]
  x86-64 strncpy: Properly handle the length parameter [BZ# 24097]
  x86-64 strnlen/wcsnlen: Properly handle the length parameter [BZ#
    24097]

 NEWS                                          |  6 ++
 sysdeps/x86_64/memchr.S                       | 10 ++-
 sysdeps/x86_64/memrchr.S                      |  4 +-
 sysdeps/x86_64/multiarch/memchr-avx2.S        |  8 +-
 sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S  |  7 +-
 sysdeps/x86_64/multiarch/memcmp-sse4.S        |  9 ++-
 sysdeps/x86_64/multiarch/memcmp-ssse3.S       |  7 +-
 sysdeps/x86_64/multiarch/memcpy-ssse3-back.S  | 17 ++--
 sysdeps/x86_64/multiarch/memcpy-ssse3.S       | 17 ++--
 .../multiarch/memmove-avx512-no-vzeroupper.S  | 16 ++--
 .../multiarch/memmove-vec-unaligned-erms.S    | 54 +++++++------
 sysdeps/x86_64/multiarch/memrchr-avx2.S       |  4 +-
 .../multiarch/memset-avx512-no-vzeroupper.S   |  6 +-
 .../multiarch/memset-vec-unaligned-erms.S     | 34 ++++----
 sysdeps/x86_64/multiarch/strcmp-avx2.S        |  6 +-
 sysdeps/x86_64/multiarch/strcmp-sse42.S       |  6 +-
 sysdeps/x86_64/multiarch/strcpy-avx2.S        |  4 +-
 .../x86_64/multiarch/strcpy-sse2-unaligned.S  |  4 +-
 sysdeps/x86_64/multiarch/strcpy-ssse3.S       |  6 +-
 sysdeps/x86_64/multiarch/strlen-avx2.S        |  9 ++-
 sysdeps/x86_64/strcmp.S                       |  6 +-
 sysdeps/x86_64/strlen.S                       | 12 +--
 sysdeps/x86_64/x32/Makefile                   | 11 +++
 sysdeps/x86_64/x32/test-size_t.h              | 35 +++++++++
 sysdeps/x86_64/x32/tst-size_t-memchr.c        | 72 +++++++++++++++++
 sysdeps/x86_64/x32/tst-size_t-memcmp.c        | 76 ++++++++++++++++++
 sysdeps/x86_64/x32/tst-size_t-memcpy.c        | 58 ++++++++++++++
 sysdeps/x86_64/x32/tst-size_t-memrchr.c       | 57 ++++++++++++++
 sysdeps/x86_64/x32/tst-size_t-memset.c        | 73 +++++++++++++++++
 sysdeps/x86_64/x32/tst-size_t-strncasecmp.c   | 59 ++++++++++++++
 sysdeps/x86_64/x32/tst-size_t-strncmp.c       | 78 +++++++++++++++++++
 sysdeps/x86_64/x32/tst-size_t-strncpy.c       | 58 ++++++++++++++
 sysdeps/x86_64/x32/tst-size_t-strnlen.c       | 72 +++++++++++++++++
 sysdeps/x86_64/x32/tst-size_t-wcsncmp.c       | 20 +++++
 sysdeps/x86_64/x32/tst-size_t-wcsnlen.c       | 20 +++++
 sysdeps/x86_64/x32/tst-size_t-wmemchr.c       | 20 +++++
 sysdeps/x86_64/x32/tst-size_t-wmemcmp.c       | 20 +++++
 sysdeps/x86_64/x32/tst-size_t-wmemset.c       | 20 +++++
 38 files changed, 905 insertions(+), 96 deletions(-)
 create mode 100644 sysdeps/x86_64/x32/test-size_t.h
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-memchr.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-memcmp.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-memcpy.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-memrchr.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-memset.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-strncasecmp.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-strncmp.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-strncpy.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-strnlen.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-wcsncmp.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-wcsnlen.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-wmemchr.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-wmemcmp.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-wmemset.c

-- 
2.20.1


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

* [PATCH 1/8] x86-64 memchr/wmemchr: Properly handle the length parameter [BZ# 24097]
  2019-01-18 20:12 [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097] H.J. Lu
@ 2019-01-18 20:12 ` H.J. Lu
  2019-01-18 20:12 ` [PATCH 2/8] x86-64 memcmp/wmemcmp: " H.J. Lu
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 25+ messages in thread
From: H.J. Lu @ 2019-01-18 20:12 UTC (permalink / raw)
  To: libc-alpha

On x32, the size_t parameter may be passed in the lower 32 bits of a
64-bit register with the non-zero upper 32 bits.  The string/memory
functions written in assembly can only use the lower 32 bits of a
64-bit register as length or must clear the upper 32 bits before using
the full 64-bit register for length.

This pach fixes memchr/wmemchr for x32.  Tested on x86-64 and x32.  On
x86-64, libc.so is the same with and withou the fix.

	[BZ# 24097]
	CVE-2019-6488
	* sysdeps/x86_64/memchr.S: Use RDX_LP for length.  Clear the
	upper 32 bits of RDX register.
	* sysdeps/x86_64/multiarch/memchr-avx2.S: Likewise.
	* sysdeps/x86_64/x32/Makefile (tests): Add tst-size_t-memchr and
	tst-size_t-wmemchr.
	* sysdeps/x86_64/x32/test-size_t.h: New file.
	* sysdeps/x86_64/x32/tst-size_t-memchr.c: Likewise.
	* sysdeps/x86_64/x32/tst-size_t-wmemchr.c: Likewise.
---
 NEWS                                    |  6 +++
 sysdeps/x86_64/memchr.S                 | 10 ++--
 sysdeps/x86_64/multiarch/memchr-avx2.S  |  8 ++-
 sysdeps/x86_64/x32/Makefile             |  8 +++
 sysdeps/x86_64/x32/test-size_t.h        | 35 ++++++++++++
 sysdeps/x86_64/x32/tst-size_t-memchr.c  | 72 +++++++++++++++++++++++++
 sysdeps/x86_64/x32/tst-size_t-wmemchr.c | 20 +++++++
 7 files changed, 154 insertions(+), 5 deletions(-)
 create mode 100644 sysdeps/x86_64/x32/test-size_t.h
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-memchr.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-wmemchr.c

diff --git a/NEWS b/NEWS
index cc20102fda..2885c42aa5 100644
--- a/NEWS
+++ b/NEWS
@@ -101,6 +101,12 @@ Security related changes:
   denial of service due to resource exhaustion when processing getaddrinfo
   calls with crafted host names.  Reported by Guido Vranken.
 
+  CVE-2019-6488: On x32, the size_t parameter may be passed in the lower
+  32 bits of a 64-bit register with the non-zero upper 32 bits.  When
+  it happens, the string/memory functions written in assembly will cause
+  buffer overflow if the full 64-bit register is used as the 32-bit
+  size_t value.  Reported by Florian Weimer.
+
 The following bugs are resolved with this release:
 
   [The release manager will add the list generated by
diff --git a/sysdeps/x86_64/memchr.S b/sysdeps/x86_64/memchr.S
index a6f3ebba22..ec96365217 100644
--- a/sysdeps/x86_64/memchr.S
+++ b/sysdeps/x86_64/memchr.S
@@ -34,12 +34,16 @@ ENTRY(MEMCHR)
 	mov	%edi, %ecx
 
 #ifdef USE_AS_WMEMCHR
-	test	%rdx, %rdx
+	test	%RDX_LP, %RDX_LP
 	jz	L(return_null)
-	shl	$2, %rdx
+	shl	$2, %RDX_LP
 #else
+# ifdef __ILP32__
+	/* Clear the upper 32 bits.  */
+	movl	%edx, %edx
+# endif
 	punpcklbw %xmm1, %xmm1
-	test	%rdx, %rdx
+	test	%RDX_LP, %RDX_LP
 	jz	L(return_null)
 	punpcklbw %xmm1, %xmm1
 #endif
diff --git a/sysdeps/x86_64/multiarch/memchr-avx2.S b/sysdeps/x86_64/multiarch/memchr-avx2.S
index 9f98b7ec60..cfec1657b6 100644
--- a/sysdeps/x86_64/multiarch/memchr-avx2.S
+++ b/sysdeps/x86_64/multiarch/memchr-avx2.S
@@ -40,16 +40,20 @@
 ENTRY (MEMCHR)
 # ifndef USE_AS_RAWMEMCHR
 	/* Check for zero length.  */
-	testq	%rdx, %rdx
+	test	%RDX_LP, %RDX_LP
 	jz	L(null)
 # endif
 	movl	%edi, %ecx
 	/* Broadcast CHAR to YMM0.  */
 	vmovd	%esi, %xmm0
 # ifdef USE_AS_WMEMCHR
-	shl	$2, %rdx
+	shl	$2, %RDX_LP
 	vpbroadcastd %xmm0, %ymm0
 # else
+#  ifdef __ILP32__
+	/* Clear the upper 32 bits.  */
+	movl	%edx, %edx
+#  endif
 	vpbroadcastb %xmm0, %ymm0
 # endif
 	/* Check if we may cross page boundary with one vector load.  */
diff --git a/sysdeps/x86_64/x32/Makefile b/sysdeps/x86_64/x32/Makefile
index f2ebc24fb0..7d528889c6 100644
--- a/sysdeps/x86_64/x32/Makefile
+++ b/sysdeps/x86_64/x32/Makefile
@@ -4,3 +4,11 @@ ifeq ($(subdir),math)
 # 64-bit llround.  Add -fno-builtin-lround to silence the compiler.
 CFLAGS-s_llround.c += -fno-builtin-lround
 endif
+
+ifeq ($(subdir),string)
+tests += tst-size_t-memchr
+endif
+
+ifeq ($(subdir),wcsmbs)
+tests += tst-size_t-wmemchr
+endif
diff --git a/sysdeps/x86_64/x32/test-size_t.h b/sysdeps/x86_64/x32/test-size_t.h
new file mode 100644
index 0000000000..78a940863e
--- /dev/null
+++ b/sysdeps/x86_64/x32/test-size_t.h
@@ -0,0 +1,35 @@
+/* Test string/memory functions with size_t in the lower 32 bits of
+   64-bit register.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_MAIN
+#include <string/test-string.h>
+
+/* On x32, parameter_t may be passed in a 64-bit register with the LEN
+   field in the lower 32 bits.  When the LEN field of 64-bit register
+   is passed to string/memory function as the size_t parameter, only
+   the lower 32 bits can be used.  */
+typedef struct
+{
+  union
+    {
+      size_t len;
+      void (*fn) (void);
+    };
+  void *p;
+} parameter_t;
diff --git a/sysdeps/x86_64/x32/tst-size_t-memchr.c b/sysdeps/x86_64/x32/tst-size_t-memchr.c
new file mode 100644
index 0000000000..29a3daf102
--- /dev/null
+++ b/sysdeps/x86_64/x32/tst-size_t-memchr.c
@@ -0,0 +1,72 @@
+/* Test memchr with size_t in the lower 32 bits of 64-bit register.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef WIDE
+# define TEST_NAME "memchr"
+#else
+# define TEST_NAME "wmemchr"
+#endif /* WIDE */
+#include "test-size_t.h"
+
+#ifndef WIDE
+# define MEMCHR memchr
+# define CHAR char
+# define UCHAR unsigned char
+#else
+# include <wchar.h>
+# define MEMCHR wmemchr
+# define CHAR wchar_t
+# define UCHAR wchar_t
+#endif /* WIDE */
+
+IMPL (MEMCHR, 1)
+
+typedef CHAR * (*proto_t) (const CHAR*, int, size_t);
+
+static CHAR *
+__attribute__ ((noinline, noclone))
+do_memchr (parameter_t a, parameter_t b)
+{
+  return CALL (&b, a.p, (uintptr_t) b.p, a.len);
+}
+
+static int
+test_main (void)
+{
+  test_init ();
+
+  parameter_t src = { { page_size / sizeof (CHAR) }, buf2 };
+  parameter_t c = { { 0 }, (void *) (uintptr_t) 0x12 };
+
+  int ret = 0;
+  FOR_EACH_IMPL (impl, 0)
+    {
+      c.fn = impl->fn;
+      CHAR *res = do_memchr (src, c);
+      if (res)
+	{
+	  error (0, 0, "Wrong result in function %s: %p != NULL",
+		 impl->name, res);
+	  ret = 1;
+	}
+    }
+
+  return ret ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/x86_64/x32/tst-size_t-wmemchr.c b/sysdeps/x86_64/x32/tst-size_t-wmemchr.c
new file mode 100644
index 0000000000..877801d646
--- /dev/null
+++ b/sysdeps/x86_64/x32/tst-size_t-wmemchr.c
@@ -0,0 +1,20 @@
+/* Test wmemchr with size_t in the lower 32 bits of 64-bit register.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define WIDE 1
+#include "tst-size_t-memchr.c"
-- 
2.20.1


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

* [PATCH 2/8] x86-64 memcmp/wmemcmp: Properly handle the length parameter [BZ# 24097]
  2019-01-18 20:12 [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097] H.J. Lu
  2019-01-18 20:12 ` [PATCH 1/8] x86-64 memchr/wmemchr: " H.J. Lu
@ 2019-01-18 20:12 ` H.J. Lu
  2019-01-18 20:12 ` [PATCH 3/8] x86-64 memcpy: " H.J. Lu
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 25+ messages in thread
From: H.J. Lu @ 2019-01-18 20:12 UTC (permalink / raw)
  To: libc-alpha

On x32, the size_t parameter may be passed in the lower 32 bits of a
64-bit register with the non-zero upper 32 bits.  The string/memory
functions written in assembly can only use the lower 32 bits of a
64-bit register as length or must clear the upper 32 bits before using
the full 64-bit register for length.

This pach fixes memcmp/wmemcmp for x32.  Tested on x86-64 and x32.  On
x86-64, libc.so is the same with and withou the fix.

	[BZ# 24097]
	CVE-2019-6488
	* sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S: Use RDX_LP for
	length.  Clear the upper 32 bits of RDX register.
	* sysdeps/x86_64/multiarch/memcmp-sse4.S: Likewise.
	* sysdeps/x86_64/multiarch/memcmp-ssse3.S: Likewise.
	* sysdeps/x86_64/x32/Makefile (tests): Add tst-size_t-memcmp and
	tst-size_t-wmemcmp.
	* sysdeps/x86_64/x32/tst-size_t-memcmp.c: New file.
	* sysdeps/x86_64/x32/tst-size_t-wmemcmp.c: Likewise.
---
 sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S |  7 +-
 sysdeps/x86_64/multiarch/memcmp-sse4.S       |  9 ++-
 sysdeps/x86_64/multiarch/memcmp-ssse3.S      |  7 +-
 sysdeps/x86_64/x32/Makefile                  |  4 +-
 sysdeps/x86_64/x32/tst-size_t-memcmp.c       | 76 ++++++++++++++++++++
 sysdeps/x86_64/x32/tst-size_t-wmemcmp.c      | 20 ++++++
 6 files changed, 114 insertions(+), 9 deletions(-)
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-memcmp.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-wmemcmp.c

diff --git a/sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S b/sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S
index a16199a087..d779639a61 100644
--- a/sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S
+++ b/sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S
@@ -58,9 +58,12 @@
 	.section .text.avx,"ax",@progbits
 ENTRY (MEMCMP)
 # ifdef USE_AS_WMEMCMP
-	shl	$2, %rdx
+	shl	$2, %RDX_LP
+# elif defined __ILP32__
+	/* Clear the upper 32 bits.  */
+	movl	%edx, %edx
 # endif
-	cmpq	$VEC_SIZE, %rdx
+	cmp	$VEC_SIZE, %RDX_LP
 	jb	L(less_vec)
 
 	/* From VEC to 2 * VEC.  No branch when size == VEC_SIZE.  */
diff --git a/sysdeps/x86_64/multiarch/memcmp-sse4.S b/sysdeps/x86_64/multiarch/memcmp-sse4.S
index 789ff15e2c..c8f67318a4 100644
--- a/sysdeps/x86_64/multiarch/memcmp-sse4.S
+++ b/sysdeps/x86_64/multiarch/memcmp-sse4.S
@@ -42,13 +42,16 @@
 	.section .text.sse4.1,"ax",@progbits
 ENTRY (MEMCMP)
 # ifdef USE_AS_WMEMCMP
-	shl	$2, %rdx
+	shl	$2, %RDX_LP
+# elif defined __ILP32__
+	/* Clear the upper 32 bits.  */
+	mov	%edx, %edx
 # endif
 	pxor	%xmm0, %xmm0
-	cmp	$79, %rdx
+	cmp	$79, %RDX_LP
 	ja	L(79bytesormore)
 # ifndef USE_AS_WMEMCMP
-	cmp	$1, %rdx
+	cmp	$1, %RDX_LP
 	je	L(firstbyte)
 # endif
 	add	%rdx, %rsi
diff --git a/sysdeps/x86_64/multiarch/memcmp-ssse3.S b/sysdeps/x86_64/multiarch/memcmp-ssse3.S
index 0008b05602..c77d1fd0dc 100644
--- a/sysdeps/x86_64/multiarch/memcmp-ssse3.S
+++ b/sysdeps/x86_64/multiarch/memcmp-ssse3.S
@@ -33,9 +33,12 @@
 	atom_text_section
 ENTRY (MEMCMP)
 # ifdef USE_AS_WMEMCMP
-	shl	$2, %rdx
-	test	%rdx, %rdx
+	shl	$2, %RDX_LP
+	test	%RDX_LP, %RDX_LP
 	jz	L(equal)
+# elif defined __ILP32__
+	/* Clear the upper 32 bits.  */
+	mov	%edx, %edx
 # endif
 	mov	%rdx, %rcx
 	mov	%rdi, %rdx
diff --git a/sysdeps/x86_64/x32/Makefile b/sysdeps/x86_64/x32/Makefile
index 7d528889c6..ddec7f0466 100644
--- a/sysdeps/x86_64/x32/Makefile
+++ b/sysdeps/x86_64/x32/Makefile
@@ -6,9 +6,9 @@ CFLAGS-s_llround.c += -fno-builtin-lround
 endif
 
 ifeq ($(subdir),string)
-tests += tst-size_t-memchr
+tests += tst-size_t-memchr tst-size_t-memcmp
 endif
 
 ifeq ($(subdir),wcsmbs)
-tests += tst-size_t-wmemchr
+tests += tst-size_t-wmemchr tst-size_t-wmemcmp
 endif
diff --git a/sysdeps/x86_64/x32/tst-size_t-memcmp.c b/sysdeps/x86_64/x32/tst-size_t-memcmp.c
new file mode 100644
index 0000000000..9bd6fdb45a
--- /dev/null
+++ b/sysdeps/x86_64/x32/tst-size_t-memcmp.c
@@ -0,0 +1,76 @@
+/* Test memcmp with size_t in the lower 32 bits of 64-bit register.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_MAIN
+#ifdef WIDE
+# define TEST_NAME "wmemcmp"
+#else
+# define TEST_NAME "memcmp"
+#endif
+
+#include "test-size_t.h"
+
+#ifdef WIDE
+# include <inttypes.h>
+# include <wchar.h>
+
+# define MEMCMP wmemcmp
+# define CHAR wchar_t
+#else
+# define MEMCMP memcmp
+# define CHAR char
+#endif
+
+IMPL (MEMCMP, 1)
+
+typedef int (*proto_t) (const CHAR *, const CHAR *, size_t);
+
+static int
+__attribute__ ((noinline, noclone))
+do_memcmp (parameter_t a, parameter_t b)
+{
+  return CALL (&b, a.p, b.p, a.len);
+}
+
+static int
+test_main (void)
+{
+  test_init ();
+
+  parameter_t dest = { { page_size / sizeof (CHAR) }, buf1 };
+  parameter_t src = { { 0 }, buf2 };
+
+  memcpy (buf1, buf2, page_size);
+
+  int ret = 0;
+  FOR_EACH_IMPL (impl, 0)
+    {
+      src.fn = impl->fn;
+      int res = do_memcmp (dest, src);
+      if (res)
+	{
+	  error (0, 0, "Wrong result in function %s: %i != 0",
+		 impl->name, res);
+	  ret = 1;
+	}
+    }
+
+  return ret ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/x86_64/x32/tst-size_t-wmemcmp.c b/sysdeps/x86_64/x32/tst-size_t-wmemcmp.c
new file mode 100644
index 0000000000..e8b5ffd0d5
--- /dev/null
+++ b/sysdeps/x86_64/x32/tst-size_t-wmemcmp.c
@@ -0,0 +1,20 @@
+/* Test wmemcmp with size_t in the lower 32 bits of 64-bit register.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define WIDE 1
+#include "tst-size_t-memcmp.c"
-- 
2.20.1


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

* [PATCH 3/8] x86-64 memcpy: Properly handle the length parameter [BZ# 24097]
  2019-01-18 20:12 [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097] H.J. Lu
  2019-01-18 20:12 ` [PATCH 1/8] x86-64 memchr/wmemchr: " H.J. Lu
  2019-01-18 20:12 ` [PATCH 2/8] x86-64 memcmp/wmemcmp: " H.J. Lu
@ 2019-01-18 20:12 ` H.J. Lu
  2019-01-18 20:12 ` [PATCH 4/8] x86-64 memrchr: " H.J. Lu
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 25+ messages in thread
From: H.J. Lu @ 2019-01-18 20:12 UTC (permalink / raw)
  To: libc-alpha

On x32, the size_t parameter may be passed in the lower 32 bits of a
64-bit register with the non-zero upper 32 bits.  The string/memory
functions written in assembly can only use the lower 32 bits of a
64-bit register as length or must clear the upper 32 bits before using
the full 64-bit register for length.

This pach fixes memcpy for x32.  Tested on x86-64 and x32.  On x86-64,
libc.so is the same with and withou the fix.

	[BZ# 24097]
	CVE-2019-6488
	* sysdeps/x86_64/multiarch/memcpy-ssse3-back.S: Use RDX_LP for
	length.  Clear the upper 32 bits of RDX register.
	* sysdeps/x86_64/multiarch/memcpy-ssse3.S: Likewise.
	* sysdeps/x86_64/multiarch/memmove-avx512-no-vzeroupper.S:
	Likewise.
	* sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:
	Likewise.
	* sysdeps/x86_64/x32/Makefile (tests): Add tst-size_t-memcpy.
	tst-size_t-wmemchr.
	* sysdeps/x86_64/x32/tst-size_t-memcpy.c: New file.
---
 sysdeps/x86_64/multiarch/memcpy-ssse3-back.S  | 17 ++++--
 sysdeps/x86_64/multiarch/memcpy-ssse3.S       | 17 ++++--
 .../multiarch/memmove-avx512-no-vzeroupper.S  | 16 +++--
 .../multiarch/memmove-vec-unaligned-erms.S    | 54 +++++++++--------
 sysdeps/x86_64/x32/Makefile                   |  2 +-
 sysdeps/x86_64/x32/tst-size_t-memcpy.c        | 58 +++++++++++++++++++
 6 files changed, 122 insertions(+), 42 deletions(-)
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-memcpy.c

diff --git a/sysdeps/x86_64/multiarch/memcpy-ssse3-back.S b/sysdeps/x86_64/multiarch/memcpy-ssse3-back.S
index bcfb21e75a..b9188cbcfb 100644
--- a/sysdeps/x86_64/multiarch/memcpy-ssse3-back.S
+++ b/sysdeps/x86_64/multiarch/memcpy-ssse3-back.S
@@ -45,28 +45,33 @@
 	.section .text.ssse3,"ax",@progbits
 #if !defined USE_AS_MEMPCPY && !defined USE_AS_MEMMOVE
 ENTRY (MEMPCPY_CHK)
-	cmpq	%rdx, %rcx
+	cmp	%RDX_LP, %RCX_LP
 	jb	HIDDEN_JUMPTARGET (__chk_fail)
 END (MEMPCPY_CHK)
 
 ENTRY (MEMPCPY)
-	movq	%rdi, %rax
-	addq	%rdx, %rax
+	mov	%RDI_LP, %RAX_LP
+	add	%RDX_LP, %RAX_LP
 	jmp	L(start)
 END (MEMPCPY)
 #endif
 
 #if !defined USE_AS_BCOPY
 ENTRY (MEMCPY_CHK)
-	cmpq	%rdx, %rcx
+	cmp	%RDX_LP, %RCX_LP
 	jb	HIDDEN_JUMPTARGET (__chk_fail)
 END (MEMCPY_CHK)
 #endif
 
 ENTRY (MEMCPY)
-	mov	%rdi, %rax
+	mov	%RDI_LP, %RAX_LP
 #ifdef USE_AS_MEMPCPY
-	add	%rdx, %rax
+	add	%RDX_LP, %RAX_LP
+#endif
+
+#ifdef __ILP32__
+	/* Clear the upper 32 bits.  */
+	mov	%edx, %edx
 #endif
 
 #ifdef USE_AS_MEMMOVE
diff --git a/sysdeps/x86_64/multiarch/memcpy-ssse3.S b/sysdeps/x86_64/multiarch/memcpy-ssse3.S
index 7d74dbd2f5..8f68315418 100644
--- a/sysdeps/x86_64/multiarch/memcpy-ssse3.S
+++ b/sysdeps/x86_64/multiarch/memcpy-ssse3.S
@@ -45,28 +45,33 @@
 	.section .text.ssse3,"ax",@progbits
 #if !defined USE_AS_MEMPCPY && !defined USE_AS_MEMMOVE
 ENTRY (MEMPCPY_CHK)
-	cmpq	%rdx, %rcx
+	cmp	%RDX_LP, %RCX_LP
 	jb	HIDDEN_JUMPTARGET (__chk_fail)
 END (MEMPCPY_CHK)
 
 ENTRY (MEMPCPY)
-	movq	%rdi, %rax
-	addq	%rdx, %rax
+	mov	%RDI_LP, %RAX_LP
+	add	%RDX_LP, %RAX_LP
 	jmp	L(start)
 END (MEMPCPY)
 #endif
 
 #if !defined USE_AS_BCOPY
 ENTRY (MEMCPY_CHK)
-	cmpq	%rdx, %rcx
+	cmp	%RDX_LP, %RCX_LP
 	jb	HIDDEN_JUMPTARGET (__chk_fail)
 END (MEMCPY_CHK)
 #endif
 
 ENTRY (MEMCPY)
-	mov	%rdi, %rax
+	mov	%RDI_LP, %RAX_LP
 #ifdef USE_AS_MEMPCPY
-	add	%rdx, %rax
+	add	%RDX_LP, %RAX_LP
+#endif
+
+#ifdef __ILP32__
+	/* Clear the upper 32 bits.  */
+	mov	%edx, %edx
 #endif
 
 #ifdef USE_AS_MEMMOVE
diff --git a/sysdeps/x86_64/multiarch/memmove-avx512-no-vzeroupper.S b/sysdeps/x86_64/multiarch/memmove-avx512-no-vzeroupper.S
index b39324df0a..27df2baab5 100644
--- a/sysdeps/x86_64/multiarch/memmove-avx512-no-vzeroupper.S
+++ b/sysdeps/x86_64/multiarch/memmove-avx512-no-vzeroupper.S
@@ -24,27 +24,31 @@
 
 	.section .text.avx512,"ax",@progbits
 ENTRY (__mempcpy_chk_avx512_no_vzeroupper)
-	cmpq	%rdx, %rcx
+	cmp	%RDX_LP, %RCX_LP
 	jb	HIDDEN_JUMPTARGET (__chk_fail)
 END (__mempcpy_chk_avx512_no_vzeroupper)
 
 ENTRY (__mempcpy_avx512_no_vzeroupper)
-	movq	%rdi, %rax
-	addq	%rdx, %rax
+	mov	%RDI_LP, %RAX_LP
+	add	%RDX_LP, %RAX_LP
 	jmp	L(start)
 END (__mempcpy_avx512_no_vzeroupper)
 
 ENTRY (__memmove_chk_avx512_no_vzeroupper)
-	cmpq	%rdx, %rcx
+	cmp	%RDX_LP, %RCX_LP
 	jb	HIDDEN_JUMPTARGET (__chk_fail)
 END (__memmove_chk_avx512_no_vzeroupper)
 
 ENTRY (__memmove_avx512_no_vzeroupper)
-	mov	%rdi, %rax
+	mov	%RDI_LP, %RAX_LP
 # ifdef USE_AS_MEMPCPY
-	add	%rdx, %rax
+	add	%RDX_LP, %RAX_LP
 # endif
 L(start):
+# ifdef __ILP32__
+	/* Clear the upper 32 bits.  */
+	mov	%edx, %edx
+# endif
 	lea	(%rsi, %rdx), %rcx
 	lea	(%rdi, %rdx), %r9
 	cmp	$512, %rdx
diff --git a/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S b/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S
index 6e4959f104..2e9d86bd33 100644
--- a/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S
+++ b/sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S
@@ -106,20 +106,20 @@
 	.section SECTION(.text),"ax",@progbits
 #if defined SHARED && IS_IN (libc)
 ENTRY (MEMMOVE_CHK_SYMBOL (__mempcpy_chk, unaligned))
-	cmpq	%rdx, %rcx
+	cmp	%RDX_LP, %RCX_LP
 	jb	HIDDEN_JUMPTARGET (__chk_fail)
 END (MEMMOVE_CHK_SYMBOL (__mempcpy_chk, unaligned))
 #endif
 
 ENTRY (MEMPCPY_SYMBOL (__mempcpy, unaligned))
-	movq	%rdi, %rax
-	addq	%rdx, %rax
+	mov	%RDI_LP, %RAX_LP
+	add	%RDX_LP, %RAX_LP
 	jmp	L(start)
 END (MEMPCPY_SYMBOL (__mempcpy, unaligned))
 
 #if defined SHARED && IS_IN (libc)
 ENTRY (MEMMOVE_CHK_SYMBOL (__memmove_chk, unaligned))
-	cmpq	%rdx, %rcx
+	cmp	%RDX_LP, %RCX_LP
 	jb	HIDDEN_JUMPTARGET (__chk_fail)
 END (MEMMOVE_CHK_SYMBOL (__memmove_chk, unaligned))
 #endif
@@ -127,9 +127,13 @@ END (MEMMOVE_CHK_SYMBOL (__memmove_chk, unaligned))
 ENTRY (MEMMOVE_SYMBOL (__memmove, unaligned))
 	movq	%rdi, %rax
 L(start):
-	cmpq	$VEC_SIZE, %rdx
+# ifdef __ILP32__
+	/* Clear the upper 32 bits.  */
+	movl	%edx, %edx
+# endif
+	cmp	$VEC_SIZE, %RDX_LP
 	jb	L(less_vec)
-	cmpq	$(VEC_SIZE * 2), %rdx
+	cmp	$(VEC_SIZE * 2), %RDX_LP
 	ja	L(more_2x_vec)
 #if !defined USE_MULTIARCH || !IS_IN (libc)
 L(last_2x_vec):
@@ -149,38 +153,38 @@ END (MEMMOVE_SYMBOL (__memmove, unaligned))
 
 # if VEC_SIZE == 16
 ENTRY (__mempcpy_chk_erms)
-	cmpq	%rdx, %rcx
+	cmp	%RDX_LP, %RCX_LP
 	jb	HIDDEN_JUMPTARGET (__chk_fail)
 END (__mempcpy_chk_erms)
 
 /* Only used to measure performance of REP MOVSB.  */
 ENTRY (__mempcpy_erms)
-	movq	%rdi, %rax
+	mov	%RDI_LP, %RAX_LP
 	/* Skip zero length.  */
-	testq	%rdx, %rdx
+	test	%RDX_LP, %RDX_LP
 	jz	2f
-	addq	%rdx, %rax
+	add	%RDX_LP, %RAX_LP
 	jmp	L(start_movsb)
 END (__mempcpy_erms)
 
 ENTRY (__memmove_chk_erms)
-	cmpq	%rdx, %rcx
+	cmp	%RDX_LP, %RCX_LP
 	jb	HIDDEN_JUMPTARGET (__chk_fail)
 END (__memmove_chk_erms)
 
 ENTRY (__memmove_erms)
 	movq	%rdi, %rax
 	/* Skip zero length.  */
-	testq	%rdx, %rdx
+	test	%RDX_LP, %RDX_LP
 	jz	2f
 L(start_movsb):
-	movq	%rdx, %rcx
-	cmpq	%rsi, %rdi
+	mov	%RDX_LP, %RCX_LP
+	cmp	%RSI_LP, %RDI_LP
 	jb	1f
 	/* Source == destination is less common.  */
 	je	2f
-	leaq	(%rsi,%rcx), %rdx
-	cmpq	%rdx, %rdi
+	lea	(%rsi,%rcx), %RDX_LP
+	cmp	%RDX_LP, %RDI_LP
 	jb	L(movsb_backward)
 1:
 	rep movsb
@@ -200,20 +204,20 @@ strong_alias (__memmove_chk_erms, __memcpy_chk_erms)
 
 # ifdef SHARED
 ENTRY (MEMMOVE_CHK_SYMBOL (__mempcpy_chk, unaligned_erms))
-	cmpq	%rdx, %rcx
+	cmp	%RDX_LP, %RCX_LP
 	jb	HIDDEN_JUMPTARGET (__chk_fail)
 END (MEMMOVE_CHK_SYMBOL (__mempcpy_chk, unaligned_erms))
 # endif
 
 ENTRY (MEMMOVE_SYMBOL (__mempcpy, unaligned_erms))
-	movq	%rdi, %rax
-	addq	%rdx, %rax
+	mov	%RDI_LP, %RAX_LP
+	add	%RDX_LP, %RAX_LP
 	jmp	L(start_erms)
 END (MEMMOVE_SYMBOL (__mempcpy, unaligned_erms))
 
 # ifdef SHARED
 ENTRY (MEMMOVE_CHK_SYMBOL (__memmove_chk, unaligned_erms))
-	cmpq	%rdx, %rcx
+	cmp	%RDX_LP, %RCX_LP
 	jb	HIDDEN_JUMPTARGET (__chk_fail)
 END (MEMMOVE_CHK_SYMBOL (__memmove_chk, unaligned_erms))
 # endif
@@ -221,9 +225,13 @@ END (MEMMOVE_CHK_SYMBOL (__memmove_chk, unaligned_erms))
 ENTRY (MEMMOVE_SYMBOL (__memmove, unaligned_erms))
 	movq	%rdi, %rax
 L(start_erms):
-	cmpq	$VEC_SIZE, %rdx
+# ifdef __ILP32__
+	/* Clear the upper 32 bits.  */
+	movl	%edx, %edx
+# endif
+	cmp	$VEC_SIZE, %RDX_LP
 	jb	L(less_vec)
-	cmpq	$(VEC_SIZE * 2), %rdx
+	cmp	$(VEC_SIZE * 2), %RDX_LP
 	ja	L(movsb_more_2x_vec)
 L(last_2x_vec):
 	/* From VEC and to 2 * VEC.  No branch when size == VEC_SIZE. */
@@ -250,7 +258,7 @@ L(movsb):
 # endif
 	jb	L(more_8x_vec_backward)
 1:
-	movq	%rdx, %rcx
+	mov	%RDX_LP, %RCX_LP
 	rep movsb
 L(nop):
 	ret
diff --git a/sysdeps/x86_64/x32/Makefile b/sysdeps/x86_64/x32/Makefile
index ddec7f0466..2fe1e5ac5a 100644
--- a/sysdeps/x86_64/x32/Makefile
+++ b/sysdeps/x86_64/x32/Makefile
@@ -6,7 +6,7 @@ CFLAGS-s_llround.c += -fno-builtin-lround
 endif
 
 ifeq ($(subdir),string)
-tests += tst-size_t-memchr tst-size_t-memcmp
+tests += tst-size_t-memchr tst-size_t-memcmp tst-size_t-memcpy
 endif
 
 ifeq ($(subdir),wcsmbs)
diff --git a/sysdeps/x86_64/x32/tst-size_t-memcpy.c b/sysdeps/x86_64/x32/tst-size_t-memcpy.c
new file mode 100644
index 0000000000..66b71e1749
--- /dev/null
+++ b/sysdeps/x86_64/x32/tst-size_t-memcpy.c
@@ -0,0 +1,58 @@
+/* Test memcpy with size_t in the lower 32 bits of 64-bit register.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_NAME "memcpy"
+#include "test-size_t.h"
+
+IMPL (memcpy, 1)
+
+typedef void *(*proto_t) (void *, const void *, size_t);
+
+static void *
+__attribute__ ((noinline, noclone))
+do_memcpy (parameter_t a, parameter_t b)
+{
+  return CALL (&b, a.p, b.p, a.len);
+}
+
+static int
+test_main (void)
+{
+  test_init ();
+
+  parameter_t dest = { { page_size }, buf1 };
+  parameter_t src = { { 0 }, buf2 };
+
+  int ret = 0;
+  FOR_EACH_IMPL (impl, 0)
+    {
+      src.fn = impl->fn;
+      do_memcpy (dest, src);
+      int res = memcmp (dest.p, src.p, dest.len);
+      if (res)
+	{
+	  error (0, 0, "Wrong result in function %s: %i != 0",
+		 impl->name, res);
+	  ret = 1;
+	}
+    }
+
+  return ret ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+#include <support/test-driver.c>
-- 
2.20.1


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

* [PATCH 4/8] x86-64 memrchr: Properly handle the length parameter [BZ# 24097]
  2019-01-18 20:12 [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097] H.J. Lu
                   ` (2 preceding siblings ...)
  2019-01-18 20:12 ` [PATCH 3/8] x86-64 memcpy: " H.J. Lu
@ 2019-01-18 20:12 ` H.J. Lu
  2019-01-18 20:12 ` [PATCH 5/8] x86-64 memset/wmemset: " H.J. Lu
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 25+ messages in thread
From: H.J. Lu @ 2019-01-18 20:12 UTC (permalink / raw)
  To: libc-alpha

On x32, the size_t parameter may be passed in the lower 32 bits of a
64-bit register with the non-zero upper 32 bits.  The string/memory
functions written in assembly can only use the lower 32 bits of a
64-bit register as length or must clear the upper 32 bits before using
the full 64-bit register for length.

This pach fixes memrchr for x32.  Tested on x86-64 and x32.  On x86-64,
libc.so is the same with and withou the fix.

	[BZ# 24097]
	CVE-2019-6488
	* sysdeps/x86_64/memrchr.S: Use RDX_LP for length.
	* sysdeps/x86_64/multiarch/memrchr-avx2.S: Likewise.
	* sysdeps/x86_64/x32/Makefile (tests): Add tst-size_t-memrchr.
	* sysdeps/x86_64/x32/tst-size_t-memrchr.c: New file.
---
 sysdeps/x86_64/memrchr.S                |  4 +-
 sysdeps/x86_64/multiarch/memrchr-avx2.S |  4 +-
 sysdeps/x86_64/x32/Makefile             |  3 +-
 sysdeps/x86_64/x32/tst-size_t-memrchr.c | 57 +++++++++++++++++++++++++
 4 files changed, 63 insertions(+), 5 deletions(-)
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-memrchr.c

diff --git a/sysdeps/x86_64/memrchr.S b/sysdeps/x86_64/memrchr.S
index 0483b1d2e9..131796aefc 100644
--- a/sysdeps/x86_64/memrchr.S
+++ b/sysdeps/x86_64/memrchr.S
@@ -24,13 +24,13 @@
 ENTRY (__memrchr)
 	movd	%esi, %xmm1
 
-	sub	$16, %rdx
+	sub	$16, %RDX_LP
 	jbe	L(length_less16)
 
 	punpcklbw	%xmm1, %xmm1
 	punpcklbw	%xmm1, %xmm1
 
-	add	%rdx, %rdi
+	add	%RDX_LP, %RDI_LP
 	pshufd	$0, %xmm1, %xmm1
 
 	movdqu	(%rdi), %xmm0
diff --git a/sysdeps/x86_64/multiarch/memrchr-avx2.S b/sysdeps/x86_64/multiarch/memrchr-avx2.S
index 3c23bad7dd..e19a732396 100644
--- a/sysdeps/x86_64/multiarch/memrchr-avx2.S
+++ b/sysdeps/x86_64/multiarch/memrchr-avx2.S
@@ -32,10 +32,10 @@ ENTRY (__memrchr_avx2)
 	vmovd	%esi, %xmm0
 	vpbroadcastb %xmm0, %ymm0
 
-	subq	$VEC_SIZE, %rdx
+	sub	$VEC_SIZE, %RDX_LP
 	jbe	L(last_vec_or_less)
 
-	addq	%rdx, %rdi
+	add	%RDX_LP, %RDI_LP
 
 	/* Check the last VEC_SIZE bytes.  */
 	vpcmpeqb (%rdi), %ymm0, %ymm1
diff --git a/sysdeps/x86_64/x32/Makefile b/sysdeps/x86_64/x32/Makefile
index 2fe1e5ac5a..e99dbd7c86 100644
--- a/sysdeps/x86_64/x32/Makefile
+++ b/sysdeps/x86_64/x32/Makefile
@@ -6,7 +6,8 @@ CFLAGS-s_llround.c += -fno-builtin-lround
 endif
 
 ifeq ($(subdir),string)
-tests += tst-size_t-memchr tst-size_t-memcmp tst-size_t-memcpy
+tests += tst-size_t-memchr tst-size_t-memcmp tst-size_t-memcpy \
+	 tst-size_t-memrchr
 endif
 
 ifeq ($(subdir),wcsmbs)
diff --git a/sysdeps/x86_64/x32/tst-size_t-memrchr.c b/sysdeps/x86_64/x32/tst-size_t-memrchr.c
new file mode 100644
index 0000000000..c83699c097
--- /dev/null
+++ b/sysdeps/x86_64/x32/tst-size_t-memrchr.c
@@ -0,0 +1,57 @@
+/* Test memrchr with size_t in the lower 32 bits of 64-bit register.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_NAME "memrchr"
+#include "test-size_t.h"
+
+IMPL (memchr, 1)
+
+typedef void * (*proto_t) (const void *, int, size_t);
+
+static void *
+__attribute__ ((noinline, noclone))
+do_memrchr (parameter_t a, parameter_t b)
+{
+  return CALL (&b, a.p, (uintptr_t) b.p, a.len);
+}
+
+static int
+test_main (void)
+{
+  test_init ();
+
+  parameter_t src = { { page_size }, buf2 };
+  parameter_t c = { { 0 }, (void *) (uintptr_t) 0x12 };
+
+  int ret = 0;
+  FOR_EACH_IMPL (impl, 0)
+    {
+      c.fn = impl->fn;
+      void * res = do_memrchr (src, c);
+      if (res)
+	{
+	  error (0, 0, "Wrong result in function %s: %p != NULL",
+		 impl->name, res);
+	  ret = 1;
+	}
+    }
+
+  return ret ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+#include <support/test-driver.c>
-- 
2.20.1


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

* [PATCH 5/8] x86-64 memset/wmemset: Properly handle the length parameter [BZ# 24097]
  2019-01-18 20:12 [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097] H.J. Lu
                   ` (3 preceding siblings ...)
  2019-01-18 20:12 ` [PATCH 4/8] x86-64 memrchr: " H.J. Lu
@ 2019-01-18 20:12 ` H.J. Lu
  2019-01-18 20:12 ` [PATCH 6/8] x86-64 strncmp family: " H.J. Lu
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 25+ messages in thread
From: H.J. Lu @ 2019-01-18 20:12 UTC (permalink / raw)
  To: libc-alpha

On x32, the size_t parameter may be passed in the lower 32 bits of a
64-bit register with the non-zero upper 32 bits.  The string/memory
functions written in assembly can only use the lower 32 bits of a
64-bit register as length or must clear the upper 32 bits before using
the full 64-bit register for length.

This pach fixes memset/wmemset for x32.  Tested on x86-64 and x32.  On
x86-64, libc.so is the same with and withou the fix.

	[BZ# 24097]
	CVE-2019-6488
	* sysdeps/x86_64/multiarch/memset-avx512-no-vzeroupper.S: Use
	RDX_LP for length.  Clear the upper 32 bits of RDX register.
	* sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S: Likewise.
	* sysdeps/x86_64/x32/Makefile (tests): Add tst-size_t-wmemset.
	* sysdeps/x86_64/x32/tst-size_t-memset.c: New file.
	* sysdeps/x86_64/x32/tst-size_t-wmemset.c: Likewise.
---
 .../multiarch/memset-avx512-no-vzeroupper.S   |  6 +-
 .../multiarch/memset-vec-unaligned-erms.S     | 34 +++++----
 sysdeps/x86_64/x32/Makefile                   |  4 +-
 sysdeps/x86_64/x32/tst-size_t-memset.c        | 73 +++++++++++++++++++
 sysdeps/x86_64/x32/tst-size_t-wmemset.c       | 20 +++++
 5 files changed, 121 insertions(+), 16 deletions(-)
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-memset.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-wmemset.c

diff --git a/sysdeps/x86_64/multiarch/memset-avx512-no-vzeroupper.S b/sysdeps/x86_64/multiarch/memset-avx512-no-vzeroupper.S
index 6506ce6252..cd7a32c7c2 100644
--- a/sysdeps/x86_64/multiarch/memset-avx512-no-vzeroupper.S
+++ b/sysdeps/x86_64/multiarch/memset-avx512-no-vzeroupper.S
@@ -29,12 +29,16 @@
 	.section .text.avx512,"ax",@progbits
 #if defined PIC
 ENTRY (MEMSET_CHK)
-	cmpq	%rdx, %rcx
+	cmp	%RDX_LP, %RCX_LP
 	jb	HIDDEN_JUMPTARGET (__chk_fail)
 END (MEMSET_CHK)
 #endif
 
 ENTRY (MEMSET)
+# ifdef __ILP32__
+	/* Clear the upper 32 bits.  */
+	mov	%edx, %edx
+# endif
 	vpxor	%xmm0, %xmm0, %xmm0
 	vmovd	%esi, %xmm1
 	lea	(%rdi, %rdx), %rsi
diff --git a/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S
index 71a0887c68..5e0d307d85 100644
--- a/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S
+++ b/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S
@@ -75,8 +75,8 @@
 	.section SECTION(.text),"ax",@progbits
 #if VEC_SIZE == 16 && IS_IN (libc)
 ENTRY (__bzero)
-	movq	%rdi, %rax /* Set return value.  */
-	movq	%rsi, %rdx /* Set n.  */
+	mov	%RDI_LP, %RAX_LP /* Set return value.  */
+	mov	%RSI_LP, %RDX_LP /* Set n.  */
 	pxor	%xmm0, %xmm0
 	jmp	L(entry_from_bzero)
 END (__bzero)
@@ -86,13 +86,13 @@ weak_alias (__bzero, bzero)
 #if IS_IN (libc)
 # if defined SHARED
 ENTRY_CHK (WMEMSET_CHK_SYMBOL (__wmemset_chk, unaligned))
-	cmpq	%rdx, %rcx
+	cmp	%RDX_LP, %RCX_LP
 	jb	HIDDEN_JUMPTARGET (__chk_fail)
 END_CHK (WMEMSET_CHK_SYMBOL (__wmemset_chk, unaligned))
 # endif
 
 ENTRY (WMEMSET_SYMBOL (__wmemset, unaligned))
-	shlq	$2, %rdx
+	shl	$2, %RDX_LP
 	WMEMSET_VDUP_TO_VEC0_AND_SET_RETURN (%esi, %rdi)
 	jmp	L(entry_from_bzero)
 END (WMEMSET_SYMBOL (__wmemset, unaligned))
@@ -100,13 +100,17 @@ END (WMEMSET_SYMBOL (__wmemset, unaligned))
 
 #if defined SHARED && IS_IN (libc)
 ENTRY_CHK (MEMSET_CHK_SYMBOL (__memset_chk, unaligned))
-	cmpq	%rdx, %rcx
+	cmp	%RDX_LP, %RCX_LP
 	jb	HIDDEN_JUMPTARGET (__chk_fail)
 END_CHK (MEMSET_CHK_SYMBOL (__memset_chk, unaligned))
 #endif
 
 ENTRY (MEMSET_SYMBOL (__memset, unaligned))
 	MEMSET_VDUP_TO_VEC0_AND_SET_RETURN (%esi, %rdi)
+# ifdef __ILP32__
+	/* Clear the upper 32 bits.  */
+	mov	%edx, %edx
+# endif
 L(entry_from_bzero):
 	cmpq	$VEC_SIZE, %rdx
 	jb	L(less_vec)
@@ -122,14 +126,14 @@ END (MEMSET_SYMBOL (__memset, unaligned))
 
 # if VEC_SIZE == 16
 ENTRY (__memset_chk_erms)
-	cmpq	%rdx, %rcx
+	cmp	%RDX_LP, %RCX_LP
 	jb	HIDDEN_JUMPTARGET (__chk_fail)
 END (__memset_chk_erms)
 
 /* Only used to measure performance of REP STOSB.  */
 ENTRY (__memset_erms)
 	/* Skip zero length.  */
-	testq	%rdx, %rdx
+	test	%RDX_LP, %RDX_LP
 	jnz	 L(stosb)
 	movq	%rdi, %rax
 	ret
@@ -141,11 +145,11 @@ ENTRY (MEMSET_SYMBOL (__memset, erms))
 L(stosb):
 	/* Issue vzeroupper before rep stosb.  */
 	VZEROUPPER
-	movq	%rdx, %rcx
+	mov	%RDX_LP, %RCX_LP
 	movzbl	%sil, %eax
-	movq	%rdi, %rdx
+	mov	%RDI_LP, %RDX_LP
 	rep stosb
-	movq	%rdx, %rax
+	mov	%RDX_LP, %RAX_LP
 	ret
 # if VEC_SIZE == 16
 END (__memset_erms)
@@ -155,16 +159,20 @@ END (MEMSET_SYMBOL (__memset, erms))
 
 # if defined SHARED && IS_IN (libc)
 ENTRY_CHK (MEMSET_CHK_SYMBOL (__memset_chk, unaligned_erms))
-	cmpq	%rdx, %rcx
+	cmp	%RDX_LP, %RCX_LP
 	jb	HIDDEN_JUMPTARGET (__chk_fail)
 END_CHK (MEMSET_CHK_SYMBOL (__memset_chk, unaligned_erms))
 # endif
 
 ENTRY (MEMSET_SYMBOL (__memset, unaligned_erms))
 	MEMSET_VDUP_TO_VEC0_AND_SET_RETURN (%esi, %rdi)
-	cmpq	$VEC_SIZE, %rdx
+# ifdef __ILP32__
+	/* Clear the upper 32 bits.  */
+	mov	%edx, %edx
+# endif
+	cmp	$VEC_SIZE, %RDX_LP
 	jb	L(less_vec)
-	cmpq	$(VEC_SIZE * 2), %rdx
+	cmp	$(VEC_SIZE * 2), %RDX_LP
 	ja	L(stosb_more_2x_vec)
 	/* From VEC and to 2 * VEC.  No branch when size == VEC_SIZE.  */
 	VMOVU	%VEC(0), -VEC_SIZE(%rdi,%rdx)
diff --git a/sysdeps/x86_64/x32/Makefile b/sysdeps/x86_64/x32/Makefile
index e99dbd7c86..98bd9ae9cd 100644
--- a/sysdeps/x86_64/x32/Makefile
+++ b/sysdeps/x86_64/x32/Makefile
@@ -7,9 +7,9 @@ endif
 
 ifeq ($(subdir),string)
 tests += tst-size_t-memchr tst-size_t-memcmp tst-size_t-memcpy \
-	 tst-size_t-memrchr
+	 tst-size_t-memrchr tst-size_t-memset
 endif
 
 ifeq ($(subdir),wcsmbs)
-tests += tst-size_t-wmemchr tst-size_t-wmemcmp
+tests += tst-size_t-wmemchr tst-size_t-wmemcmp tst-size_t-wmemset
 endif
diff --git a/sysdeps/x86_64/x32/tst-size_t-memset.c b/sysdeps/x86_64/x32/tst-size_t-memset.c
new file mode 100644
index 0000000000..2c367af6cd
--- /dev/null
+++ b/sysdeps/x86_64/x32/tst-size_t-memset.c
@@ -0,0 +1,73 @@
+/* Test memset with size_t in the lower 32 bits of 64-bit register.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifdef WIDE
+# define TEST_NAME "wmemset"
+#else
+# define TEST_NAME "memset"
+#endif /* WIDE */
+
+#include "test-size_t.h"
+
+#ifdef WIDE
+# include <wchar.h>
+# define MEMSET wmemset
+# define CHAR wchar_t
+#else
+# define MEMSET memset
+# define CHAR char
+#endif /* WIDE */
+
+IMPL (MEMSET, 1)
+
+typedef CHAR *(*proto_t) (CHAR *, int, size_t);
+
+static void *
+__attribute__ ((noinline, noclone))
+do_memset (parameter_t a, parameter_t b)
+{
+  return CALL (&b, a.p, (uintptr_t) b.p, a.len);
+}
+
+static int
+test_main (void)
+{
+  test_init ();
+
+  CHAR ch = 0x23;
+  parameter_t src = { { page_size / sizeof (CHAR) }, buf2 };
+  parameter_t c = { { 0 }, (void *) (uintptr_t) ch };
+
+  int ret = 0;
+  FOR_EACH_IMPL (impl, 0)
+    {
+      c.fn = impl->fn;
+      CHAR *p = (CHAR *) do_memset (src, c);
+      size_t i;
+      for (i = 0; i < src.len; i++)
+	if (p[i] != ch)
+	  {
+	    error (0, 0, "Wrong result in function %s", impl->name);
+	    ret = 1;
+	  }
+    }
+
+  return ret ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/x86_64/x32/tst-size_t-wmemset.c b/sysdeps/x86_64/x32/tst-size_t-wmemset.c
new file mode 100644
index 0000000000..955eb488c2
--- /dev/null
+++ b/sysdeps/x86_64/x32/tst-size_t-wmemset.c
@@ -0,0 +1,20 @@
+/* Test wmemset with size_t in the lower 32 bits of 64-bit register.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define WIDE 1
+#include "tst-size_t-memset.c"
-- 
2.20.1


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

* [PATCH 6/8] x86-64 strncmp family: Properly handle the length parameter [BZ# 24097]
  2019-01-18 20:12 [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097] H.J. Lu
                   ` (4 preceding siblings ...)
  2019-01-18 20:12 ` [PATCH 5/8] x86-64 memset/wmemset: " H.J. Lu
@ 2019-01-18 20:12 ` H.J. Lu
  2019-01-18 20:12 ` [PATCH 7/8] x86-64 strncpy: " H.J. Lu
  2019-01-18 20:12 ` [PATCH 8/8] x86-64 strnlen/wcsnlen: " H.J. Lu
  7 siblings, 0 replies; 25+ messages in thread
From: H.J. Lu @ 2019-01-18 20:12 UTC (permalink / raw)
  To: libc-alpha

On x32, the size_t parameter may be passed in the lower 32 bits of a
64-bit register with the non-zero upper 32 bits.  The string/memory
functions written in assembly can only use the lower 32 bits of a
64-bit register as length or must clear the upper 32 bits before using
the full 64-bit register for length.

This pach fixes the strncmp family for x32.  Tested on x86-64 and x32.
On x86-64, libc.so is the same with and withou the fix.

	[BZ# 24097]
	CVE-2019-6488
	* sysdeps/x86_64/multiarch/strcmp-avx2.S: Use RDX_LP for length.
	* sysdeps/x86_64/multiarch/strcmp-sse42.S: Likewise.
	* sysdeps/x86_64/strcmp.S: Likewise.
	* sysdeps/x86_64/x32/Makefile (tests): Add tst-size_t-strncasecmp,
	tst-size_t-strncmp and tst-size_t-wcsncmp.
	* sysdeps/x86_64/x32/tst-size_t-strncasecmp.c: New file.
	* sysdeps/x86_64/x32/tst-size_t-strncmp.c: Likewise.
	* sysdeps/x86_64/x32/tst-size_t-wcsncmp.c: Likewise.
---
 sysdeps/x86_64/multiarch/strcmp-avx2.S      |  6 +-
 sysdeps/x86_64/multiarch/strcmp-sse42.S     |  6 +-
 sysdeps/x86_64/strcmp.S                     |  6 +-
 sysdeps/x86_64/x32/Makefile                 |  6 +-
 sysdeps/x86_64/x32/tst-size_t-strncasecmp.c | 59 ++++++++++++++++
 sysdeps/x86_64/x32/tst-size_t-strncmp.c     | 78 +++++++++++++++++++++
 sysdeps/x86_64/x32/tst-size_t-wcsncmp.c     | 20 ++++++
 7 files changed, 170 insertions(+), 11 deletions(-)
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-strncasecmp.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-strncmp.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-wcsncmp.c

diff --git a/sysdeps/x86_64/multiarch/strcmp-avx2.S b/sysdeps/x86_64/multiarch/strcmp-avx2.S
index 0c27f90d29..b32a5e3528 100644
--- a/sysdeps/x86_64/multiarch/strcmp-avx2.S
+++ b/sysdeps/x86_64/multiarch/strcmp-avx2.S
@@ -79,15 +79,15 @@
 ENTRY (STRCMP)
 # ifdef USE_AS_STRNCMP
 	/* Check for simple cases (0 or 1) in offset.  */
-	cmp	$1, %rdx
+	cmp	$1, %RDX_LP
 	je	L(char0)
 	jb	L(zero)
 #  ifdef USE_AS_WCSCMP
 	/* Convert units: from wide to byte char.  */
-	shl	$2, %rdx
+	shl	$2, %RDX_LP
 #  endif
 	/* Register %r11 tracks the maximum offset.  */
-	movq	%rdx, %r11
+	mov	%RDX_LP, %R11_LP
 # endif
 	movl	%edi, %eax
 	xorl	%edx, %edx
diff --git a/sysdeps/x86_64/multiarch/strcmp-sse42.S b/sysdeps/x86_64/multiarch/strcmp-sse42.S
index 2f4b34a03f..73bbe5c9e1 100644
--- a/sysdeps/x86_64/multiarch/strcmp-sse42.S
+++ b/sysdeps/x86_64/multiarch/strcmp-sse42.S
@@ -156,11 +156,11 @@ STRCMP_SSE42:
 #endif
 
 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-	test	%rdx, %rdx
+	test	%RDX_LP, %RDX_LP
 	je	LABEL(strcmp_exitz)
-	cmp	$1, %rdx
+	cmp	$1, %RDX_LP
 	je	LABEL(Byte0)
-	mov	%rdx, %r11
+	mov	%RDX_LP, %R11_LP
 #endif
 	mov	%esi, %ecx
 	mov	%edi, %eax
diff --git a/sysdeps/x86_64/strcmp.S b/sysdeps/x86_64/strcmp.S
index 55445148d5..f95463155a 100644
--- a/sysdeps/x86_64/strcmp.S
+++ b/sysdeps/x86_64/strcmp.S
@@ -135,11 +135,11 @@ ENTRY (STRCMP)
  * This implementation uses SSE to compare up to 16 bytes at a time.
  */
 #if defined USE_AS_STRNCMP || defined USE_AS_STRNCASECMP_L
-	test	%rdx, %rdx
+	test	%RDX_LP, %RDX_LP
 	je	LABEL(strcmp_exitz)
-	cmp	$1, %rdx
+	cmp	$1, %RDX_LP
 	je	LABEL(Byte0)
-	mov	%rdx, %r11
+	mov	%RDX_LP, %R11_LP
 #endif
 	mov	%esi, %ecx
 	mov	%edi, %eax
diff --git a/sysdeps/x86_64/x32/Makefile b/sysdeps/x86_64/x32/Makefile
index 98bd9ae9cd..db30283977 100644
--- a/sysdeps/x86_64/x32/Makefile
+++ b/sysdeps/x86_64/x32/Makefile
@@ -7,9 +7,11 @@ endif
 
 ifeq ($(subdir),string)
 tests += tst-size_t-memchr tst-size_t-memcmp tst-size_t-memcpy \
-	 tst-size_t-memrchr tst-size_t-memset
+	 tst-size_t-memrchr tst-size_t-memset tst-size_t-strncasecmp \
+	 tst-size_t-strncmp
 endif
 
 ifeq ($(subdir),wcsmbs)
-tests += tst-size_t-wmemchr tst-size_t-wmemcmp tst-size_t-wmemset
+tests += tst-size_t-wmemchr tst-size_t-wmemcmp tst-size_t-wmemset \
+	 tst-size_t-wcsncmp
 endif
diff --git a/sysdeps/x86_64/x32/tst-size_t-strncasecmp.c b/sysdeps/x86_64/x32/tst-size_t-strncasecmp.c
new file mode 100644
index 0000000000..862335937b
--- /dev/null
+++ b/sysdeps/x86_64/x32/tst-size_t-strncasecmp.c
@@ -0,0 +1,59 @@
+/* Test strncaecmp with size_t in the lower 32 bits of 64-bit register.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_NAME "strncasecmp"
+#include "test-size_t.h"
+
+IMPL (strncasecmp, 1)
+
+typedef int (*proto_t) (const char *, const char *, size_t);
+
+static int
+__attribute__ ((noinline, noclone))
+do_strncasecmp (parameter_t a, parameter_t b)
+{
+  return CALL (&b, a.p, b.p, a.len);
+}
+
+static int
+test_main (void)
+{
+  test_init ();
+
+  parameter_t dest = { { page_size }, buf1 };
+  parameter_t src = { { 0 }, buf2 };
+
+  strncpy ((char *) buf1, (const char *) buf2, page_size);
+
+  int ret = 0;
+  FOR_EACH_IMPL (impl, 0)
+    {
+      src.fn = impl->fn;
+      int res = do_strncasecmp (dest, src);
+      if (res)
+	{
+	  error (0, 0, "Wrong result in function %s: %i != 0",
+		 impl->name, res);
+	  ret = 1;
+	}
+    }
+
+  return ret ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/x86_64/x32/tst-size_t-strncmp.c b/sysdeps/x86_64/x32/tst-size_t-strncmp.c
new file mode 100644
index 0000000000..54e6bd83ef
--- /dev/null
+++ b/sysdeps/x86_64/x32/tst-size_t-strncmp.c
@@ -0,0 +1,78 @@
+/* Test strncmp with size_t in the lower 32 bits of 64-bit register.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifdef WIDE
+# define TEST_NAME "wcsncmp"
+#else
+# define TEST_NAME "strncmp"
+#endif
+
+#include "test-size_t.h"
+
+#ifdef WIDE
+# include <wchar.h>
+
+# define STRNCMP wcsncmp
+# define STRNCPY wcsncpy
+# define CHAR wchar_t
+#else
+# define STRNCMP strncmp
+# define STRNCPY strncpy
+# define CHAR char
+#endif
+
+IMPL (STRNCMP, 1)
+
+typedef int (*proto_t) (const CHAR *, const CHAR *, size_t);
+
+
+static int
+__attribute__ ((noinline, noclone))
+do_strncmp (parameter_t a, parameter_t b)
+{
+  return CALL (&b, a.p, b.p, a.len);
+}
+
+static int
+test_main (void)
+{
+  test_init ();
+
+  size_t size = page_size / sizeof (CHAR);
+  parameter_t dest = { { size }, buf1 };
+  parameter_t src = { { 0 }, buf2 };
+
+  STRNCPY ((CHAR *) buf1, (const CHAR *) buf2, size);
+
+  int ret = 0;
+  FOR_EACH_IMPL (impl, 0)
+    {
+      src.fn = impl->fn;
+      int res = do_strncmp (dest, src);
+      if (res)
+	{
+	  error (0, 0, "Wrong result in function %s: %i != 0",
+		 impl->name, res);
+	  ret = 1;
+	}
+    }
+
+  return ret ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/x86_64/x32/tst-size_t-wcsncmp.c b/sysdeps/x86_64/x32/tst-size_t-wcsncmp.c
new file mode 100644
index 0000000000..4829647c19
--- /dev/null
+++ b/sysdeps/x86_64/x32/tst-size_t-wcsncmp.c
@@ -0,0 +1,20 @@
+/* Test wcsncmp with size_t in the lower 32 bits of 64-bit register.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define WIDE 1
+#include "tst-size_t-strncmp.c"
-- 
2.20.1


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

* [PATCH 7/8] x86-64 strncpy: Properly handle the length parameter [BZ# 24097]
  2019-01-18 20:12 [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097] H.J. Lu
                   ` (5 preceding siblings ...)
  2019-01-18 20:12 ` [PATCH 6/8] x86-64 strncmp family: " H.J. Lu
@ 2019-01-18 20:12 ` H.J. Lu
  2019-01-18 20:12 ` [PATCH 8/8] x86-64 strnlen/wcsnlen: " H.J. Lu
  7 siblings, 0 replies; 25+ messages in thread
From: H.J. Lu @ 2019-01-18 20:12 UTC (permalink / raw)
  To: libc-alpha

On x32, the size_t parameter may be passed in the lower 32 bits of a
64-bit register with the non-zero upper 32 bits.  The string/memory
functions written in assembly can only use the lower 32 bits of a
64-bit register as length or must clear the upper 32 bits before using
the full 64-bit register for length.

This pach fixes strncpy for x32.  Tested on x86-64 and x32.  On x86-64,
libc.so is the same with and withou the fix.

	[BZ# 24097]
	CVE-2019-6488
	* sysdeps/x86_64/multiarch/strcpy-avx2.S: Use RDX_LP for length.
	* sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S: Likewise.
	* sysdeps/x86_64/multiarch/strcpy-ssse3.S: Likewise.
	* sysdeps/x86_64/x32/Makefile (tests): Add tst-size_t-strncpy.
	* sysdeps/x86_64/x32/tst-size_t-strncpy.c: New file.
---
 sysdeps/x86_64/multiarch/strcpy-avx2.S        |  4 +-
 .../x86_64/multiarch/strcpy-sse2-unaligned.S  |  4 +-
 sysdeps/x86_64/multiarch/strcpy-ssse3.S       |  6 +-
 sysdeps/x86_64/x32/Makefile                   |  2 +-
 sysdeps/x86_64/x32/tst-size_t-strncpy.c       | 58 +++++++++++++++++++
 5 files changed, 66 insertions(+), 8 deletions(-)
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-strncpy.c

diff --git a/sysdeps/x86_64/multiarch/strcpy-avx2.S b/sysdeps/x86_64/multiarch/strcpy-avx2.S
index 81677f9060..e72a0cad7d 100644
--- a/sysdeps/x86_64/multiarch/strcpy-avx2.S
+++ b/sysdeps/x86_64/multiarch/strcpy-avx2.S
@@ -49,8 +49,8 @@
 	.section .text.avx,"ax",@progbits
 ENTRY (STRCPY)
 #  ifdef USE_AS_STRNCPY
-	mov	%rdx, %r8
-	test	%r8, %r8
+	mov	%RDX_LP, %R8_LP
+	test	%R8_LP, %R8_LP
 	jz	L(ExitZero)
 #  endif
 	mov	%rsi, %rcx
diff --git a/sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S b/sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S
index b7c79976ea..0d6914e113 100644
--- a/sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S
+++ b/sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S
@@ -40,8 +40,8 @@
 .text
 ENTRY (STRCPY)
 #  ifdef USE_AS_STRNCPY
-	mov	%rdx, %r8
-	test	%r8, %r8
+	mov	%RDX_LP, %R8_LP
+	test	%R8_LP, %R8_LP
 	jz	L(ExitZero)
 #  endif
 	mov	%rsi, %rcx
diff --git a/sysdeps/x86_64/multiarch/strcpy-ssse3.S b/sysdeps/x86_64/multiarch/strcpy-ssse3.S
index ec53f2a632..39e6ad762c 100644
--- a/sysdeps/x86_64/multiarch/strcpy-ssse3.S
+++ b/sysdeps/x86_64/multiarch/strcpy-ssse3.S
@@ -31,13 +31,13 @@ ENTRY (STRCPY)
 
 	mov	%rsi, %rcx
 #  ifdef USE_AS_STRNCPY
-	mov	%rdx, %r8
+	mov	%RDX_LP, %R8_LP
 #  endif
 	mov	%rdi, %rdx
 #  ifdef USE_AS_STRNCPY
-	test	%r8, %r8
+	test	%R8_LP, %R8_LP
 	jz	L(Exit0)
-	cmp	$8, %r8
+	cmp	$8, %R8_LP
 	jbe	L(StrncpyExit8Bytes)
 # endif
 	cmpb	$0, (%rcx)
diff --git a/sysdeps/x86_64/x32/Makefile b/sysdeps/x86_64/x32/Makefile
index db30283977..2a9e20a90b 100644
--- a/sysdeps/x86_64/x32/Makefile
+++ b/sysdeps/x86_64/x32/Makefile
@@ -8,7 +8,7 @@ endif
 ifeq ($(subdir),string)
 tests += tst-size_t-memchr tst-size_t-memcmp tst-size_t-memcpy \
 	 tst-size_t-memrchr tst-size_t-memset tst-size_t-strncasecmp \
-	 tst-size_t-strncmp
+	 tst-size_t-strncmp tst-size_t-strncpy
 endif
 
 ifeq ($(subdir),wcsmbs)
diff --git a/sysdeps/x86_64/x32/tst-size_t-strncpy.c b/sysdeps/x86_64/x32/tst-size_t-strncpy.c
new file mode 100644
index 0000000000..4dec71e6b3
--- /dev/null
+++ b/sysdeps/x86_64/x32/tst-size_t-strncpy.c
@@ -0,0 +1,58 @@
+/* Test strncpy with size_t in the lower 32 bits of 64-bit register.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_NAME "strncpy"
+#include "test-size_t.h"
+
+IMPL (strncpy, 1)
+
+typedef char *(*proto_t) (char *, const char*, size_t);
+
+static void *
+__attribute__ ((noinline, noclone))
+do_strncpy (parameter_t a, parameter_t b)
+{
+  return CALL (&b, a.p, b.p, a.len);
+}
+
+static int
+test_main (void)
+{
+  test_init ();
+
+  parameter_t dest = { { page_size }, buf1 };
+  parameter_t src = { { 0 }, buf2 };
+
+  int ret = 0;
+  FOR_EACH_IMPL (impl, 0)
+    {
+      src.fn = impl->fn;
+      do_strncpy (dest, src);
+      int res = strncmp (dest.p, src.p, dest.len);
+      if (res)
+	{
+	  error (0, 0, "Wrong result in function %s: %i != 0",
+		 impl->name, res);
+	  ret = 1;
+	}
+    }
+
+  return ret ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+#include <support/test-driver.c>
-- 
2.20.1


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

* [PATCH 8/8] x86-64 strnlen/wcsnlen: Properly handle the length parameter [BZ# 24097]
  2019-01-18 20:12 [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097] H.J. Lu
                   ` (6 preceding siblings ...)
  2019-01-18 20:12 ` [PATCH 7/8] x86-64 strncpy: " H.J. Lu
@ 2019-01-18 20:12 ` H.J. Lu
  7 siblings, 0 replies; 25+ messages in thread
From: H.J. Lu @ 2019-01-18 20:12 UTC (permalink / raw)
  To: libc-alpha

On x32, the size_t parameter may be passed in the lower 32 bits of a
64-bit register with the non-zero upper 32 bits.  The string/memory
functions written in assembly can only use the lower 32 bits of a
64-bit register as length or must clear the upper 32 bits before using
the full 64-bit register for length.

This pach fixes strnlen/wcsnlen for x32.  Tested on x86-64 and x32.  On
x86-64, libc.so is the same with and withou the fix.

	[BZ# 24097]
	CVE-2019-6488
	* sysdeps/x86_64/multiarch/strlen-avx2.S: Use RDX_LP for length.
	Clear the upper 32 bits of RDX register.
	* sysdeps/x86_64/strlen.S: Use RDX_LP for length.
	* sysdeps/x86_64/x32/Makefile (tests): Add tst-size_t-strnlen
	and tst-size_t-wcsnlen.
	* sysdeps/x86_64/x32/tst-size_t-strnlen.c: New file.
	* sysdeps/x86_64/x32/tst-size_t-wcsnlen.c: Likewise.
---
 sysdeps/x86_64/multiarch/strlen-avx2.S  |  9 ++--
 sysdeps/x86_64/strlen.S                 | 12 ++---
 sysdeps/x86_64/x32/Makefile             |  4 +-
 sysdeps/x86_64/x32/tst-size_t-strnlen.c | 72 +++++++++++++++++++++++++
 sysdeps/x86_64/x32/tst-size_t-wcsnlen.c | 20 +++++++
 5 files changed, 106 insertions(+), 11 deletions(-)
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-strnlen.c
 create mode 100644 sysdeps/x86_64/x32/tst-size_t-wcsnlen.c

diff --git a/sysdeps/x86_64/multiarch/strlen-avx2.S b/sysdeps/x86_64/multiarch/strlen-avx2.S
index aa0ade503f..3e7f14a846 100644
--- a/sysdeps/x86_64/multiarch/strlen-avx2.S
+++ b/sysdeps/x86_64/multiarch/strlen-avx2.S
@@ -42,12 +42,15 @@
 ENTRY (STRLEN)
 # ifdef USE_AS_STRNLEN
 	/* Check for zero length.  */
-	testq	%rsi, %rsi
+	test	%RSI_LP, %RSI_LP
 	jz	L(zero)
 #  ifdef USE_AS_WCSLEN
-	shl	$2, %rsi
+	shl	$2, %RSI_LP
+#  elif defined __ILP32__
+	/* Clear the upper 32 bits.  */
+	movl	%esi, %esi
 #  endif
-	movq	%rsi, %r8
+	mov	%RSI_LP, %R8_LP
 # endif
 	movl	%edi, %ecx
 	movq	%rdi, %rdx
diff --git a/sysdeps/x86_64/strlen.S b/sysdeps/x86_64/strlen.S
index d6fdc3580f..9ab357fc1a 100644
--- a/sysdeps/x86_64/strlen.S
+++ b/sysdeps/x86_64/strlen.S
@@ -59,21 +59,21 @@ ENTRY(strlen)
 
 #ifdef AS_STRNLEN
 /* Do not read anything when n==0.  */
-	test	%rsi, %rsi
+	test	%RSI_LP, %RSI_LP
 	jne	L(n_nonzero)
 	xor	%rax, %rax
 	ret
 L(n_nonzero):
 # ifdef AS_WCSLEN
-	shlq	$2, %rsi
+	shl	$2, %RSI_LP
 # endif
 
 /* Initialize long lived registers.  */
 
-	add	%rdi, %rsi
-	mov	%rsi, %r10
-	and	$-64, %r10
-	mov	%rsi, %r11
+	add	%RDI_LP, %RSI_LP
+	mov	%RSI_LP, %R10_LP
+	and	$-64, %R10_LP
+	mov	%RSI_LP, %R11_LP
 #endif
 
 	pxor	%xmm0, %xmm0
diff --git a/sysdeps/x86_64/x32/Makefile b/sysdeps/x86_64/x32/Makefile
index 2a9e20a90b..1557724b0c 100644
--- a/sysdeps/x86_64/x32/Makefile
+++ b/sysdeps/x86_64/x32/Makefile
@@ -8,10 +8,10 @@ endif
 ifeq ($(subdir),string)
 tests += tst-size_t-memchr tst-size_t-memcmp tst-size_t-memcpy \
 	 tst-size_t-memrchr tst-size_t-memset tst-size_t-strncasecmp \
-	 tst-size_t-strncmp tst-size_t-strncpy
+	 tst-size_t-strncmp tst-size_t-strncpy tst-size_t-strnlen
 endif
 
 ifeq ($(subdir),wcsmbs)
 tests += tst-size_t-wmemchr tst-size_t-wmemcmp tst-size_t-wmemset \
-	 tst-size_t-wcsncmp
+	 tst-size_t-wcsncmp tst-size_t-wcsnlen
 endif
diff --git a/sysdeps/x86_64/x32/tst-size_t-strnlen.c b/sysdeps/x86_64/x32/tst-size_t-strnlen.c
new file mode 100644
index 0000000000..690a4a8a31
--- /dev/null
+++ b/sysdeps/x86_64/x32/tst-size_t-strnlen.c
@@ -0,0 +1,72 @@
+/* Test strnlen with size_t in the lower 32 bits of 64-bit register.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifdef WIDE
+# define TEST_NAME "wcsnlen"
+#else
+# define TEST_NAME "strnlen"
+#endif /* WIDE */
+
+#include "test-size_t.h"
+
+#ifdef WIDE
+# include <wchar.h>
+# define STRNLEN wcsnlen
+# define CHAR wchar_t
+#else
+# define STRNLEN strnlen
+# define CHAR char
+#endif /* WIDE */
+
+IMPL (STRNLEN, 1)
+
+typedef size_t (*proto_t) (const CHAR *, size_t);
+
+static size_t
+__attribute__ ((noinline, noclone))
+do_strnlen (parameter_t a, parameter_t b)
+{
+  return CALL (&a, a.p, b.len);
+}
+
+static int
+test_main (void)
+{
+  test_init ();
+
+  size_t size = page_size / sizeof (CHAR);
+  parameter_t src = { { 0 }, buf2 };
+  parameter_t c = { { size }, (void *) (uintptr_t) 'a' };
+
+  int ret = 0;
+  FOR_EACH_IMPL (impl, 0)
+    {
+      src.fn = impl->fn;
+      size_t res = do_strnlen (src, c);
+      if (res != size)
+	{
+	  error (0, 0, "Wrong result in function %s: 0x%x != 0x%x",
+		 impl->name, res, size);
+	  ret = 1;
+	}
+    }
+
+  return ret ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/x86_64/x32/tst-size_t-wcsnlen.c b/sysdeps/x86_64/x32/tst-size_t-wcsnlen.c
new file mode 100644
index 0000000000..093b4bbe1b
--- /dev/null
+++ b/sysdeps/x86_64/x32/tst-size_t-wcsnlen.c
@@ -0,0 +1,20 @@
+/* Test wcsnlen with size_t in the lower 32 bits of 64-bit register.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define WIDE 1
+#include "tst-size_t-strnlen.c"
-- 
2.20.1


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

* Re: [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097]
  2019-01-18 19:56     ` Florian Weimer
@ 2019-01-18 20:15       ` H.J. Lu
  2019-01-18 20:21         ` Florian Weimer
  2019-01-18 20:15       ` Florian Weimer
  1 sibling, 1 reply; 25+ messages in thread
From: H.J. Lu @ 2019-01-18 20:15 UTC (permalink / raw)
  To: Florian Weimer; +Cc: GNU C Library

On Fri, Jan 18, 2019 at 11:56 AM Florian Weimer <fweimer@redhat.com> wrote:
>
> * H. J. Lu:
>
> > On Fri, Jan 18, 2019 at 2:50 AM Florian Weimer <fweimer@redhat.com> wrote:
> >>
> >> * H. J. Lu:
> >>
> >> > On x32, the size_t parameter may be passed in the lower 32 bits of a
> >> > 64-bit register with the non-zero upper 32 bits.  The string/memory
> >> > functions written in assembly can only use the lower 32 bits of a
> >> > 64-bit register as length or must clear the upper 32 bits before using
> >> > the full 64-bit register for length.
> >> >
> >> > This pach fixes string/memory functions written in assembly for x32.
> >> > Tested on x86-64 and x32.  On x86-64, libc.so is the same with and
> >> > withou the fix.
> >>
> >> Can this bug result in buffer overflows?  Should we obtain a CVE
> >
> > Yes, definitely.
> >
> >> identifier?
> >>
> >
> > Yes, please.  Can you do that for me?
>
> Done, MITRE gave us CVE-2019-6488.  Please reference this in the
> ChangeLog and the commit message if you have not done so.  Please also

Done.  I just regenerated and submitted the new patch set.

> add short NEWS entry in the security section.  Thanks.
>

I added:

  CVE-2019-6488: On x32, the size_t parameter may be passed in the lower
  32 bits of a 64-bit register with the non-zero upper 32 bits.  When
  it happens, the string/memory functions written in assembly will cause
  buffer overflow if the full 64-bit register is used as the 32-bit
  size_t value.  Reported by Florian Weimer.

I will check in the new patch set. tomorrow if there are no objections.


-- 
H.J.

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

* Re: [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097]
  2019-01-18 19:56     ` Florian Weimer
  2019-01-18 20:15       ` H.J. Lu
@ 2019-01-18 20:15       ` Florian Weimer
  1 sibling, 0 replies; 25+ messages in thread
From: Florian Weimer @ 2019-01-18 20:15 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GNU C Library

* Florian Weimer:

> * H. J. Lu:
>
>> On Fri, Jan 18, 2019 at 2:50 AM Florian Weimer <fweimer@redhat.com> wrote:
>>>
>>> * H. J. Lu:
>>>
>>> > On x32, the size_t parameter may be passed in the lower 32 bits of a
>>> > 64-bit register with the non-zero upper 32 bits.  The string/memory
>>> > functions written in assembly can only use the lower 32 bits of a
>>> > 64-bit register as length or must clear the upper 32 bits before using
>>> > the full 64-bit register for length.
>>> >
>>> > This pach fixes string/memory functions written in assembly for x32.
>>> > Tested on x86-64 and x32.  On x86-64, libc.so is the same with and
>>> > withou the fix.
>>>
>>> Can this bug result in buffer overflows?  Should we obtain a CVE
>>
>> Yes, definitely.
>>
>>> identifier?
>>>
>>
>> Yes, please.  Can you do that for me?
>
> Done, MITRE gave us CVE-2019-6488.  Please reference this in the
> ChangeLog and the commit message if you have not done so.  Please also
> add short NEWS entry in the security section.  Thanks.

I should clarify that I have not reviewed the actual patches.

Thanks,
Florian

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

* Re: [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097]
  2019-01-18 20:15       ` H.J. Lu
@ 2019-01-18 20:21         ` Florian Weimer
  2019-01-18 20:24           ` H.J. Lu
  0 siblings, 1 reply; 25+ messages in thread
From: Florian Weimer @ 2019-01-18 20:21 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GNU C Library

* H. J. Lu:

> On Fri, Jan 18, 2019 at 11:56 AM Florian Weimer <fweimer@redhat.com> wrote:
>>
>> * H. J. Lu:
>>
>> > On Fri, Jan 18, 2019 at 2:50 AM Florian Weimer <fweimer@redhat.com> wrote:
>> >>
>> >> * H. J. Lu:
>> >>
>> >> > On x32, the size_t parameter may be passed in the lower 32 bits of a
>> >> > 64-bit register with the non-zero upper 32 bits.  The string/memory
>> >> > functions written in assembly can only use the lower 32 bits of a
>> >> > 64-bit register as length or must clear the upper 32 bits before using
>> >> > the full 64-bit register for length.
>> >> >
>> >> > This pach fixes string/memory functions written in assembly for x32.
>> >> > Tested on x86-64 and x32.  On x86-64, libc.so is the same with and
>> >> > withou the fix.
>> >>
>> >> Can this bug result in buffer overflows?  Should we obtain a CVE
>> >
>> > Yes, definitely.
>> >
>> >> identifier?
>> >>
>> >
>> > Yes, please.  Can you do that for me?
>>
>> Done, MITRE gave us CVE-2019-6488.  Please reference this in the
>> ChangeLog and the commit message if you have not done so.  Please also
>
> Done.  I just regenerated and submitted the new patch set.
>
>> add short NEWS entry in the security section.  Thanks.
>>
>
> I added:
>
>   CVE-2019-6488: On x32, the size_t parameter may be passed in the lower
>   32 bits of a 64-bit register with the non-zero upper 32 bits.  When
>   it happens, the string/memory functions written in assembly will cause
>   buffer overflow if the full 64-bit register is used as the 32-bit

I think we generally describe the faulty behavior in the past tense
(“When this happen*ed*, the string/memory functions written in assembly
*would* cause *a* buffer overflow if the full 64-bit register was
used”).  The first sentence is still current behavior, so it's okay.

>   size_t value.  Reported by Florian Weimer.

Huh.  Did I really report this?  When?

Thanks,
Florian

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

* Re: [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097]
  2019-01-18 20:21         ` Florian Weimer
@ 2019-01-18 20:24           ` H.J. Lu
  2019-01-18 20:40             ` Florian Weimer
  0 siblings, 1 reply; 25+ messages in thread
From: H.J. Lu @ 2019-01-18 20:24 UTC (permalink / raw)
  To: Florian Weimer; +Cc: GNU C Library

On Fri, Jan 18, 2019 at 12:21 PM Florian Weimer <fweimer@redhat.com> wrote:
>
> * H. J. Lu:
>
> > On Fri, Jan 18, 2019 at 11:56 AM Florian Weimer <fweimer@redhat.com> wrote:
> >>
> >> * H. J. Lu:
> >>
> >> > On Fri, Jan 18, 2019 at 2:50 AM Florian Weimer <fweimer@redhat.com> wrote:
> >> >>
> >> >> * H. J. Lu:
> >> >>
> >> >> > On x32, the size_t parameter may be passed in the lower 32 bits of a
> >> >> > 64-bit register with the non-zero upper 32 bits.  The string/memory
> >> >> > functions written in assembly can only use the lower 32 bits of a
> >> >> > 64-bit register as length or must clear the upper 32 bits before using
> >> >> > the full 64-bit register for length.
> >> >> >
> >> >> > This pach fixes string/memory functions written in assembly for x32.
> >> >> > Tested on x86-64 and x32.  On x86-64, libc.so is the same with and
> >> >> > withou the fix.
> >> >>
> >> >> Can this bug result in buffer overflows?  Should we obtain a CVE
> >> >
> >> > Yes, definitely.
> >> >
> >> >> identifier?
> >> >>
> >> >
> >> > Yes, please.  Can you do that for me?
> >>
> >> Done, MITRE gave us CVE-2019-6488.  Please reference this in the
> >> ChangeLog and the commit message if you have not done so.  Please also
> >
> > Done.  I just regenerated and submitted the new patch set.
> >
> >> add short NEWS entry in the security section.  Thanks.
> >>
> >
> > I added:
> >
> >   CVE-2019-6488: On x32, the size_t parameter may be passed in the lower
> >   32 bits of a 64-bit register with the non-zero upper 32 bits.  When
> >   it happens, the string/memory functions written in assembly will cause
> >   buffer overflow if the full 64-bit register is used as the 32-bit
>
> I think we generally describe the faulty behavior in the past tense
> (“When this happen*ed*, the string/memory functions written in assembly
> *would* cause *a* buffer overflow if the full 64-bit register was
> used”).  The first sentence is still current behavior, so it's okay.

Like this?

  CVE-2019-6488: On x32, the size_t parameter may be passed in the lower
  32 bits of a 64-bit register with the non-zero upper 32 bits.  When
  it happened, the string/memory functions written in assembly would
  cause a buffer overflow if the full 64-bit register was used as the
  32-bit size_t value.  Reported by H.J. Lu.

> >   size_t value.  Reported by Florian Weimer.
>
> Huh.  Did I really report this?  When?

It was my misunderstanding.

-- 
H.J.

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

* Re: [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097]
  2019-01-18 20:24           ` H.J. Lu
@ 2019-01-18 20:40             ` Florian Weimer
  2019-01-18 20:47               ` H.J. Lu
  0 siblings, 1 reply; 25+ messages in thread
From: Florian Weimer @ 2019-01-18 20:40 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GNU C Library

* H. J. Lu:

> On Fri, Jan 18, 2019 at 12:21 PM Florian Weimer <fweimer@redhat.com> wrote:
>>
>> * H. J. Lu:
>>
>> > On Fri, Jan 18, 2019 at 11:56 AM Florian Weimer <fweimer@redhat.com> wrote:
>> >>
>> >> * H. J. Lu:
>> >>
>> >> > On Fri, Jan 18, 2019 at 2:50 AM Florian Weimer <fweimer@redhat.com> wrote:
>> >> >>
>> >> >> * H. J. Lu:
>> >> >>
>> >> >> > On x32, the size_t parameter may be passed in the lower 32 bits of a
>> >> >> > 64-bit register with the non-zero upper 32 bits.  The string/memory
>> >> >> > functions written in assembly can only use the lower 32 bits of a
>> >> >> > 64-bit register as length or must clear the upper 32 bits before using
>> >> >> > the full 64-bit register for length.
>> >> >> >
>> >> >> > This pach fixes string/memory functions written in assembly for x32.
>> >> >> > Tested on x86-64 and x32.  On x86-64, libc.so is the same with and
>> >> >> > withou the fix.
>> >> >>
>> >> >> Can this bug result in buffer overflows?  Should we obtain a CVE
>> >> >
>> >> > Yes, definitely.
>> >> >
>> >> >> identifier?
>> >> >>
>> >> >
>> >> > Yes, please.  Can you do that for me?
>> >>
>> >> Done, MITRE gave us CVE-2019-6488.  Please reference this in the
>> >> ChangeLog and the commit message if you have not done so.  Please also
>> >
>> > Done.  I just regenerated and submitted the new patch set.
>> >
>> >> add short NEWS entry in the security section.  Thanks.
>> >>
>> >
>> > I added:
>> >
>> >   CVE-2019-6488: On x32, the size_t parameter may be passed in the lower
>> >   32 bits of a 64-bit register with the non-zero upper 32 bits.  When
>> >   it happens, the string/memory functions written in assembly will cause
>> >   buffer overflow if the full 64-bit register is used as the 32-bit
>>
>> I think we generally describe the faulty behavior in the past tense
>> (“When this happen*ed*, the string/memory functions written in assembly
>> *would* cause *a* buffer overflow if the full 64-bit register was
>> used”).  The first sentence is still current behavior, so it's okay.
>
> Like this?
>
>   CVE-2019-6488: On x32, the size_t parameter may be passed in the lower
>   32 bits of a 64-bit register with the non-zero upper 32 bits.  When

“with non-zero upper 32 bits”

>   it happened, the string/memory functions written in assembly would
>   cause a buffer overflow if the full 64-bit register was used as the

Hmm.  Maybe “because the full”?

>   32-bit size_t value.  Reported by H.J. Lu.

Rest of this descriptions looks okay to me.  (Not a native speaker.)

Thanks,
Florian

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

* Re: [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097]
  2019-01-18 20:40             ` Florian Weimer
@ 2019-01-18 20:47               ` H.J. Lu
  2019-01-19  3:23                 ` Rical Jasan
  0 siblings, 1 reply; 25+ messages in thread
From: H.J. Lu @ 2019-01-18 20:47 UTC (permalink / raw)
  To: Florian Weimer; +Cc: GNU C Library

On Fri, Jan 18, 2019 at 12:40 PM Florian Weimer <fweimer@redhat.com> wrote:
>
> * H. J. Lu:
>
> > On Fri, Jan 18, 2019 at 12:21 PM Florian Weimer <fweimer@redhat.com> wrote:
> >>
> >> * H. J. Lu:
> >>
> >> > On Fri, Jan 18, 2019 at 11:56 AM Florian Weimer <fweimer@redhat.com> wrote:
> >> >>
> >> >> * H. J. Lu:
> >> >>
> >> >> > On Fri, Jan 18, 2019 at 2:50 AM Florian Weimer <fweimer@redhat.com> wrote:
> >> >> >>
> >> >> >> * H. J. Lu:
> >> >> >>
> >> >> >> > On x32, the size_t parameter may be passed in the lower 32 bits of a
> >> >> >> > 64-bit register with the non-zero upper 32 bits.  The string/memory
> >> >> >> > functions written in assembly can only use the lower 32 bits of a
> >> >> >> > 64-bit register as length or must clear the upper 32 bits before using
> >> >> >> > the full 64-bit register for length.
> >> >> >> >
> >> >> >> > This pach fixes string/memory functions written in assembly for x32.
> >> >> >> > Tested on x86-64 and x32.  On x86-64, libc.so is the same with and
> >> >> >> > withou the fix.
> >> >> >>
> >> >> >> Can this bug result in buffer overflows?  Should we obtain a CVE
> >> >> >
> >> >> > Yes, definitely.
> >> >> >
> >> >> >> identifier?
> >> >> >>
> >> >> >
> >> >> > Yes, please.  Can you do that for me?
> >> >>
> >> >> Done, MITRE gave us CVE-2019-6488.  Please reference this in the
> >> >> ChangeLog and the commit message if you have not done so.  Please also
> >> >
> >> > Done.  I just regenerated and submitted the new patch set.
> >> >
> >> >> add short NEWS entry in the security section.  Thanks.
> >> >>
> >> >
> >> > I added:
> >> >
> >> >   CVE-2019-6488: On x32, the size_t parameter may be passed in the lower
> >> >   32 bits of a 64-bit register with the non-zero upper 32 bits.  When
> >> >   it happens, the string/memory functions written in assembly will cause
> >> >   buffer overflow if the full 64-bit register is used as the 32-bit
> >>
> >> I think we generally describe the faulty behavior in the past tense
> >> (“When this happen*ed*, the string/memory functions written in assembly
> >> *would* cause *a* buffer overflow if the full 64-bit register was
> >> used”).  The first sentence is still current behavior, so it's okay.
> >
> > Like this?
> >
> >   CVE-2019-6488: On x32, the size_t parameter may be passed in the lower
> >   32 bits of a 64-bit register with the non-zero upper 32 bits.  When
>
> “with non-zero upper 32 bits”
>
> >   it happened, the string/memory functions written in assembly would
> >   cause a buffer overflow if the full 64-bit register was used as the
>
> Hmm.  Maybe “because the full”?
>
> >   32-bit size_t value.  Reported by H.J. Lu.
>
> Rest of this descriptions looks okay to me.  (Not a native speaker.)
>

Now it has:

  CVE-2019-6488: On x32, the size_t parameter may be passed in the lower
  32 bits of a 64-bit register with with non-zero upper 32 bit.  When it
  happened, the string/memory functions written in assembly would cause a
  buffer overflow because the full 64-bit register was used as the 32-bit
  size_t value.  Reported by H.J. Lu.

Thanks.

-- 
H.J.

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

* Re: [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097]
  2019-01-18 20:47               ` H.J. Lu
@ 2019-01-19  3:23                 ` Rical Jasan
  2019-01-19 10:38                   ` Florian Weimer
  0 siblings, 1 reply; 25+ messages in thread
From: Rical Jasan @ 2019-01-19  3:23 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Florian Weimer, GNU C Library

On 01/18/2019 12:47 PM, H.J. Lu wrote:
> Now it has:
> 
>   CVE-2019-6488: On x32, the size_t parameter may be passed in the lower
>   32 bits of a 64-bit register with with non-zero upper 32 bit.  When it
>   happened, the string/memory functions written in assembly would cause a
>   buffer overflow because the full 64-bit register was used as the 32-bit
>   size_t value.  Reported by H.J. Lu.

How about:

CVE-2019-6488: On x32, the size_t parameter may be passed in the lower
32 bits of a 64-bit register with non-zero upper 32 bits, causing a
buffer overflow in string and memory functions written in assembly when
the full 64-bit register was used as the 32-bit size_t value.

Rical

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

* Re: [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097]
  2019-01-19  3:23                 ` Rical Jasan
@ 2019-01-19 10:38                   ` Florian Weimer
  2019-01-19 15:13                     ` H.J. Lu
  0 siblings, 1 reply; 25+ messages in thread
From: Florian Weimer @ 2019-01-19 10:38 UTC (permalink / raw)
  To: Rical Jasan; +Cc: H.J. Lu, GNU C Library

* Rical Jasan:

> On 01/18/2019 12:47 PM, H.J. Lu wrote:
>> Now it has:
>> 
>>   CVE-2019-6488: On x32, the size_t parameter may be passed in the lower
>>   32 bits of a 64-bit register with with non-zero upper 32 bit.  When it
>>   happened, the string/memory functions written in assembly would cause a
>>   buffer overflow because the full 64-bit register was used as the 32-bit
>>   size_t value.  Reported by H.J. Lu.
>
> How about:
>
> CVE-2019-6488: On x32, the size_t parameter may be passed in the lower
> 32 bits of a 64-bit register with non-zero upper 32 bits, causing a
> buffer overflow in string and memory functions written in assembly when
> the full 64-bit register was used as the 32-bit size_t value.

The problem is not the first part (the undefined upper half of the
register, that's part of the ABI).  It's that the string functions did
not account for this ABI property.

Thanks,
Florian

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

* Re: [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097]
  2019-01-19 10:38                   ` Florian Weimer
@ 2019-01-19 15:13                     ` H.J. Lu
  2019-01-20 15:50                       ` H.J. Lu
  0 siblings, 1 reply; 25+ messages in thread
From: H.J. Lu @ 2019-01-19 15:13 UTC (permalink / raw)
  To: Florian Weimer; +Cc: Rical Jasan, GNU C Library

On Sat, Jan 19, 2019 at 2:38 AM Florian Weimer <fweimer@redhat.com> wrote:
>
> * Rical Jasan:
>
> > On 01/18/2019 12:47 PM, H.J. Lu wrote:
> >> Now it has:
> >>
> >>   CVE-2019-6488: On x32, the size_t parameter may be passed in the lower
> >>   32 bits of a 64-bit register with with non-zero upper 32 bit.  When it
> >>   happened, the string/memory functions written in assembly would cause a
> >>   buffer overflow because the full 64-bit register was used as the 32-bit
> >>   size_t value.  Reported by H.J. Lu.
> >
> > How about:
> >
> > CVE-2019-6488: On x32, the size_t parameter may be passed in the lower
> > 32 bits of a 64-bit register with non-zero upper 32 bits, causing a
> > buffer overflow in string and memory functions written in assembly when
> > the full 64-bit register was used as the 32-bit size_t value.
>
> The problem is not the first part (the undefined upper half of the
> register, that's part of the ABI).  It's that the string functions did
> not account for this ABI property.
>

How about this one?

  CVE-2019-6488: On x32, the size_t parameter may be passed in the lower
  32 bits of a 64-bit register with with non-zero upper 32 bit.  When it
  happened, accessing the 32-bit size_t value as the full 64-bit register
  in the assembly string/memory functions would cause a buffer overflow.
  Reported by H.J. Lu.

-- 
H.J.

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

* Re: [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097]
  2019-01-19 15:13                     ` H.J. Lu
@ 2019-01-20 15:50                       ` H.J. Lu
  0 siblings, 0 replies; 25+ messages in thread
From: H.J. Lu @ 2019-01-20 15:50 UTC (permalink / raw)
  To: Florian Weimer; +Cc: Rical Jasan, GNU C Library

On Sat, Jan 19, 2019 at 7:13 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Sat, Jan 19, 2019 at 2:38 AM Florian Weimer <fweimer@redhat.com> wrote:
> >
> > * Rical Jasan:
> >
> > > On 01/18/2019 12:47 PM, H.J. Lu wrote:
> > >> Now it has:
> > >>
> > >>   CVE-2019-6488: On x32, the size_t parameter may be passed in the lower
> > >>   32 bits of a 64-bit register with with non-zero upper 32 bit.  When it
> > >>   happened, the string/memory functions written in assembly would cause a
> > >>   buffer overflow because the full 64-bit register was used as the 32-bit
> > >>   size_t value.  Reported by H.J. Lu.
> > >
> > > How about:
> > >
> > > CVE-2019-6488: On x32, the size_t parameter may be passed in the lower
> > > 32 bits of a 64-bit register with non-zero upper 32 bits, causing a
> > > buffer overflow in string and memory functions written in assembly when
> > > the full 64-bit register was used as the 32-bit size_t value.
> >
> > The problem is not the first part (the undefined upper half of the
> > register, that's part of the ABI).  It's that the string functions did
> > not account for this ABI property.
> >
>
> How about this one?
>
>   CVE-2019-6488: On x32, the size_t parameter may be passed in the lower
>   32 bits of a 64-bit register with with non-zero upper 32 bit.  When it
>   happened, accessing the 32-bit size_t value as the full 64-bit register
>   in the assembly string/memory functions would cause a buffer overflow.
>   Reported by H.J. Lu.

If there are no objections, I will check in my fixes tomorrow.

-- 
H.J.

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

end of thread, other threads:[~2019-01-20 15:51 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-18 20:12 [PATCH 0/8] x86-64: Properly handle the length parameter [BZ# 24097] H.J. Lu
2019-01-18 20:12 ` [PATCH 1/8] x86-64 memchr/wmemchr: " H.J. Lu
2019-01-18 20:12 ` [PATCH 2/8] x86-64 memcmp/wmemcmp: " H.J. Lu
2019-01-18 20:12 ` [PATCH 3/8] x86-64 memcpy: " H.J. Lu
2019-01-18 20:12 ` [PATCH 4/8] x86-64 memrchr: " H.J. Lu
2019-01-18 20:12 ` [PATCH 5/8] x86-64 memset/wmemset: " H.J. Lu
2019-01-18 20:12 ` [PATCH 6/8] x86-64 strncmp family: " H.J. Lu
2019-01-18 20:12 ` [PATCH 7/8] x86-64 strncpy: " H.J. Lu
2019-01-18 20:12 ` [PATCH 8/8] x86-64 strnlen/wcsnlen: " H.J. Lu
  -- strict thread matches above, loose matches on Subject: below --
2019-01-17 16:53 [PATCH 0/8] x86-64: " H.J. Lu
2019-01-18 10:50 ` Florian Weimer
2019-01-18 13:14   ` H.J. Lu
2019-01-18 13:31     ` Florian Weimer
2019-01-18 13:32       ` H.J. Lu
2019-01-18 19:56     ` Florian Weimer
2019-01-18 20:15       ` H.J. Lu
2019-01-18 20:21         ` Florian Weimer
2019-01-18 20:24           ` H.J. Lu
2019-01-18 20:40             ` Florian Weimer
2019-01-18 20:47               ` H.J. Lu
2019-01-19  3:23                 ` Rical Jasan
2019-01-19 10:38                   ` Florian Weimer
2019-01-19 15:13                     ` H.J. Lu
2019-01-20 15:50                       ` H.J. Lu
2019-01-18 20:15       ` Florian Weimer

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 read-only IMAP folder(s) and NNTP newsgroup(s).