Fix ldconfig -p on i686 (#2167811)

Resolves: #2167811
This commit is contained in:
Florian Weimer 2023-02-08 14:26:21 +01:00
parent 3ccfcc3019
commit 5eec3980b9
4 changed files with 511 additions and 1 deletions

View File

@ -0,0 +1,48 @@
commit c5c792092b57687ae3ebecbe8645fa71ddb19f8c
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Thu Feb 2 07:49:02 2023 -0500
cdefs: Limit definition of fortification macros
Define the __glibc_fortify and other macros only when __FORTIFY_LEVEL >
0. This has the effect of not defining these macros on older C90
compilers that do not have support for variable length argument lists.
Also trim off the trailing backslashes from the definition of
__glibc_fortify and __glibc_fortify_n macros.
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit 2337e04e21ba6040926ec871e403533f77043c40)
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
index b166f3d209fe361f..92dbd3e1fc68dae7 100644
--- a/misc/sys/cdefs.h
+++ b/misc/sys/cdefs.h
@@ -151,6 +151,7 @@
# define __glibc_objsize(__o) __bos (__o)
#endif
+#if __USE_FORTIFY_LEVEL > 0
/* Compile time conditions to choose between the regular, _chk and _chk_warn
variants. These conditions should get evaluated to constant and optimized
away. */
@@ -186,7 +187,7 @@
? __ ## f ## _alias (__VA_ARGS__) \
: (__glibc_unsafe_len (__l, __s, __osz) \
? __ ## f ## _chk_warn (__VA_ARGS__, __osz) \
- : __ ## f ## _chk (__VA_ARGS__, __osz))) \
+ : __ ## f ## _chk (__VA_ARGS__, __osz)))
/* Fortify function f, where object size argument passed to f is the number of
elements and not total size. */
@@ -196,7 +197,8 @@
? __ ## f ## _alias (__VA_ARGS__) \
: (__glibc_unsafe_len (__l, __s, __osz) \
? __ ## f ## _chk_warn (__VA_ARGS__, (__osz) / (__s)) \
- : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s)))) \
+ : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s))))
+#endif
#if __GNUC_PREREQ (4,3)
# define __warnattr(msg) __attribute__((__warning__ (msg)))

View File

@ -0,0 +1,127 @@
commit 0b962177ee3b45cf775176eb454fcf6aa1b0f6e3
Author: Andreas Schwab <schwab@suse.de>
Date: Thu Jan 26 14:25:05 2023 +0100
Use 64-bit time_t interfaces in strftime and strptime (bug 30053)
Both functions use time_t only internally, so the ABI is not affected.
(cherry picked from commit 41349f6f67c83e7bafe49f985b56493d2c4c9c77)
diff --git a/time/Makefile b/time/Makefile
index 38e3a7f4c77ea27f..ef3bb767b825f76a 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -50,7 +50,7 @@ tests := test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
tst-clock tst-clock2 tst-clock_nanosleep tst-cpuclock1 \
tst-adjtime tst-ctime tst-difftime tst-mktime4 tst-clock_settime \
tst-settimeofday tst-itimer tst-gmtime tst-timegm \
- tst-timespec_get tst-timespec_getres
+ tst-timespec_get tst-timespec_getres tst-strftime4
tests-time64 := \
tst-adjtime-time64 \
@@ -65,6 +65,7 @@ tests-time64 := \
tst-itimer-time64 \
tst-mktime4-time64 \
tst-settimeofday-time64 \
+ tst-strftime4-time64 \
tst-timegm-time64 \
tst-timespec_get-time64 \
tst-timespec_getres-time64 \
diff --git a/time/strftime_l.c b/time/strftime_l.c
index d8cde9c5a3af87c7..57abbaa571694505 100644
--- a/time/strftime_l.c
+++ b/time/strftime_l.c
@@ -159,6 +159,10 @@ extern char *tzname[];
#ifdef _LIBC
# define tzname __tzname
# define tzset __tzset
+
+# define time_t __time64_t
+# define __gmtime_r(t, tp) __gmtime64_r (t, tp)
+# define mktime(tp) __mktime64 (tp)
#endif
#if !HAVE_TM_GMTOFF
diff --git a/time/strptime_l.c b/time/strptime_l.c
index 02c5d63c798f9c13..39d1e59b0871f4b4 100644
--- a/time/strptime_l.c
+++ b/time/strptime_l.c
@@ -30,8 +30,10 @@
#ifdef _LIBC
# define HAVE_LOCALTIME_R 0
# include "../locale/localeinfo.h"
-#endif
+# define time_t __time64_t
+# define __localtime_r(t, tp) __localtime64_r (t, tp)
+#endif
#if ! HAVE_LOCALTIME_R && ! defined localtime_r
# ifdef _LIBC
diff --git a/time/tst-strftime4-time64.c b/time/tst-strftime4-time64.c
new file mode 100644
index 0000000000000000..4d47ee7d79f9e648
--- /dev/null
+++ b/time/tst-strftime4-time64.c
@@ -0,0 +1 @@
+#include "tst-strftime4.c"
diff --git a/time/tst-strftime4.c b/time/tst-strftime4.c
new file mode 100644
index 0000000000000000..659716d0fa4534ae
--- /dev/null
+++ b/time/tst-strftime4.c
@@ -0,0 +1,52 @@
+/* Test strftime and strptime after 2038-01-19 03:14:07 UTC (bug 30053).
+ Copyright (C) 2023 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 <time.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <support/check.h>
+
+static int
+do_test (void)
+{
+ TEST_VERIFY_EXIT (setenv ("TZ", "UTC0", 1) == 0);
+ tzset ();
+ if (sizeof (time_t) > 4)
+ {
+ time_t wrap = (time_t) 2147483648LL;
+ char buf[80];
+ struct tm *tm = gmtime (&wrap);
+ TEST_VERIFY_EXIT (tm != NULL);
+ TEST_VERIFY_EXIT (strftime (buf, sizeof buf, "%s", tm) > 0);
+ puts (buf);
+ TEST_VERIFY (strcmp (buf, "2147483648") == 0);
+
+ struct tm tm2;
+ char *p = strptime (buf, "%s", &tm2);
+ TEST_VERIFY_EXIT (p != NULL && *p == '\0');
+ time_t t = mktime (&tm2);
+ printf ("%lld\n", (long long) t);
+ TEST_VERIFY (t == wrap);
+ }
+ else
+ FAIL_UNSUPPORTED ("32-bit time_t");
+ return 0;
+}
+
+#include <support/test-driver.c>

View File

@ -0,0 +1,328 @@
commit 11ad405fd4c4c9f320d461d9ae1dd2e087cc8c32
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Wed Dec 29 10:20:46 2021 -0300
elf: Fix 64 time_t support for installed statically binaries
The usage of internal static symbol for statically linked binaries
does not work correctly for objects built with -D_TIME_BITS=64,
since the internal definition does not provide the expected aliases.
This patch makes it to use the default stat functions instead (which
uses the default 64 time_t alias and types).
Checked on i686-linux-gnu.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit 9fe6f6363886aae6b2b210cae3ed1f5921299083)
diff --git a/elf/cache.c b/elf/cache.c
index 8a3404923c625d18..062ec7fb0c9c300f 100644
--- a/elf/cache.c
+++ b/elf/cache.c
@@ -319,8 +319,8 @@ print_cache (const char *cache_name)
if (fd < 0)
error (EXIT_FAILURE, errno, _("Can't open cache file %s\n"), cache_name);
- struct stat64 st;
- if (__fstat64 (fd, &st) < 0
+ struct stat st;
+ if (fstat (fd, &st) < 0
/* No need to map the file if it is empty. */
|| st.st_size == 0)
{
@@ -933,7 +933,7 @@ init_aux_cache (void)
}
int
-search_aux_cache (struct stat64 *stat_buf, int *flags,
+search_aux_cache (struct stat *stat_buf, int *flags,
unsigned int *osversion, unsigned int *isa_level,
char **soname)
{
@@ -995,7 +995,7 @@ insert_to_aux_cache (struct aux_cache_entry_id *id, int flags,
}
void
-add_to_aux_cache (struct stat64 *stat_buf, int flags,
+add_to_aux_cache (struct stat *stat_buf, int flags,
unsigned int osversion, unsigned int isa_level,
const char *soname)
{
@@ -1018,8 +1018,8 @@ load_aux_cache (const char *aux_cache_name)
return;
}
- struct stat64 st;
- if (__fstat64 (fd, &st) < 0 || st.st_size < sizeof (struct aux_cache_file))
+ struct stat st;
+ if (fstat (fd, &st) < 0 || st.st_size < sizeof (struct aux_cache_file))
{
close (fd);
init_aux_cache ();
@@ -1135,8 +1135,8 @@ save_aux_cache (const char *aux_cache_name)
char *dir = strdupa (aux_cache_name);
dir = dirname (dir);
- struct stat64 st;
- if (stat64 (dir, &st) < 0)
+ struct stat st;
+ if (stat (dir, &st) < 0)
{
if (mkdir (dir, 0700) < 0)
goto out_fail;
diff --git a/elf/chroot_canon.c b/elf/chroot_canon.c
index 045611e730be9e41..a70fd25046112290 100644
--- a/elf/chroot_canon.c
+++ b/elf/chroot_canon.c
@@ -67,7 +67,7 @@ chroot_canon (const char *chroot, const char *name)
for (start = end = name; *start; start = end)
{
- struct stat64 st;
+ struct stat st;
/* Skip sequence of multiple path-separators. */
while (*start == '/')
@@ -114,7 +114,7 @@ chroot_canon (const char *chroot, const char *name)
dest = mempcpy (dest, start, end - start);
*dest = '\0';
- if (lstat64 (rpath, &st) < 0)
+ if (lstat (rpath, &st) < 0)
{
if (*end == '\0')
goto done;
diff --git a/elf/ldconfig.c b/elf/ldconfig.c
index b8893637f8aaea8d..be47ad8c2d7f89f3 100644
--- a/elf/ldconfig.c
+++ b/elf/ldconfig.c
@@ -338,7 +338,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
inode data from *ST. */
static struct dir_entry *
new_sub_entry (const struct dir_entry *entry, const char *path,
- const struct stat64 *st)
+ const struct stat *st)
{
struct dir_entry *new_entry = xmalloc (sizeof (struct dir_entry));
new_entry->from_file = entry->from_file;
@@ -428,8 +428,8 @@ add_glibc_hwcaps_subdirectories (struct dir_entry *entry, const char *path)
continue;
/* See if this entry eventually resolves to a directory. */
- struct stat64 st;
- if (fstatat64 (dirfd (dir), e->d_name, &st, 0) < 0)
+ struct stat st;
+ if (fstatat (dirfd (dir), e->d_name, &st, 0) < 0)
/* Ignore unreadable entries. */
continue;
@@ -513,8 +513,8 @@ add_dir_1 (const char *line, const char *from_file, int from_line)
if (opt_chroot != NULL)
path = chroot_canon (opt_chroot, path);
- struct stat64 stat_buf;
- if (path == NULL || stat64 (path, &stat_buf))
+ struct stat stat_buf;
+ if (path == NULL || stat (path, &stat_buf))
{
if (opt_verbose)
error (0, errno, _("Can't stat %s"), entry->path);
@@ -542,15 +542,15 @@ add_dir (const char *line)
}
static int
-chroot_stat (const char *real_path, const char *path, struct stat64 *st)
+chroot_stat (const char *real_path, const char *path, struct stat *st)
{
int ret;
char *canon_path;
if (!opt_chroot)
- return stat64 (real_path, st);
+ return stat (real_path, st);
- ret = lstat64 (real_path, st);
+ ret = lstat (real_path, st);
if (ret || !S_ISLNK (st->st_mode))
return ret;
@@ -558,7 +558,7 @@ chroot_stat (const char *real_path, const char *path, struct stat64 *st)
if (canon_path == NULL)
return -1;
- ret = stat64 (canon_path, st);
+ ret = stat (canon_path, st);
free (canon_path);
return ret;
}
@@ -570,7 +570,7 @@ create_links (const char *real_path, const char *path, const char *libname,
{
char *full_libname, *full_soname;
char *real_full_libname, *real_full_soname;
- struct stat64 stat_lib, stat_so, lstat_so;
+ struct stat stat_lib, stat_so, lstat_so;
int do_link = 1;
int do_remove = 1;
/* XXX: The logics in this function should be simplified. */
@@ -605,7 +605,7 @@ create_links (const char *real_path, const char *path, const char *libname,
&& stat_lib.st_ino == stat_so.st_ino)
/* Link is already correct. */
do_link = 0;
- else if (lstat64 (full_soname, &lstat_so) == 0
+ else if (lstat (full_soname, &lstat_so) == 0
&& !S_ISLNK (lstat_so.st_mode))
{
error (0, 0, _("%s is not a symbolic link\n"), full_soname);
@@ -613,7 +613,7 @@ create_links (const char *real_path, const char *path, const char *libname,
do_remove = 0;
}
}
- else if (lstat64 (real_full_soname, &lstat_so) != 0
+ else if (lstat (real_full_soname, &lstat_so) != 0
|| !S_ISLNK (lstat_so.st_mode))
/* Unless it is a stale symlink, there is no need to remove. */
do_remove = 0;
@@ -657,7 +657,7 @@ manual_link (char *library)
char *real_library;
char *libname;
char *soname;
- struct stat64 stat_buf;
+ struct stat stat_buf;
int flag;
unsigned int osversion;
unsigned int isa_level;
@@ -711,7 +711,7 @@ manual_link (char *library)
}
/* Do some sanity checks first. */
- if (lstat64 (real_library, &stat_buf))
+ if (lstat (real_library, &stat_buf))
{
error (0, errno, _("Cannot lstat %s"), library);
goto out;
@@ -886,18 +886,18 @@ search_dir (const struct dir_entry *entry)
sprintf (real_file_name, "%s/%s", dir_name, direntry->d_name);
}
- struct stat64 lstat_buf;
+ struct stat lstat_buf;
/* We optimize and try to do the lstat call only if needed. */
if (direntry->d_type != DT_UNKNOWN)
lstat_buf.st_mode = DTTOIF (direntry->d_type);
else
- if (__glibc_unlikely (lstat64 (real_file_name, &lstat_buf)))
+ if (__glibc_unlikely (lstat (real_file_name, &lstat_buf)))
{
error (0, errno, _("Cannot lstat %s"), file_name);
continue;
}
- struct stat64 stat_buf;
+ struct stat stat_buf;
bool is_dir;
int is_link = S_ISLNK (lstat_buf.st_mode);
if (is_link)
@@ -915,7 +915,7 @@ search_dir (const struct dir_entry *entry)
continue;
}
}
- if (__glibc_unlikely (stat64 (target_name, &stat_buf)))
+ if (__glibc_unlikely (stat (target_name, &stat_buf)))
{
if (opt_verbose)
error (0, errno, _("Cannot stat %s"), file_name);
@@ -951,7 +951,7 @@ search_dir (const struct dir_entry *entry)
{
if (!is_link
&& direntry->d_type != DT_UNKNOWN
- && __builtin_expect (lstat64 (real_file_name, &lstat_buf), 0))
+ && __builtin_expect (lstat (real_file_name, &lstat_buf), 0))
{
error (0, errno, _("Cannot lstat %s"), file_name);
continue;
@@ -980,10 +980,10 @@ search_dir (const struct dir_entry *entry)
else
real_name = real_file_name;
- /* Call lstat64 if not done yet. */
+ /* Call lstat if not done yet. */
if (!is_link
&& direntry->d_type != DT_UNKNOWN
- && __builtin_expect (lstat64 (real_file_name, &lstat_buf), 0))
+ && __builtin_expect (lstat (real_file_name, &lstat_buf), 0))
{
error (0, errno, _("Cannot lstat %s"), file_name);
continue;
diff --git a/elf/readlib.c b/elf/readlib.c
index 7383c23249426c44..8901de2684835653 100644
--- a/elf/readlib.c
+++ b/elf/readlib.c
@@ -76,10 +76,10 @@ int
process_file (const char *real_file_name, const char *file_name,
const char *lib, int *flag, unsigned int *osversion,
unsigned int *isa_level, char **soname, int is_link,
- struct stat64 *stat_buf)
+ struct stat *stat_buf)
{
FILE *file;
- struct stat64 statbuf;
+ struct stat statbuf;
void *file_contents;
int ret;
ElfW(Ehdr) *elf_header;
@@ -99,7 +99,7 @@ process_file (const char *real_file_name, const char *file_name,
return 1;
}
- if (fstat64 (fileno (file), &statbuf) < 0)
+ if (fstat (fileno (file), &statbuf) < 0)
{
error (0, 0, _("Cannot fstat file %s.\n"), file_name);
fclose (file);
diff --git a/elf/sln.c b/elf/sln.c
index 26f371a4932cf475..f71321d565803f06 100644
--- a/elf/sln.c
+++ b/elf/sln.c
@@ -153,11 +153,11 @@ makesymlinks (const char *file)
static int
makesymlink (const char *src, const char *dest)
{
- struct stat64 stats;
+ struct stat stats;
const char *error;
/* Destination must not be a directory. */
- if (lstat64 (dest, &stats) == 0)
+ if (lstat (dest, &stats) == 0)
{
if (S_ISDIR (stats.st_mode))
{
diff --git a/sysdeps/generic/ldconfig.h b/sysdeps/generic/ldconfig.h
index 3ab757077d160520..c0eb95bcf989dddc 100644
--- a/sysdeps/generic/ldconfig.h
+++ b/sysdeps/generic/ldconfig.h
@@ -79,11 +79,11 @@ extern void init_aux_cache (void);
extern void load_aux_cache (const char *aux_cache_name);
-extern int search_aux_cache (struct stat64 *stat_buf, int *flags,
+extern int search_aux_cache (struct stat *stat_buf, int *flags,
unsigned int *osversion,
unsigned int *isa_level, char **soname);
-extern void add_to_aux_cache (struct stat64 *stat_buf, int flags,
+extern void add_to_aux_cache (struct stat *stat_buf, int flags,
unsigned int osversion,
unsigned int isa_level, const char *soname);
@@ -94,7 +94,7 @@ extern int process_file (const char *real_file_name, const char *file_name,
const char *lib, int *flag,
unsigned int *osversion, unsigned int *isa_level,
char **soname, int is_link,
- struct stat64 *stat_buf);
+ struct stat *stat_buf);
extern char *implicit_soname (const char *lib, int flag);

View File

@ -155,7 +155,7 @@ end \
Summary: The GNU libc libraries
Name: glibc
Version: %{glibcversion}
Release: 58%{?dist}
Release: 59%{?dist}
# In general, GPLv2+ is used by programs, LGPLv2+ is used for
# libraries.
@ -695,6 +695,10 @@ Patch463: glibc-upstream-2.34-382.patch
Patch464: glibc-upstream-2.34-383.patch
Patch465: glibc-upstream-2.34-384.patch
Patch466: glibc-rh2162962.patch
Patch467: glibc-upstream-2.34-385.patch
Patch468: glibc-upstream-2.34-386.patch
# glibc-upstream-2.34-387.patch is a NEWS-only update. Skipped downstream.
Patch469: glibc-upstream-2.34-388.patch
##############################################################################
# Continued list of core "glibc" package information:
@ -2854,6 +2858,9 @@ fi
%endif
%changelog
* Wed Feb 8 2023 Florian Weimer <fweimer@redhat.com> - 2.34-59
- Fix ldconfig -p on i686 (#2167811)
* Wed Jan 25 2023 Florian Weimer <fweimer@redhat.com> - 2.34-58
- Enhance internal tunables ABI stability (awk iteration order) (#2162962)