Accepting request 958082 from Base:System

- get-nprocs-sched-uninit-read.patch: linux: __get_nprocs_sched: do not
  feed CPU_COUNT_S with garbage (BZ #28850)
- get-nprocs-inaccurate.patch: linux: fix accuracy of get_nprocs and
  get_nprocs_conf (BZ #28865)
- strcmp-rtm-fallback.path: x86: Fallback {str|wcs}cmp RTM in the ncmp
  overflow case (BZ #28896)
- pt-load-invalid-hole.patch: elf: Check invalid hole in PT_LOAD segments
  (BZ #28838)
- localedef-ld-monetary.patch: localedef: Update LC_MONETARY handling (BZ
  #28845) (forwarded request 958081 from Andreas_Schwab)

OBS-URL: https://build.opensuse.org/request/show/958082
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/glibc?expand=0&rev=258
This commit is contained in:
Dominique Leuenberger 2022-03-02 17:20:01 +00:00 committed by Git OBS Bridge
commit 44ce94d869
7 changed files with 746 additions and 0 deletions

199
get-nprocs-inaccurate.patch Normal file
View File

@ -0,0 +1,199 @@
From 491f2ef1f0ff849490f374917957018d07ee0586 Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@altlinux.org>
Date: Sat, 5 Feb 2022 08:00:00 +0000
Subject: [PATCH] linux: fix accuracy of get_nprocs and get_nprocs_conf [BZ
#28865]
get_nprocs() and get_nprocs_conf() use various methods to obtain an
accurate number of processors. Re-introduce __get_nprocs_sched() as
a source of information, and fix the order in which these methods are
used to return the most accurate information. The primary source of
information used in both functions remains unchanged.
This also changes __get_nprocs_sched() error return value from 2 to 0,
but all its users are already prepared to handle that.
Old fallback order:
get_nprocs:
/sys/devices/system/cpu/online -> /proc/stat -> 2
get_nprocs_conf:
/sys/devices/system/cpu/ -> /proc/stat -> 2
New fallback order:
get_nprocs:
/sys/devices/system/cpu/online -> /proc/stat -> sched_getaffinity -> 2
get_nprocs_conf:
/sys/devices/system/cpu/ -> /proc/stat -> sched_getaffinity -> 2
Fixes: 342298278e ("linux: Revert the use of sched_getaffinity on get_nproc")
Closes: BZ #28865
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
(cherry picked from commit e1d32b836410767270a3adf1f82b1a47e6e4cd51)
---
NEWS | 2 +
sysdeps/unix/sysv/linux/getsysstats.c | 94 ++++++++++++++++++---------
2 files changed, 65 insertions(+), 31 deletions(-)
diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c
index c98c8ce3d4..d1ea074f0d 100644
--- a/sysdeps/unix/sysv/linux/getsysstats.c
+++ b/sysdeps/unix/sysv/linux/getsysstats.c
@@ -50,9 +50,8 @@ __get_nprocs_sched (void)
is an arbitrary values assuming such systems should be rare and there
is no offline cpus. */
return max_num_cpus;
- /* Some other error. 2 is conservative (not a uniprocessor system, so
- atomics are needed). */
- return 2;
+ /* Some other error. */
+ return 0;
}
static char *
@@ -108,22 +107,19 @@ next_line (int fd, char *const buffer, char **cp, char **re,
}
static int
-get_nproc_stat (char *buffer, size_t buffer_size)
+get_nproc_stat (void)
{
+ enum { buffer_size = 1024 };
+ char buffer[buffer_size];
char *buffer_end = buffer + buffer_size;
char *cp = buffer_end;
char *re = buffer_end;
-
- /* Default to an SMP system in case we cannot obtain an accurate
- number. */
- int result = 2;
+ int result = 0;
const int flags = O_RDONLY | O_CLOEXEC;
int fd = __open_nocancel ("/proc/stat", flags);
if (fd != -1)
{
- result = 0;
-
char *l;
while ((l = next_line (fd, buffer, &cp, &re, buffer_end)) != NULL)
/* The current format of /proc/stat has all the cpu* entries
@@ -139,8 +135,8 @@ get_nproc_stat (char *buffer, size_t buffer_size)
return result;
}
-int
-__get_nprocs (void)
+static int
+get_nprocs_cpu_online (void)
{
enum { buffer_size = 1024 };
char buffer[buffer_size];
@@ -179,7 +175,8 @@ __get_nprocs (void)
}
}
- result += m - n + 1;
+ if (m >= n)
+ result += m - n + 1;
l = endp;
if (l < re && *l == ',')
@@ -188,28 +185,18 @@ __get_nprocs (void)
while (l < re && *l != '\n');
__close_nocancel_nostatus (fd);
-
- if (result > 0)
- return result;
}
- return get_nproc_stat (buffer, buffer_size);
+ return result;
}
-libc_hidden_def (__get_nprocs)
-weak_alias (__get_nprocs, get_nprocs)
-
-/* On some architectures it is possible to distinguish between configured
- and active cpus. */
-int
-__get_nprocs_conf (void)
+static int
+get_nprocs_cpu (void)
{
- /* Try to use the sysfs filesystem. It has actual information about
- online processors. */
+ int count = 0;
DIR *dir = __opendir ("/sys/devices/system/cpu");
if (dir != NULL)
{
- int count = 0;
struct dirent64 *d;
while ((d = __readdir64 (dir)) != NULL)
@@ -224,12 +211,57 @@ __get_nprocs_conf (void)
__closedir (dir);
- return count;
}
+ return count;
+}
- enum { buffer_size = 1024 };
- char buffer[buffer_size];
- return get_nproc_stat (buffer, buffer_size);
+static int
+get_nprocs_fallback (void)
+{
+ int result;
+
+ /* Try /proc/stat first. */
+ result = get_nproc_stat ();
+ if (result != 0)
+ return result;
+
+ /* Try sched_getaffinity. */
+ result = __get_nprocs_sched ();
+ if (result != 0)
+ return result;
+
+ /* We failed to obtain an accurate number. Be conservative: return
+ the smallest number meaning that this is not a uniprocessor system,
+ so atomics are needed. */
+ return 2;
+}
+
+int
+__get_nprocs (void)
+{
+ /* Try /sys/devices/system/cpu/online first. */
+ int result = get_nprocs_cpu_online ();
+ if (result != 0)
+ return result;
+
+ /* Fall back to /proc/stat and sched_getaffinity. */
+ return get_nprocs_fallback ();
+}
+libc_hidden_def (__get_nprocs)
+weak_alias (__get_nprocs, get_nprocs)
+
+/* On some architectures it is possible to distinguish between configured
+ and active cpus. */
+int
+__get_nprocs_conf (void)
+{
+ /* Try /sys/devices/system/cpu/ first. */
+ int result = get_nprocs_cpu ();
+ if (result != 0)
+ return result;
+
+ /* Fall back to /proc/stat and sched_getaffinity. */
+ return get_nprocs_fallback ();
}
libc_hidden_def (__get_nprocs_conf)
weak_alias (__get_nprocs_conf, get_nprocs_conf)
--
2.35.0

View File

@ -0,0 +1,33 @@
From a2f1675634b3513c09c38e55e6766e8c05768b1f Mon Sep 17 00:00:00 2001
From: Gleb Fotengauer-Malinovskiy <glebfm@altlinux.org>
Date: Tue, 1 Feb 2022 22:39:02 +0000
Subject: [PATCH] linux: __get_nprocs_sched: do not feed CPU_COUNT_S with
garbage [BZ #28850]
Pass the actual number of bytes returned by the kernel.
Fixes: 33099d72e41c ("linux: Simplify get_nprocs")
Reviewed-by: Dmitry V. Levin <ldv@altlinux.org>
(cherry picked from commit 97ba273b505763325efd802dc3a9562dbba79579)
---
NEWS | 1 +
sysdeps/unix/sysv/linux/getsysstats.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c
index 4798cc337e..c98c8ce3d4 100644
--- a/sysdeps/unix/sysv/linux/getsysstats.c
+++ b/sysdeps/unix/sysv/linux/getsysstats.c
@@ -44,7 +44,7 @@ __get_nprocs_sched (void)
int r = INTERNAL_SYSCALL_CALL (sched_getaffinity, 0, cpu_bits_size,
cpu_bits);
if (r > 0)
- return CPU_COUNT_S (cpu_bits_size, (cpu_set_t*) cpu_bits);
+ return CPU_COUNT_S (r, (cpu_set_t*) cpu_bits);
else if (r == -EINVAL)
/* The input buffer is still not enough to store the number of cpus. This
is an arbitrary values assuming such systems should be rare and there
--
2.35.0

View File

@ -1,3 +1,17 @@
-------------------------------------------------------------------
Mon Feb 28 10:51:19 UTC 2022 - Andreas Schwab <schwab@suse.de>
- get-nprocs-sched-uninit-read.patch: linux: __get_nprocs_sched: do not
feed CPU_COUNT_S with garbage (BZ #28850)
- get-nprocs-inaccurate.patch: linux: fix accuracy of get_nprocs and
get_nprocs_conf (BZ #28865)
- strcmp-rtm-fallback.path: x86: Fallback {str|wcs}cmp RTM in the ncmp
overflow case (BZ #28896)
- pt-load-invalid-hole.patch: elf: Check invalid hole in PT_LOAD segments
(BZ #28838)
- localedef-ld-monetary.patch: localedef: Update LC_MONETARY handling (BZ
#28845)
-------------------------------------------------------------------
Thu Feb 3 11:52:01 UTC 2022 - Andreas Schwab <schwab@suse.de>

View File

@ -283,6 +283,16 @@ Patch306: glibc-fix-double-loopback.diff
###
# Patches from upstream
###
# PATCH-FIX-OPENSUSE linux: __get_nprocs_sched: do not feed CPU_COUNT_S with garbage (BZ #28850)
Patch1000: get-nprocs-sched-uninit-read.patch
# PATCH-FIX-OPENSUSE linux: fix accuracy of get_nprocs and get_nprocs_conf (BZ #28865)
Patch1001: get-nprocs-inaccurate.patch
# PATCH-FIX-OPENSUSE x86: Fallback {str|wcs}cmp RTM in the ncmp overflow case (BZ #28896)
Patch1002: strcmp-rtm-fallback.path
# PATCH-FIX-OPENSUSE elf: Check invalid hole in PT_LOAD segments (BZ #28838)
Patch1003: pt-load-invalid-hole.patch
# PATCH-FIX-OPENSUSE localedef: Update LC_MONETARY handling (BZ #28845)
Patch1004: localedef-ld-monetary.patch
###
# Patches awaiting upstream approval
@ -502,6 +512,12 @@ library in a cross compilation setting.
%patch304 -p1
%patch306 -p1
%patch1000 -p1
%patch1001 -p1
%patch1002 -p1
%patch1003 -p1
%patch1004 -p1
%patch2000 -p1
%patch2001 -p1

302
localedef-ld-monetary.patch Normal file
View File

@ -0,0 +1,302 @@
From 3feecd80013c822a12d4b01c5c25e155dfbc6e2f Mon Sep 17 00:00:00 2001
From: Carlos O'Donell <carlos@redhat.com>
Date: Thu, 3 Feb 2022 16:51:59 -0500
Subject: [PATCH] localedef: Update LC_MONETARY handling (Bug 28845)
ISO C17, POSIX Issue 7, and ISO 30112 all allow the char*
types to be empty strings i.e. "", integer or char values to
be -1 or CHAR_MAX respectively, with the exception of
decimal_point which must be non-empty in ISO C. Note that
the defaults for mon_grouping vary, but are functionaly
equivalent e.g. "\177" (no further grouping reuqired) vs.
"" (no grouping defined for all groups).
We include a broad comment talking about harmonizing ISO C,
POSIX, ISO 30112, and the default C/POSIX locale for glibc.
We reorder all setting based on locale/categories.def order.
We soften all missing definitions from errors to warnings when
defaults exist.
Given that ISO C, POSIX and ISO 30112 allow the empty string
we change LC_MONETARY handling of mon_decimal_point to allow
the empty string. If mon_decimal_point is not defined at all
then we pick the existing legacy glibc default value of
<U002E> i.e. ".".
We also set the default for mon_thousands_sep_wc at the
same time as mon_thousands_sep, but this is not a change in
behaviour, it is always either a matching value or L'\0',
but if in the future we change the default to a non-empty
string we would need to update both at the same time.
Tested on x86_64 and i686 without regressions.
Tested with install-locale-archive target.
Tested with install-locale-files target.
Reviewed-by: DJ Delorie <dj@redhat.com>
(cherry picked from commit 2ab8b74567dc0a9a3c98696e6444881997dd6c49)
---
locale/programs/ld-monetary.c | 182 +++++++++++++++++++++++++++-------
1 file changed, 146 insertions(+), 36 deletions(-)
diff --git a/locale/programs/ld-monetary.c b/locale/programs/ld-monetary.c
index 3b0412b405..18698bbe94 100644
--- a/locale/programs/ld-monetary.c
+++ b/locale/programs/ld-monetary.c
@@ -196,21 +196,105 @@ No definition for %s category found"), "LC_MONETARY");
}
}
+ /* Generally speaking there are 3 standards the define the default,
+ warning, and error behaviour of LC_MONETARY. They are ISO/IEC TR 30112,
+ ISO/IEC 9899:2018 (ISO C17), and POSIX.1-2017. Within 30112 we have the
+ definition of a standard i18n FDCC-set, which for LC_MONETARY has the
+ following default values:
+ int_curr_symbol ""
+ currency_symbol ""
+ mon_decimal_point "<U002C>" i.e. ","
+ mon_thousand_sep ""
+ mon_grouping "\177" i.e. CHAR_MAX
+ positive_sign ""
+ negative_sign "<U002E>" i.e. "."
+ int_frac_digits -1
+ frac_digits -1
+ p_cs_precedes -1
+ p_sep_by_space -1
+ n_cs_precedes -1
+ n_sep_by_space -1
+ p_sign_posn -1
+ n_sign_posn -1
+ Under 30112 a keyword that is not provided implies an empty string ""
+ for string values or a -1 for integer values, and indicates the value
+ is unspecified with no default implied. No errors are considered.
+ The exception is mon_grouping which is a string with a terminating
+ CHAR_MAX.
+ For POSIX Issue 7 we have:
+ https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html
+ and again values not provided default to "" or -1, and indicate the value
+ is not available to the locale. The exception is mon_grouping which is
+ a string with a terminating CHAR_MAX. For the POSIX locale the values of
+ LC_MONETARY should be:
+ int_curr_symbol ""
+ currency_symbol ""
+ mon_decimal_point ""
+ mon_thousands_sep ""
+ mon_grouping "\177" i.e. CHAR_MAX
+ positive_sign ""
+ negative_sign ""
+ int_frac_digits -1
+ frac_digits -1
+ p_cs_precedes -1
+ p_sep_by_space -1
+ n_cs_precedes -1
+ n_sep_by_space -1
+ p_sign_posn -1
+ n_sign_posn -1
+ int_p_cs_precedes -1
+ int_p_sep_by_space -1
+ int_n_cs_precedes -1
+ int_n_sep_by_space -1
+ int_p_sign_posn -1
+ int_n_sign_posn -1
+ Like with 30112, POSIX also considers no error if the keywords are
+ missing, only that if the cateory as a whole is missing the referencing
+ of the category results in unspecified behaviour.
+ For ISO C17 there is no default value provided, but the localeconv
+ specification in 7.11.2.1 admits that members of char * type may point
+ to "" to indicate a value is not available or is of length zero.
+ The exception is decimal_point (not mon_decimal_point) which must be a
+ defined non-empty string. The values of char, which are generally
+ mapped to integer values in 30112 and POSIX, must be non-negative
+ numbers that map to CHAR_MAX when a value is not available in the
+ locale.
+ In ISO C17 for the "C" locale all values are empty strings "", or
+ CHAR_MAX, with the exception of decimal_point which is "." (defined
+ in LC_NUMERIC). ISO C17 makes no exception for mon_grouping like
+ 30112 and POSIX, but a value of "" is functionally equivalent to
+ "\177" since neither defines a grouping (though the latter terminates
+ the grouping).
+
+ Lastly, we must consider the legacy C/POSIX locale that implemented
+ as a builtin in glibc and wether a default value mapping to the
+ C/POSIX locale may benefit the user from a compatibility perspective.
+
+ Thus given 30112, POSIX, ISO C, and the builtin C/POSIX locale we
+ need to pick appropriate defaults below. */
+
+ /* The members of LC_MONETARY are handled in the order of their definition
+ in locale/categories.def. Please keep them in that order. */
+
+ /* The purpose of TEST_ELEM is to define a default value for the fields
+ in the category if the field was not defined in the cateory. If the
+ category was present but we didn't see a definition for the field then
+ we also issue a warning, otherwise the only warning you get is the one
+ earlier when a default category is created (completely missing category).
+ This missing field warning is glibc-specific since no standard requires
+ this warning, but we consider it valuable to print a warning for all
+ missing fields in the category. */
#define TEST_ELEM(cat, initval) \
if (monetary->cat == NULL) \
{ \
if (! nothing) \
- record_error (0, 0, _("%s: field `%s' not defined"), \
- "LC_MONETARY", #cat); \
+ record_warning (_("%s: field `%s' not defined"), \
+ "LC_MONETARY", #cat); \
monetary->cat = initval; \
}
+ /* Keyword: int_curr_symbol. */
TEST_ELEM (int_curr_symbol, "");
- TEST_ELEM (currency_symbol, "");
- TEST_ELEM (mon_thousands_sep, "");
- TEST_ELEM (positive_sign, "");
- TEST_ELEM (negative_sign, "");
-
/* The international currency symbol must come from ISO 4217. */
if (monetary->int_curr_symbol != NULL)
{
@@ -247,41 +331,63 @@ not correspond to a valid name in ISO 4217 [--no-warnings=intcurrsym]"),
}
}
- /* The decimal point must not be empty. This is not said explicitly
- in POSIX but ANSI C (ISO/IEC 9899) says in 4.4.2.1 it has to be
- != "". */
+ /* Keyword: currency_symbol */
+ TEST_ELEM (currency_symbol, "");
+
+ /* Keyword: mon_decimal_point */
+ /* ISO C17 7.11.2.1.3 explicitly allows mon_decimal_point to be the
+ empty string e.g. "". This indicates the value is not available in the
+ current locale or is of zero length. However, if the value was never
+ defined then we issue a warning and use a glibc-specific default. ISO
+ 30112 in the i18n FDCC-Set uses <U002C> ",", and POSIX Issue 7 in the
+ POSIX locale uses "". It is specific to glibc that the default is <U002E>
+ "."; we retain this existing behaviour for backwards compatibility. */
if (monetary->mon_decimal_point == NULL)
{
if (! nothing)
- record_error (0, 0, _("%s: field `%s' not defined"),
- "LC_MONETARY", "mon_decimal_point");
+ record_warning (_("%s: field `%s' not defined, using defaults"),
+ "LC_MONETARY", "mon_decimal_point");
monetary->mon_decimal_point = ".";
monetary->mon_decimal_point_wc = L'.';
}
- else if (monetary->mon_decimal_point[0] == '\0' && ! be_quiet && ! nothing)
+
+ /* Keyword: mon_thousands_sep */
+ if (monetary->mon_thousands_sep == NULL)
{
- record_error (0, 0, _("\
-%s: value for field `%s' must not be an empty string"),
- "LC_MONETARY", "mon_decimal_point");
+ if (! nothing)
+ record_warning (_("%s: field `%s' not defined, using defaults"),
+ "LC_MONETARY", "mon_thousands_sep");
+ monetary->mon_thousands_sep = "";
+ monetary->mon_thousands_sep_wc = L'\0';
}
+ /* Keyword: mon_grouping */
if (monetary->mon_grouping_len == 0)
{
if (! nothing)
- record_error (0, 0, _("%s: field `%s' not defined"),
- "LC_MONETARY", "mon_grouping");
-
+ record_warning (_("%s: field `%s' not defined"),
+ "LC_MONETARY", "mon_grouping");
+ /* Missing entries are given 1 element in their bytearray with
+ a value of CHAR_MAX which indicates that "No further grouping
+ is to be performed" (functionally equivalent to ISO C's "C"
+ locale default of ""). */
monetary->mon_grouping = (char *) "\177";
monetary->mon_grouping_len = 1;
}
+ /* Keyword: positive_sign */
+ TEST_ELEM (positive_sign, "");
+
+ /* Keyword: negative_sign */
+ TEST_ELEM (negative_sign, "");
+
#undef TEST_ELEM
#define TEST_ELEM(cat, min, max, initval) \
if (monetary->cat == -2) \
{ \
if (! nothing) \
- record_error (0, 0, _("%s: field `%s' not defined"), \
- "LC_MONETARY", #cat); \
+ record_warning (_("%s: field `%s' not defined"), \
+ "LC_MONETARY", #cat); \
monetary->cat = initval; \
} \
else if ((monetary->cat < min || monetary->cat > max) \
@@ -300,16 +406,11 @@ not correspond to a valid name in ISO 4217 [--no-warnings=intcurrsym]"),
TEST_ELEM (p_sign_posn, -1, 4, -1);
TEST_ELEM (n_sign_posn, -1, 4, -1);
- /* The non-POSIX.2 extensions are optional. */
- if (monetary->duo_int_curr_symbol == NULL)
- monetary->duo_int_curr_symbol = monetary->int_curr_symbol;
- if (monetary->duo_currency_symbol == NULL)
- monetary->duo_currency_symbol = monetary->currency_symbol;
-
- if (monetary->duo_int_frac_digits == -2)
- monetary->duo_int_frac_digits = monetary->int_frac_digits;
- if (monetary->duo_frac_digits == -2)
- monetary->duo_frac_digits = monetary->frac_digits;
+ /* Keyword: crncystr */
+ monetary->crncystr = (char *) xmalloc (strlen (monetary->currency_symbol)
+ + 2);
+ monetary->crncystr[0] = monetary->p_cs_precedes ? '-' : '+';
+ strcpy (&monetary->crncystr[1], monetary->currency_symbol);
#undef TEST_ELEM
#define TEST_ELEM(cat, alt, min, max) \
@@ -327,6 +428,17 @@ not correspond to a valid name in ISO 4217 [--no-warnings=intcurrsym]"),
TEST_ELEM (int_p_sign_posn, p_sign_posn, -1, 4);
TEST_ELEM (int_n_sign_posn, n_sign_posn, -1, 4);
+ /* The non-POSIX.2 extensions are optional. */
+ if (monetary->duo_int_curr_symbol == NULL)
+ monetary->duo_int_curr_symbol = monetary->int_curr_symbol;
+ if (monetary->duo_currency_symbol == NULL)
+ monetary->duo_currency_symbol = monetary->currency_symbol;
+
+ if (monetary->duo_int_frac_digits == -2)
+ monetary->duo_int_frac_digits = monetary->int_frac_digits;
+ if (monetary->duo_frac_digits == -2)
+ monetary->duo_frac_digits = monetary->frac_digits;
+
TEST_ELEM (duo_p_cs_precedes, p_cs_precedes, -1, 1);
TEST_ELEM (duo_p_sep_by_space, p_sep_by_space, -1, 2);
TEST_ELEM (duo_n_cs_precedes, n_cs_precedes, -1, 1);
@@ -349,17 +461,15 @@ not correspond to a valid name in ISO 4217 [--no-warnings=intcurrsym]"),
if (monetary->duo_valid_to == 0)
monetary->duo_valid_to = 99991231;
+ /* Keyword: conversion_rate */
if (monetary->conversion_rate[0] == 0)
{
monetary->conversion_rate[0] = 1;
monetary->conversion_rate[1] = 1;
}
- /* Create the crncystr entry. */
- monetary->crncystr = (char *) xmalloc (strlen (monetary->currency_symbol)
- + 2);
- monetary->crncystr[0] = monetary->p_cs_precedes ? '-' : '+';
- strcpy (&monetary->crncystr[1], monetary->currency_symbol);
+ /* A value for monetary-decimal-point-wc was set when
+ monetary_decimal_point was set, likewise for monetary-thousands-sep-wc. */
}
--
2.35.0

View File

@ -0,0 +1,50 @@
From 1dd783fafdbc30bd82e078ccab42b9539d3274a5 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Tue, 15 Feb 2022 06:57:11 -0800
Subject: [PATCH] elf: Check invalid hole in PT_LOAD segments [BZ #28838]
Changes in v2:
1. Update commit log.
commit 163f625cf9becbb82dfec63a29e566324129c0cd
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Tue Dec 21 12:35:47 2021 -0800
elf: Remove excessive p_align check on PT_LOAD segments [BZ #28688]
removed the p_align check against the page size. It caused the loader
error or crash on elf/tst-p_align3 when loading elf/tst-p_alignmod3.so,
which has the invalid p_align in PT_LOAD segments, added by
commit d8d94863ef125a392b929732b37e07dc927fbcd1
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Tue Dec 21 13:42:28 2021 -0800
The loader failure caused by a negative length passed to __mprotect is
random, depending on architecture and toolchain. Update _dl_map_segments
to detect invalid holes. This fixes BZ #28838.
Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit 2c0915cbf570cb9c8a65f1d20a55c5a7238e5b63)
---
elf/dl-map-segments.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/elf/dl-map-segments.h b/elf/dl-map-segments.h
index 172692b120..fd24cf5d01 100644
--- a/elf/dl-map-segments.h
+++ b/elf/dl-map-segments.h
@@ -113,6 +113,9 @@ _dl_map_segments (struct link_map *l, int fd,
unallocated. Then jump into the normal segment-mapping loop to
handle the portion of the segment past the end of the file
mapping. */
+ if (__glibc_unlikely (loadcmds[nloadcmds - 1].mapstart <
+ c->mapend))
+ return N_("ELF load command address/offset not page-aligned");
if (__glibc_unlikely
(__mprotect ((caddr_t) (l->l_addr + c->mapend),
loadcmds[nloadcmds - 1].mapstart - c->mapend,
--
2.35.0

132
strcmp-rtm-fallback.path Normal file
View File

@ -0,0 +1,132 @@
From fd412fff6d2bd322ec24ebd13fab196efc6c5506 Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n@gmail.com>
Date: Tue, 15 Feb 2022 08:18:15 -0600
Subject: [PATCH] x86: Fallback {str|wcs}cmp RTM in the ncmp overflow case [BZ
#28896]
In the overflow fallback strncmp-avx2-rtm and wcsncmp-avx2-rtm would
call strcmp-avx2 and wcscmp-avx2 respectively. This would have
not checks around vzeroupper and would trigger spurious
aborts. This commit fixes that.
test-strcmp, test-strncmp, test-wcscmp, and test-wcsncmp all pass on
AVX2 machines with and without RTM.
Co-authored-by: H.J. Lu <hjl.tools@gmail.com>
(cherry picked from commit c6272098323153db373f2986c67786ea8c85f1cf)
---
sysdeps/x86/Makefile | 2 +-
sysdeps/x86/tst-strncmp-rtm.c | 17 ++++++++++++++++-
sysdeps/x86_64/multiarch/strcmp-avx2.S | 2 +-
sysdeps/x86_64/multiarch/strncmp-avx2-rtm.S | 1 +
sysdeps/x86_64/multiarch/strncmp-avx2.S | 1 +
sysdeps/x86_64/multiarch/wcsncmp-avx2-rtm.S | 2 +-
sysdeps/x86_64/multiarch/wcsncmp-avx2.S | 2 +-
7 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
index 6cf708335c..d110f7b7f2 100644
--- a/sysdeps/x86/Makefile
+++ b/sysdeps/x86/Makefile
@@ -109,7 +109,7 @@ CFLAGS-tst-memset-rtm.c += -mrtm
CFLAGS-tst-strchr-rtm.c += -mrtm
CFLAGS-tst-strcpy-rtm.c += -mrtm
CFLAGS-tst-strlen-rtm.c += -mrtm
-CFLAGS-tst-strncmp-rtm.c += -mrtm
+CFLAGS-tst-strncmp-rtm.c += -mrtm -Wno-error
CFLAGS-tst-strrchr-rtm.c += -mrtm
endif
diff --git a/sysdeps/x86/tst-strncmp-rtm.c b/sysdeps/x86/tst-strncmp-rtm.c
index 09ed6fa0d6..9e20abaacc 100644
--- a/sysdeps/x86/tst-strncmp-rtm.c
+++ b/sysdeps/x86/tst-strncmp-rtm.c
@@ -16,6 +16,7 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#include <stdint.h>
#include <tst-string-rtm.h>
#define LOOP 3000
@@ -45,8 +46,22 @@ function (void)
return 1;
}
+__attribute__ ((noinline, noclone))
+static int
+function_overflow (void)
+{
+ if (strncmp (string1, string2, SIZE_MAX) == 0)
+ return 0;
+ else
+ return 1;
+}
+
static int
do_test (void)
{
- return do_test_1 ("strncmp", LOOP, prepare, function);
+ int status = do_test_1 ("strncmp", LOOP, prepare, function);
+ if (status != EXIT_SUCCESS)
+ return status;
+ status = do_test_1 ("strncmp", LOOP, prepare, function_overflow);
+ return status;
}
diff --git a/sysdeps/x86_64/multiarch/strcmp-avx2.S b/sysdeps/x86_64/multiarch/strcmp-avx2.S
index 9c73b5899d..cdcb3c5a26 100644
--- a/sysdeps/x86_64/multiarch/strcmp-avx2.S
+++ b/sysdeps/x86_64/multiarch/strcmp-avx2.S
@@ -95,7 +95,7 @@ ENTRY (STRCMP)
length to bound a valid memory region. In these cases just use
'wcscmp'. */
shrq $56, %rcx
- jnz __wcscmp_avx2
+ jnz OVERFLOW_STRCMP
# endif
/* Convert units: from wide to byte char. */
shl $2, %RDX_LP
diff --git a/sysdeps/x86_64/multiarch/strncmp-avx2-rtm.S b/sysdeps/x86_64/multiarch/strncmp-avx2-rtm.S
index 37d1224bb9..68bad365ba 100644
--- a/sysdeps/x86_64/multiarch/strncmp-avx2-rtm.S
+++ b/sysdeps/x86_64/multiarch/strncmp-avx2-rtm.S
@@ -1,3 +1,4 @@
#define STRCMP __strncmp_avx2_rtm
#define USE_AS_STRNCMP 1
+#define OVERFLOW_STRCMP __strcmp_avx2_rtm
#include "strcmp-avx2-rtm.S"
diff --git a/sysdeps/x86_64/multiarch/strncmp-avx2.S b/sysdeps/x86_64/multiarch/strncmp-avx2.S
index 1678bcc235..f138e9f1fd 100644
--- a/sysdeps/x86_64/multiarch/strncmp-avx2.S
+++ b/sysdeps/x86_64/multiarch/strncmp-avx2.S
@@ -1,3 +1,4 @@
#define STRCMP __strncmp_avx2
#define USE_AS_STRNCMP 1
+#define OVERFLOW_STRCMP __strcmp_avx2
#include "strcmp-avx2.S"
diff --git a/sysdeps/x86_64/multiarch/wcsncmp-avx2-rtm.S b/sysdeps/x86_64/multiarch/wcsncmp-avx2-rtm.S
index 4e88c70cc6..f467582cbe 100644
--- a/sysdeps/x86_64/multiarch/wcsncmp-avx2-rtm.S
+++ b/sysdeps/x86_64/multiarch/wcsncmp-avx2-rtm.S
@@ -1,5 +1,5 @@
#define STRCMP __wcsncmp_avx2_rtm
#define USE_AS_STRNCMP 1
#define USE_AS_WCSCMP 1
-
+#define OVERFLOW_STRCMP __wcscmp_avx2_rtm
#include "strcmp-avx2-rtm.S"
diff --git a/sysdeps/x86_64/multiarch/wcsncmp-avx2.S b/sysdeps/x86_64/multiarch/wcsncmp-avx2.S
index 4fa1de4d3f..e9ede522b8 100644
--- a/sysdeps/x86_64/multiarch/wcsncmp-avx2.S
+++ b/sysdeps/x86_64/multiarch/wcsncmp-avx2.S
@@ -1,5 +1,5 @@
#define STRCMP __wcsncmp_avx2
#define USE_AS_STRNCMP 1
#define USE_AS_WCSCMP 1
-
+#define OVERFLOW_STRCMP __wcscmp_avx2
#include "strcmp-avx2.S"
--
2.35.0