Merge branch release/2.30/master into ibm/2.30/master

This commit is contained in:
Raphael Moreira Zinsly 2021-03-18 18:05:13 -03:00
commit 903f0b6942
14 changed files with 247 additions and 48 deletions

3
NEWS
View File

@ -34,6 +34,7 @@ CVE-2020-29562: An assertion failure has been fixed in the iconv function
The following bugs are resolved with this release: The following bugs are resolved with this release:
[20019] NULL pointer dereference in libc.so.6 IFUNC due to uninitialized GOT
[20543] Please move from .gnu.linkonce to comdat [20543] Please move from .gnu.linkonce to comdat
[23296] Data race in setting function descriptor during lazy binding [23296] Data race in setting function descriptor during lazy binding
[23518] login: Remove utmp backend jump tables [23518] login: Remove utmp backend jump tables
@ -64,6 +65,8 @@ The following bugs are resolved with this release:
[25933] Off by one error in __strncmp_avx2 [25933] Off by one error in __strncmp_avx2
[25966] Incorrect access of __x86_shared_non_temporal_threshold for x32 [25966] Incorrect access of __x86_shared_non_temporal_threshold for x32
[25976] nss_compat: internal_end*ent may clobber errno, hiding ERANGE [25976] nss_compat: internal_end*ent may clobber errno, hiding ERANGE
[27130] "rep movsb" performance issue
[27177] GLIBC_TUNABLES=glibc.cpu.x86_ibt=on:glibc.cpu.x86_shstk=on doesn't work
Version 2.30 Version 2.30

View File

@ -1302,6 +1302,8 @@ CFLAGS-ifuncmain7pie.c += $(pie-ccflag)
CFLAGS-ifuncmain9pie.c += $(pie-ccflag) CFLAGS-ifuncmain9pie.c += $(pie-ccflag)
CFLAGS-tst-ifunc-textrel.c += $(pic-ccflag) CFLAGS-tst-ifunc-textrel.c += $(pic-ccflag)
LDFLAGS-ifuncmain6pie = -Wl,-z,lazy
$(objpfx)ifuncmain1pie: $(objpfx)ifuncmod1.so $(objpfx)ifuncmain1pie: $(objpfx)ifuncmod1.so
$(objpfx)ifuncmain1staticpie: $(objpfx)ifuncdep1pic.o $(objpfx)ifuncmain1staticpie: $(objpfx)ifuncdep1pic.o
$(objpfx)ifuncmain1vispie: $(objpfx)ifuncmod1.so $(objpfx)ifuncmain1vispie: $(objpfx)ifuncmod1.so

View File

@ -9,7 +9,6 @@
#include "ifunc-sel.h" #include "ifunc-sel.h"
typedef int (*foo_p) (void); typedef int (*foo_p) (void);
extern foo_p foo_ptr;
static int static int
one (void) one (void)
@ -28,20 +27,17 @@ foo_ifunc (void)
} }
extern int foo (void); extern int foo (void);
extern foo_p get_foo (void); extern int call_foo (void);
extern foo_p get_foo_p (void); extern foo_p get_foo_p (void);
foo_p my_foo_ptr = foo; foo_p foo_ptr = foo;
int int
main (void) main (void)
{ {
foo_p p; foo_p p;
p = get_foo (); if (call_foo () != -30)
if (p != foo)
abort ();
if ((*p) () != -30)
abort (); abort ();
p = get_foo_p (); p = get_foo_p ();
@ -52,12 +48,8 @@ main (void)
if (foo_ptr != foo) if (foo_ptr != foo)
abort (); abort ();
if (my_foo_ptr != foo)
abort ();
if ((*foo_ptr) () != -30) if ((*foo_ptr) () != -30)
abort (); abort ();
if ((*my_foo_ptr) () != -30)
abort ();
if (foo () != -30) if (foo () != -30)
abort (); abort ();

View File

@ -4,7 +4,7 @@ extern int foo (void);
typedef int (*foo_p) (void); typedef int (*foo_p) (void);
foo_p foo_ptr = foo; extern foo_p foo_ptr;
foo_p foo_p
get_foo_p (void) get_foo_p (void)
@ -12,8 +12,8 @@ get_foo_p (void)
return foo_ptr; return foo_ptr;
} }
foo_p int
get_foo (void) call_foo (void)
{ {
return foo; return foo ();
} }

View File

@ -73,7 +73,7 @@ modules.so := $(addsuffix .so, $(modules))
ifeq (yes,$(build-shared)) ifeq (yes,$(build-shared))
tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \ tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \
tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \ tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \
bug-iconv10 bug-iconv11 bug-iconv12 bug-iconv10 bug-iconv11 bug-iconv12 bug-iconv14
ifeq ($(have-thread-library),yes) ifeq ($(have-thread-library),yes)
tests += bug-iconv3 tests += bug-iconv3
endif endif
@ -316,6 +316,8 @@ $(objpfx)bug-iconv10.out: $(objpfx)gconv-modules \
$(addprefix $(objpfx),$(modules.so)) $(addprefix $(objpfx),$(modules.so))
$(objpfx)bug-iconv12.out: $(objpfx)gconv-modules \ $(objpfx)bug-iconv12.out: $(objpfx)gconv-modules \
$(addprefix $(objpfx),$(modules.so)) $(addprefix $(objpfx),$(modules.so))
$(objpfx)bug-iconv14.out: $(objpfx)gconv-modules \
$(addprefix $(objpfx),$(modules.so))
$(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \ $(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \
$(addprefix $(objpfx),$(modules.so)) \ $(addprefix $(objpfx),$(modules.so)) \

127
iconvdata/bug-iconv14.c Normal file
View File

@ -0,0 +1,127 @@
/* Assertion in ISO-2022-JP-3 due to two-character sequence (bug 27256).
Copyright (C) 2021 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
<https://www.gnu.org/licenses/>. */
#include <iconv.h>
#include <string.h>
#include <errno.h>
#include <support/check.h>
/* Use an escape sequence to return to the initial state. */
static void
with_escape_sequence (void)
{
iconv_t c = iconv_open ("UTF-8", "ISO-2022-JP-3");
TEST_VERIFY_EXIT (c != (iconv_t) -1);
char in[] = "\e$(O+D\e(B";
char *inbuf = in;
size_t inleft = strlen (in);
char out[3]; /* Space for one output character. */
char *outbuf;
size_t outleft;
outbuf = out;
outleft = sizeof (out);
TEST_COMPARE (iconv (c, &inbuf, &inleft, &outbuf, &outleft), (size_t) -1);
TEST_COMPARE (errno, E2BIG);
TEST_COMPARE (inleft, 3);
TEST_COMPARE (inbuf - in, strlen (in) - 3);
TEST_COMPARE (outleft, sizeof (out) - 2);
TEST_COMPARE (outbuf - out, 2);
TEST_COMPARE (out[0] & 0xff, 0xc3);
TEST_COMPARE (out[1] & 0xff, 0xa6);
/* Return to the initial shift state, producing the pending
character. */
outbuf = out;
outleft = sizeof (out);
TEST_COMPARE (iconv (c, &inbuf, &inleft, &outbuf, &outleft), 0);
TEST_COMPARE (inleft, 0);
TEST_COMPARE (inbuf - in, strlen (in));
TEST_COMPARE (outleft, sizeof (out) - 2);
TEST_COMPARE (outbuf - out, 2);
TEST_COMPARE (out[0] & 0xff, 0xcc);
TEST_COMPARE (out[1] & 0xff, 0x80);
/* Nothing should be flushed the second time. */
outbuf = out;
outleft = sizeof (out);
TEST_COMPARE (iconv (c, NULL, 0, &outbuf, &outleft), 0);
TEST_COMPARE (outleft, sizeof (out));
TEST_COMPARE (outbuf - out, 0);
TEST_COMPARE (out[0] & 0xff, 0xcc);
TEST_COMPARE (out[1] & 0xff, 0x80);
TEST_COMPARE (iconv_close (c), 0);
}
/* Use an explicit flush to return to the initial state. */
static void
with_flush (void)
{
iconv_t c = iconv_open ("UTF-8", "ISO-2022-JP-3");
TEST_VERIFY_EXIT (c != (iconv_t) -1);
char in[] = "\e$(O+D";
char *inbuf = in;
size_t inleft = strlen (in);
char out[3]; /* Space for one output character. */
char *outbuf;
size_t outleft;
outbuf = out;
outleft = sizeof (out);
TEST_COMPARE (iconv (c, &inbuf, &inleft, &outbuf, &outleft), (size_t) -1);
TEST_COMPARE (errno, E2BIG);
TEST_COMPARE (inleft, 0);
TEST_COMPARE (inbuf - in, strlen (in));
TEST_COMPARE (outleft, sizeof (out) - 2);
TEST_COMPARE (outbuf - out, 2);
TEST_COMPARE (out[0] & 0xff, 0xc3);
TEST_COMPARE (out[1] & 0xff, 0xa6);
/* Flush the pending character. */
outbuf = out;
outleft = sizeof (out);
TEST_COMPARE (iconv (c, NULL, 0, &outbuf, &outleft), 0);
TEST_COMPARE (outleft, sizeof (out) - 2);
TEST_COMPARE (outbuf - out, 2);
TEST_COMPARE (out[0] & 0xff, 0xcc);
TEST_COMPARE (out[1] & 0xff, 0x80);
/* Nothing should be flushed the second time. */
outbuf = out;
outleft = sizeof (out);
TEST_COMPARE (iconv (c, NULL, 0, &outbuf, &outleft), 0);
TEST_COMPARE (outleft, sizeof (out));
TEST_COMPARE (outbuf - out, 0);
TEST_COMPARE (out[0] & 0xff, 0xcc);
TEST_COMPARE (out[1] & 0xff, 0x80);
TEST_COMPARE (iconv_close (c), 0);
}
static int
do_test (void)
{
with_escape_sequence ();
with_flush ();
return 0;
}
#include <support/test-driver.c>

View File

@ -67,23 +67,34 @@ enum
CURRENT_SEL_MASK = 7 << 3 CURRENT_SEL_MASK = 7 << 3
}; };
/* During UCS-4 to ISO-2022-JP-3 conversion, the COUNT element of the state /* During UCS-4 to ISO-2022-JP-3 conversion, the COUNT element of the
also contains the last two bytes to be output, shifted by 6 bits, and a state also contains the last two bytes to be output, shifted by 6
one-bit indicator whether they must be preceded by the shift sequence, bits, and a one-bit indicator whether they must be preceded by the
in bit 22. */ shift sequence, in bit 22. During ISO-2022-JP-3 to UCS-4
conversion, COUNT may also contain a non-zero pending wide
character, shifted by six bits. This happens for certain inputs in
JISX0213_1_2004_set and JISX0213_2_set if the second wide character
in a combining sequence cannot be written because the buffer is
full. */
/* Since this is a stateful encoding we have to provide code which resets /* Since this is a stateful encoding we have to provide code which resets
the output state to the initial state. This has to be done during the the output state to the initial state. This has to be done during the
flushing. */ flushing. */
#define EMIT_SHIFT_TO_INIT \ #define EMIT_SHIFT_TO_INIT \
if ((data->__statep->__count & ~7) != ASCII_set) \ if (data->__statep->__count != ASCII_set) \
{ \ { \
if (FROM_DIRECTION) \ if (FROM_DIRECTION) \
{ \ { \
/* It's easy, we don't have to emit anything, we just reset the \ if (__glibc_likely (outbuf + 4 <= outend)) \
state for the input. */ \ { \
data->__statep->__count &= 7; \ /* Write out the last character. */ \
data->__statep->__count |= ASCII_set; \ *((uint32_t *) outbuf) = data->__statep->__count >> 6; \
outbuf += sizeof (uint32_t); \
data->__statep->__count = ASCII_set; \
} \
else \
/* We don't have enough room in the output buffer. */ \
status = __GCONV_FULL_OUTPUT; \
} \ } \
else \ else \
{ \ { \
@ -151,7 +162,21 @@ enum
#define LOOPFCT FROM_LOOP #define LOOPFCT FROM_LOOP
#define BODY \ #define BODY \
{ \ { \
uint32_t ch = *inptr; \ uint32_t ch; \
\
/* Output any pending character. */ \
ch = set >> 6; \
if (__glibc_unlikely (ch != 0)) \
{ \
put32 (outptr, ch); \
outptr += 4; \
/* Remove the pending character, but preserve state bits. */ \
set &= (1 << 6) - 1; \
continue; \
} \
\
/* Otherwise read the next input byte. */ \
ch = *inptr; \
\ \
/* Recognize escape sequences. */ \ /* Recognize escape sequences. */ \
if (__glibc_unlikely (ch == ESC)) \ if (__glibc_unlikely (ch == ESC)) \
@ -297,21 +322,25 @@ enum
uint32_t u1 = __jisx0213_to_ucs_combining[ch - 1][0]; \ uint32_t u1 = __jisx0213_to_ucs_combining[ch - 1][0]; \
uint32_t u2 = __jisx0213_to_ucs_combining[ch - 1][1]; \ uint32_t u2 = __jisx0213_to_ucs_combining[ch - 1][1]; \
\ \
inptr += 2; \
\
put32 (outptr, u1); \
outptr += 4; \
\
/* See whether we have room for two characters. */ \ /* See whether we have room for two characters. */ \
if (outptr + 8 <= outend) \ if (outptr + 4 <= outend) \
{ \ { \
inptr += 2; \
put32 (outptr, u1); \
outptr += 4; \
put32 (outptr, u2); \ put32 (outptr, u2); \
outptr += 4; \ outptr += 4; \
continue; \ continue; \
} \ } \
else \ \
{ \ /* Otherwise store only the first character now, and \
result = __GCONV_FULL_OUTPUT; \ put the second one into the queue. */ \
break; \ set |= u2 << 6; \
} \ /* Tell the caller why we terminate the loop. */ \
result = __GCONV_FULL_OUTPUT; \
break; \
} \ } \
\ \
inptr += 2; \ inptr += 2; \

View File

@ -248,7 +248,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
: NULL); : NULL);
ndomain = (ndomain ? newbuf + ndomaindiff ndomain = (ndomain ? newbuf + ndomaindiff
: NULL); : NULL);
buffer = newbuf; *tofreep = buffer = newbuf;
} }
nhost = memcpy (buffer + bufused, nhost = memcpy (buffer + bufused,
@ -319,7 +319,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
else if (status == NSS_STATUS_TRYAGAIN && e == ERANGE) else if (status == NSS_STATUS_TRYAGAIN && e == ERANGE)
{ {
buflen *= 2; buflen *= 2;
buffer = xrealloc (buffer, buflen); *tofreep = buffer = xrealloc (buffer, buflen);
} }
else if (status == NSS_STATUS_RETURN else if (status == NSS_STATUS_RETURN
|| status == NSS_STATUS_NOTFOUND || status == NSS_STATUS_NOTFOUND

View File

@ -338,16 +338,22 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
{ {
# ifndef RTLD_BOOTSTRAP # ifndef RTLD_BOOTSTRAP
if (sym_map != map if (sym_map != map
&& sym_map->l_type != lt_executable
&& !sym_map->l_relocated) && !sym_map->l_relocated)
{ {
const char *strtab const char *strtab
= (const char *) D_PTR (map, l_info[DT_STRTAB]); = (const char *) D_PTR (map, l_info[DT_STRTAB]);
_dl_error_printf ("\ if (sym_map->l_type == lt_executable)
_dl_fatal_printf ("\
%s: IFUNC symbol '%s' referenced in '%s' is defined in the executable \
and creates an unsatisfiable circular dependency.\n",
RTLD_PROGNAME, strtab + refsym->st_name,
map->l_name);
else
_dl_error_printf ("\
%s: Relink `%s' with `%s' for IFUNC symbol `%s'\n", %s: Relink `%s' with `%s' for IFUNC symbol `%s'\n",
RTLD_PROGNAME, map->l_name, RTLD_PROGNAME, map->l_name,
sym_map->l_name, sym_map->l_name,
strtab + refsym->st_name); strtab + refsym->st_name);
} }
# endif # endif
value = ((Elf32_Addr (*) (void)) value) (); value = ((Elf32_Addr (*) (void)) value) ();

View File

@ -12,6 +12,12 @@ endif
ifeq ($(subdir),setjmp) ifeq ($(subdir),setjmp)
gen-as-const-headers += jmp_buf-ssp.sym gen-as-const-headers += jmp_buf-ssp.sym
sysdep_routines += __longjmp_cancel sysdep_routines += __longjmp_cancel
ifneq ($(enable-cet),no)
ifneq ($(have-tunables),no)
tests += tst-setjmp-cet
tst-setjmp-cet-ENV = GLIBC_TUNABLES=glibc.cpu.x86_ibt=on:glibc.cpu.x86_shstk=on
endif
endif
endif endif
ifeq ($(enable-cet),yes) ifeq ($(enable-cet),yes)

View File

@ -105,7 +105,11 @@ dl_cet_check (struct link_map *m, const char *program)
/* No legacy object check if both IBT and SHSTK are always on. */ /* No legacy object check if both IBT and SHSTK are always on. */
if (enable_ibt_type == CET_ALWAYS_ON if (enable_ibt_type == CET_ALWAYS_ON
&& enable_shstk_type == CET_ALWAYS_ON) && enable_shstk_type == CET_ALWAYS_ON)
return; {
THREAD_SETMEM (THREAD_SELF, header.feature_1,
GL(dl_x86_feature_1)[0]);
return;
}
/* Check if IBT is enabled by kernel. */ /* Check if IBT is enabled by kernel. */
bool ibt_enabled bool ibt_enabled

View File

@ -0,0 +1 @@
#include <setjmp/tst-setjmp.c>

View File

@ -315,16 +315,22 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
{ {
# ifndef RTLD_BOOTSTRAP # ifndef RTLD_BOOTSTRAP
if (sym_map != map if (sym_map != map
&& sym_map->l_type != lt_executable
&& !sym_map->l_relocated) && !sym_map->l_relocated)
{ {
const char *strtab const char *strtab
= (const char *) D_PTR (map, l_info[DT_STRTAB]); = (const char *) D_PTR (map, l_info[DT_STRTAB]);
_dl_error_printf ("\ if (sym_map->l_type == lt_executable)
_dl_fatal_printf ("\
%s: IFUNC symbol '%s' referenced in '%s' is defined in the executable \
and creates an unsatisfiable circular dependency.\n",
RTLD_PROGNAME, strtab + refsym->st_name,
map->l_name);
else
_dl_error_printf ("\
%s: Relink `%s' with `%s' for IFUNC symbol `%s'\n", %s: Relink `%s' with `%s' for IFUNC symbol `%s'\n",
RTLD_PROGNAME, map->l_name, RTLD_PROGNAME, map->l_name,
sym_map->l_name, sym_map->l_name,
strtab + refsym->st_name); strtab + refsym->st_name);
} }
# endif # endif
value = ((ElfW(Addr) (*) (void)) value) (); value = ((ElfW(Addr) (*) (void)) value) ();

View File

@ -67,6 +67,13 @@
# define REP_MOVSB_THRESHOLD (2048 * (VEC_SIZE / 16)) # define REP_MOVSB_THRESHOLD (2048 * (VEC_SIZE / 16))
#endif #endif
/* Avoid short distance rep movsb only with non-SSE vector. */
#ifndef AVOID_SHORT_DISTANCE_REP_MOVSB
# define AVOID_SHORT_DISTANCE_REP_MOVSB (VEC_SIZE > 16)
#else
# define AVOID_SHORT_DISTANCE_REP_MOVSB 0
#endif
#ifndef PREFETCH #ifndef PREFETCH
# define PREFETCH(addr) prefetcht0 addr # define PREFETCH(addr) prefetcht0 addr
#endif #endif
@ -257,7 +264,21 @@ L(movsb):
# error Unsupported REP_MOVSB_THRESHOLD and VEC_SIZE! # error Unsupported REP_MOVSB_THRESHOLD and VEC_SIZE!
# endif # endif
jb L(more_8x_vec_backward) jb L(more_8x_vec_backward)
# if AVOID_SHORT_DISTANCE_REP_MOVSB
movq %rdi, %rcx
subq %rsi, %rcx
jmp 2f
# endif
1: 1:
# if AVOID_SHORT_DISTANCE_REP_MOVSB
movq %rsi, %rcx
subq %rdi, %rcx
2:
/* Avoid "rep movsb" if RCX, the distance between source and destination,
is N*4GB + [1..63] with N >= 0. */
cmpl $63, %ecx
jbe L(more_2x_vec) /* Avoid "rep movsb" if ECX <= 63. */
# endif
mov %RDX_LP, %RCX_LP mov %RDX_LP, %RCX_LP
rep movsb rep movsb
L(nop): L(nop):