parent
a0b7ce8f05
commit
026f78f16f
44
glibc-upstream-2.34-21.patch
Normal file
44
glibc-upstream-2.34-21.patch
Normal file
@ -0,0 +1,44 @@
|
||||
commit 433ec4f14a5753c7689c83c20c9972915c53c204
|
||||
Author: Aurelien Jarno <aurelien@aurel32.net>
|
||||
Date: Fri Sep 10 19:39:35 2021 +0200
|
||||
|
||||
posix: Fix attribute access mode on getcwd [BZ #27476]
|
||||
|
||||
There is a GNU extension that allows to call getcwd(NULL, >0). It is
|
||||
described in the documentation, but also directly in the unistd.h
|
||||
header, just above the declaration.
|
||||
|
||||
Therefore the attribute access mode added in commit 06febd8c6705
|
||||
is not correct. Drop it.
|
||||
|
||||
diff --git a/posix/bits/unistd.h b/posix/bits/unistd.h
|
||||
index f0831386c7ddb574..622adeb2b28ed298 100644
|
||||
--- a/posix/bits/unistd.h
|
||||
+++ b/posix/bits/unistd.h
|
||||
@@ -199,10 +199,9 @@ __NTH (readlinkat (int __fd, const char *__restrict __path,
|
||||
#endif
|
||||
|
||||
extern char *__getcwd_chk (char *__buf, size_t __size, size_t __buflen)
|
||||
- __THROW __wur __attr_access ((__write_only__, 1, 2));
|
||||
+ __THROW __wur;
|
||||
extern char *__REDIRECT_NTH (__getcwd_alias,
|
||||
- (char *__buf, size_t __size), getcwd)
|
||||
- __wur __attr_access ((__write_only__, 1, 2));
|
||||
+ (char *__buf, size_t __size), getcwd) __wur;
|
||||
extern char *__REDIRECT_NTH (__getcwd_chk_warn,
|
||||
(char *__buf, size_t __size, size_t __buflen),
|
||||
__getcwd_chk)
|
||||
diff --git a/posix/unistd.h b/posix/unistd.h
|
||||
index 3dca65732fdde52f..8224c5fbc956306f 100644
|
||||
--- a/posix/unistd.h
|
||||
+++ b/posix/unistd.h
|
||||
@@ -528,8 +528,7 @@ extern int fchdir (int __fd) __THROW __wur;
|
||||
an array is allocated with `malloc'; the array is SIZE
|
||||
bytes long, unless SIZE == 0, in which case it is as
|
||||
big as necessary. */
|
||||
-extern char *getcwd (char *__buf, size_t __size) __THROW __wur
|
||||
- __attr_access ((__write_only__, 1, 2));
|
||||
+extern char *getcwd (char *__buf, size_t __size) __THROW __wur;
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* Return a malloc'd string containing the current directory name.
|
137
glibc-upstream-2.34-22.patch
Normal file
137
glibc-upstream-2.34-22.patch
Normal file
@ -0,0 +1,137 @@
|
||||
commit 73c7f5a87971de2797f261e1a447f68dce09284b
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Sep 20 14:56:08 2021 +0200
|
||||
|
||||
nptl: pthread_kill needs to return ESRCH for old programs (bug 19193)
|
||||
|
||||
The fix for bug 19193 breaks some old applications which appear
|
||||
to use pthread_kill to probe if a thread is still running, something
|
||||
that is not supported by POSIX.
|
||||
|
||||
(cherry picked from commit 95dba35bf05e4a5d69dfae5e9c9d4df3646a7f93)
|
||||
|
||||
diff --git a/nptl/pthread_kill.c b/nptl/pthread_kill.c
|
||||
index fb7862eff787a94f..a44dc8f2d9baa925 100644
|
||||
--- a/nptl/pthread_kill.c
|
||||
+++ b/nptl/pthread_kill.c
|
||||
@@ -21,8 +21,11 @@
|
||||
#include <pthreadP.h>
|
||||
#include <shlib-compat.h>
|
||||
|
||||
-int
|
||||
-__pthread_kill_internal (pthread_t threadid, int signo)
|
||||
+/* Sends SIGNO to THREADID. If the thread is about to exit or has
|
||||
+ already exited on the kernel side, return NO_TID. Otherwise return
|
||||
+ 0 or an error code. */
|
||||
+static int
|
||||
+__pthread_kill_implementation (pthread_t threadid, int signo, int no_tid)
|
||||
{
|
||||
struct pthread *pd = (struct pthread *) threadid;
|
||||
if (pd == THREAD_SELF)
|
||||
@@ -52,11 +55,8 @@ __pthread_kill_internal (pthread_t threadid, int signo)
|
||||
signal is either not observable (the target thread has already
|
||||
blocked signals at this point), or it will fail, or it might be
|
||||
delivered to a new, unrelated thread that has reused the TID.
|
||||
- So do not actually send the signal. Do not report an error
|
||||
- because the threadid argument is still valid (the thread ID
|
||||
- lifetime has not ended), and ESRCH (for example) would be
|
||||
- misleading. */
|
||||
- ret = 0;
|
||||
+ So do not actually send the signal. */
|
||||
+ ret = no_tid;
|
||||
else
|
||||
{
|
||||
/* Using tgkill is a safety measure. pd->exit_lock ensures that
|
||||
@@ -71,6 +71,15 @@ __pthread_kill_internal (pthread_t threadid, int signo)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+int
|
||||
+__pthread_kill_internal (pthread_t threadid, int signo)
|
||||
+{
|
||||
+ /* Do not report an error in the no-tid case because the threadid
|
||||
+ argument is still valid (the thread ID lifetime has not ended),
|
||||
+ and ESRCH (for example) would be misleading. */
|
||||
+ return __pthread_kill_implementation (threadid, signo, 0);
|
||||
+}
|
||||
+
|
||||
int
|
||||
__pthread_kill (pthread_t threadid, int signo)
|
||||
{
|
||||
@@ -81,6 +90,7 @@ __pthread_kill (pthread_t threadid, int signo)
|
||||
|
||||
return __pthread_kill_internal (threadid, signo);
|
||||
}
|
||||
+
|
||||
/* Some architectures (for instance arm) might pull raise through libgcc, so
|
||||
avoid the symbol version if it ends up being used on ld.so. */
|
||||
#if !IS_IN(rtld)
|
||||
@@ -88,6 +98,17 @@ libc_hidden_def (__pthread_kill)
|
||||
versioned_symbol (libc, __pthread_kill, pthread_kill, GLIBC_2_34);
|
||||
|
||||
# if OTHER_SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_34)
|
||||
-compat_symbol (libc, __pthread_kill, pthread_kill, GLIBC_2_0);
|
||||
+/* Variant which returns ESRCH in the no-TID case, for backwards
|
||||
+ compatibility. */
|
||||
+int
|
||||
+attribute_compat_text_section
|
||||
+__pthread_kill_esrch (pthread_t threadid, int signo)
|
||||
+{
|
||||
+ if (__is_internal_signal (signo))
|
||||
+ return EINVAL;
|
||||
+
|
||||
+ return __pthread_kill_implementation (threadid, signo, ESRCH);
|
||||
+}
|
||||
+compat_symbol (libc, __pthread_kill_esrch, pthread_kill, GLIBC_2_0);
|
||||
# endif
|
||||
#endif
|
||||
diff --git a/sysdeps/pthread/tst-pthread_kill-exited.c b/sysdeps/pthread/tst-pthread_kill-exited.c
|
||||
index 7575fb6d58cae99c..a2fddad526666c8c 100644
|
||||
--- a/sysdeps/pthread/tst-pthread_kill-exited.c
|
||||
+++ b/sysdeps/pthread/tst-pthread_kill-exited.c
|
||||
@@ -16,11 +16,15 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
-/* This test verifies that pthread_kill returns 0 (and not ESRCH) for
|
||||
- a thread that has exited on the kernel side. */
|
||||
+/* This test verifies that the default pthread_kill returns 0 (and not
|
||||
+ ESRCH) for a thread that has exited on the kernel side. */
|
||||
|
||||
+#include <errno.h>
|
||||
+#include <pthread.h>
|
||||
+#include <shlib-compat.h>
|
||||
#include <signal.h>
|
||||
#include <stddef.h>
|
||||
+#include <support/check.h>
|
||||
#include <support/support.h>
|
||||
#include <support/xthread.h>
|
||||
|
||||
@@ -30,6 +34,12 @@ noop_thread (void *closure)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+#if TEST_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_34) && PTHREAD_IN_LIBC
|
||||
+extern __typeof (pthread_kill) compat_pthread_kill;
|
||||
+compat_symbol_reference (libpthread, compat_pthread_kill, pthread_kill,
|
||||
+ GLIBC_2_0);
|
||||
+#endif
|
||||
+
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
@@ -37,7 +47,14 @@ do_test (void)
|
||||
|
||||
support_wait_for_thread_exit ();
|
||||
|
||||
+ /* NB: Always uses the default symbol due to separate compilation. */
|
||||
xpthread_kill (thr, SIGUSR1);
|
||||
+
|
||||
+#if TEST_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_34) && PTHREAD_IN_LIBC
|
||||
+ /* Old binaries need the non-conforming ESRCH error code. */
|
||||
+ TEST_COMPARE (compat_pthread_kill (thr, SIGUSR1), ESRCH);
|
||||
+#endif
|
||||
+
|
||||
xpthread_join (thr);
|
||||
|
||||
return 0;
|
32
glibc-upstream-2.34-23.patch
Normal file
32
glibc-upstream-2.34-23.patch
Normal file
@ -0,0 +1,32 @@
|
||||
commit 8b8a1d0b7375c547ae905917a03743ed6759c5bc
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Sep 21 07:12:56 2021 +0200
|
||||
|
||||
nptl: Fix type of pthread_mutexattr_getrobust_np, pthread_mutexattr_setrobust_np (bug 28036)
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
Tested-by: Carlos O'Donell <carlos@redhat.com>
|
||||
(cherry picked from commit f3e664563361dc17530113b3205998d1f19dc4d9)
|
||||
|
||||
diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h
|
||||
index f1b7f2bdc6062c3e..43146e91c9d9579b 100644
|
||||
--- a/sysdeps/nptl/pthread.h
|
||||
+++ b/sysdeps/nptl/pthread.h
|
||||
@@ -933,7 +933,7 @@ extern int pthread_mutexattr_getrobust (const pthread_mutexattr_t *__attr,
|
||||
# ifdef __USE_GNU
|
||||
# ifdef __REDIRECT_NTH
|
||||
extern int __REDIRECT_NTH (pthread_mutexattr_getrobust_np,
|
||||
- (pthread_mutex_t *, int *),
|
||||
+ (pthread_mutexattr_t *, int *),
|
||||
pthread_mutexattr_getrobust) __nonnull ((1))
|
||||
__attribute_deprecated_msg__ ("\
|
||||
pthread_mutexattr_getrobust_np is deprecated, use pthread_mutexattr_getrobust");
|
||||
@@ -949,7 +949,7 @@ extern int pthread_mutexattr_setrobust (pthread_mutexattr_t *__attr,
|
||||
# ifdef __USE_GNU
|
||||
# ifdef __REDIRECT_NTH
|
||||
extern int __REDIRECT_NTH (pthread_mutexattr_setrobust_np,
|
||||
- (pthread_mutex_t *, int),
|
||||
+ (pthread_mutexattr_t *, int),
|
||||
pthread_mutexattr_setrobust) __nonnull ((1))
|
||||
__attribute_deprecated_msg__ ("\
|
||||
pthread_mutexattr_setrobust_np is deprecated, use pthread_mutexattr_setrobust");
|
355
glibc-upstream-2.34-24.patch
Normal file
355
glibc-upstream-2.34-24.patch
Normal file
@ -0,0 +1,355 @@
|
||||
commit 5ad589d63bc2d9b1fc3d9f32144acaebb85e0803
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Tue Aug 24 16:12:24 2021 -0300
|
||||
|
||||
support: Add support_open_dev_null_range
|
||||
|
||||
It returns a range of file descriptor referring to the '/dev/null'
|
||||
pathname. The function takes care of restarting the open range
|
||||
if a file descriptor is found within the specified range and
|
||||
also increases RLIMIT_NOFILE if required.
|
||||
|
||||
Checked on x86_64-linux-gnu.
|
||||
|
||||
(cherry picked from commit e814f4b04ee413a7bb3dfa43e74c8fb4abf58359)
|
||||
|
||||
diff --git a/support/Makefile b/support/Makefile
|
||||
index ef2b1a980a407f8f..2a0731796fdb3f2d 100644
|
||||
--- a/support/Makefile
|
||||
+++ b/support/Makefile
|
||||
@@ -66,6 +66,7 @@ libsupport-routines = \
|
||||
support_path_support_time64 \
|
||||
support_process_state \
|
||||
support_ptrace \
|
||||
+ support-open-dev-null-range \
|
||||
support_openpty \
|
||||
support_paths \
|
||||
support_quote_blob \
|
||||
@@ -265,6 +266,7 @@ tests = \
|
||||
tst-support_capture_subprocess \
|
||||
tst-support_descriptors \
|
||||
tst-support_format_dns_packet \
|
||||
+ tst-support-open-dev-null-range \
|
||||
tst-support-process_state \
|
||||
tst-support_quote_blob \
|
||||
tst-support_quote_string \
|
||||
diff --git a/support/support-open-dev-null-range.c b/support/support-open-dev-null-range.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..80d9dba50402ce12
|
||||
--- /dev/null
|
||||
+++ b/support/support-open-dev-null-range.c
|
||||
@@ -0,0 +1,134 @@
|
||||
+/* Return a range of open file descriptors.
|
||||
+ 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 <errno.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/xunistd.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <sys/resource.h>
|
||||
+
|
||||
+static void
|
||||
+increase_nofile (void)
|
||||
+{
|
||||
+ struct rlimit rl;
|
||||
+ if (getrlimit (RLIMIT_NOFILE, &rl) == -1)
|
||||
+ FAIL_EXIT1 ("getrlimit (RLIMIT_NOFILE): %m");
|
||||
+
|
||||
+ rl.rlim_cur += 128;
|
||||
+
|
||||
+ if (setrlimit (RLIMIT_NOFILE, &rl) == 1)
|
||||
+ FAIL_EXIT1 ("setrlimit (RLIMIT_NOFILE): %m");
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+open_dev_null (int flags, mode_t mode)
|
||||
+{
|
||||
+ int fd = open64 ("/dev/null", flags, mode);
|
||||
+ if (fd > 0)
|
||||
+ return fd;
|
||||
+
|
||||
+ if (fd < 0 && errno != EMFILE)
|
||||
+ FAIL_EXIT1 ("open64 (\"/dev/null\", 0x%x, 0%o): %m", flags, mode);
|
||||
+
|
||||
+ increase_nofile ();
|
||||
+
|
||||
+ return xopen ("/dev/null", flags, mode);
|
||||
+}
|
||||
+
|
||||
+struct range
|
||||
+{
|
||||
+ int lowfd;
|
||||
+ size_t len;
|
||||
+};
|
||||
+
|
||||
+struct range_list
|
||||
+{
|
||||
+ size_t total;
|
||||
+ size_t used;
|
||||
+ struct range *ranges;
|
||||
+};
|
||||
+
|
||||
+static void
|
||||
+range_init (struct range_list *r)
|
||||
+{
|
||||
+ r->total = 8;
|
||||
+ r->used = 0;
|
||||
+ r->ranges = xmalloc (r->total * sizeof (struct range));
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+range_add (struct range_list *r, int lowfd, size_t len)
|
||||
+{
|
||||
+ if (r->used == r->total)
|
||||
+ {
|
||||
+ r->total *= 2;
|
||||
+ r->ranges = xrealloc (r->ranges, r->total * sizeof (struct range));
|
||||
+ }
|
||||
+ r->ranges[r->used].lowfd = lowfd;
|
||||
+ r->ranges[r->used].len = len;
|
||||
+ r->used++;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+range_close (struct range_list *r)
|
||||
+{
|
||||
+ for (size_t i = 0; i < r->used; i++)
|
||||
+ {
|
||||
+ int minfd = r->ranges[i].lowfd;
|
||||
+ int maxfd = r->ranges[i].lowfd + r->ranges[i].len;
|
||||
+ for (int fd = minfd; fd < maxfd; fd++)
|
||||
+ xclose (fd);
|
||||
+ }
|
||||
+ free (r->ranges);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+support_open_dev_null_range (int num, int flags, mode_t mode)
|
||||
+{
|
||||
+ /* We keep track of the ranges that hit an already opened descriptor, so
|
||||
+ we close them after we get a working range. */
|
||||
+ struct range_list rl;
|
||||
+ range_init (&rl);
|
||||
+
|
||||
+ int lowfd = open_dev_null (flags, mode);
|
||||
+ int prevfd = lowfd;
|
||||
+ while (true)
|
||||
+ {
|
||||
+ int i = 1;
|
||||
+ for (; i < num; i++)
|
||||
+ {
|
||||
+ int fd = open_dev_null (flags, mode);
|
||||
+ if (fd != lowfd + i)
|
||||
+ {
|
||||
+ range_add (&rl, lowfd, prevfd - lowfd + 1);
|
||||
+
|
||||
+ prevfd = lowfd = fd;
|
||||
+ break;
|
||||
+ }
|
||||
+ prevfd = fd;
|
||||
+ }
|
||||
+ if (i == num)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ range_close (&rl);
|
||||
+
|
||||
+ return lowfd;
|
||||
+}
|
||||
diff --git a/support/support.h b/support/support.h
|
||||
index a5978b939af2fb41..c219e0d9d1aef046 100644
|
||||
--- a/support/support.h
|
||||
+++ b/support/support.h
|
||||
@@ -197,6 +197,14 @@ struct support_stack support_stack_alloc (size_t size);
|
||||
/* Deallocate the STACK. */
|
||||
void support_stack_free (struct support_stack *stack);
|
||||
|
||||
+
|
||||
+/* Create a range of NUM opened '/dev/null' file descriptors using FLAGS and
|
||||
+ MODE. The function takes care of restarting the open range if a file
|
||||
+ descriptor is found within the specified range and also increases
|
||||
+ RLIMIT_NOFILE if required.
|
||||
+ The returned value is the lowest file descriptor number. */
|
||||
+int support_open_dev_null_range (int num, int flags, mode_t mode);
|
||||
+
|
||||
__END_DECLS
|
||||
|
||||
#endif /* SUPPORT_H */
|
||||
diff --git a/support/tst-support-open-dev-null-range.c b/support/tst-support-open-dev-null-range.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..8e29def1ce780629
|
||||
--- /dev/null
|
||||
+++ b/support/tst-support-open-dev-null-range.c
|
||||
@@ -0,0 +1,155 @@
|
||||
+/* Tests for support_open_dev_null_range.
|
||||
+ 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 <errno.h>
|
||||
+#include <dirent.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <limits.h>
|
||||
+#include <support/check.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/xunistd.h>
|
||||
+#include <sys/resource.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+#ifndef PATH_MAX
|
||||
+# define PATH_MAX 1024
|
||||
+#endif
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+static void
|
||||
+check_path (int fd)
|
||||
+{
|
||||
+ char *proc_fd_path = xasprintf ("/proc/self/fd/%d", fd);
|
||||
+ char file_path[PATH_MAX];
|
||||
+ ssize_t file_path_length
|
||||
+ = readlink (proc_fd_path, file_path, sizeof (file_path));
|
||||
+ free (proc_fd_path);
|
||||
+ if (file_path_length < 0)
|
||||
+ FAIL_EXIT1 ("readlink (%s, %p, %zu)", proc_fd_path, file_path,
|
||||
+ sizeof (file_path));
|
||||
+ file_path[file_path_length] = '\0';
|
||||
+ TEST_COMPARE_STRING (file_path, "/dev/null");
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+number_of_opened_files (void)
|
||||
+{
|
||||
+ DIR *fds = opendir ("/proc/self/fd");
|
||||
+ if (fds == NULL)
|
||||
+ FAIL_EXIT1 ("opendir (\"/proc/self/fd\"): %m");
|
||||
+
|
||||
+ int r = 0;
|
||||
+ while (true)
|
||||
+ {
|
||||
+ errno = 0;
|
||||
+ struct dirent64 *e = readdir64 (fds);
|
||||
+ if (e == NULL)
|
||||
+ {
|
||||
+ if (errno != 0)
|
||||
+ FAIL_EXIT1 ("readdir: %m");
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (e->d_name[0] == '.')
|
||||
+ continue;
|
||||
+
|
||||
+ char *endptr;
|
||||
+ long int fd = strtol (e->d_name, &endptr, 10);
|
||||
+ if (*endptr != '\0' || fd < 0 || fd > INT_MAX)
|
||||
+ FAIL_EXIT1 ("readdir: invalid file descriptor name: /proc/self/fd/%s",
|
||||
+ e->d_name);
|
||||
+
|
||||
+ /* Skip the descriptor which is used to enumerate the
|
||||
+ descriptors. */
|
||||
+ if (fd == dirfd (fds))
|
||||
+ continue;
|
||||
+
|
||||
+ r = r + 1;
|
||||
+ }
|
||||
+
|
||||
+ closedir (fds);
|
||||
+
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ const int nfds1 = 8;
|
||||
+ int lowfd = support_open_dev_null_range (nfds1, O_RDONLY, 0600);
|
||||
+ for (int i = 0; i < nfds1; i++)
|
||||
+ {
|
||||
+ TEST_VERIFY (fcntl (lowfd + i, F_GETFL) > -1);
|
||||
+ check_path (lowfd + i);
|
||||
+ }
|
||||
+
|
||||
+ /* create some gaps. */
|
||||
+ xclose (lowfd + 1);
|
||||
+ xclose (lowfd + 5);
|
||||
+ xclose (lowfd + 6);
|
||||
+
|
||||
+ const int nfds2 = 16;
|
||||
+ int lowfd2 = support_open_dev_null_range (nfds2, O_RDONLY, 0600);
|
||||
+ for (int i = 0; i < nfds2; i++)
|
||||
+ {
|
||||
+ TEST_VERIFY (fcntl (lowfd2 + i, F_GETFL) > -1);
|
||||
+ check_path (lowfd2 + i);
|
||||
+ }
|
||||
+
|
||||
+ /* Decrease the maximum number of files. */
|
||||
+ {
|
||||
+ struct rlimit rl;
|
||||
+ if (getrlimit (RLIMIT_NOFILE, &rl) == -1)
|
||||
+ FAIL_EXIT1 ("getrlimit (RLIMIT_NOFILE): %m");
|
||||
+
|
||||
+ rl.rlim_cur = number_of_opened_files ();
|
||||
+
|
||||
+ if (setrlimit (RLIMIT_NOFILE, &rl) == 1)
|
||||
+ FAIL_EXIT1 ("setrlimit (RLIMIT_NOFILE): %m");
|
||||
+ }
|
||||
+
|
||||
+ const int nfds3 = 16;
|
||||
+ int lowfd3 = support_open_dev_null_range (nfds3, O_RDONLY, 0600);
|
||||
+ for (int i = 0; i < nfds3; i++)
|
||||
+ {
|
||||
+ TEST_VERIFY (fcntl (lowfd3 + i, F_GETFL) > -1);
|
||||
+ check_path (lowfd3 + i);
|
||||
+ }
|
||||
+
|
||||
+ /* create a lot of gaps to trigger the range extension. */
|
||||
+ xclose (lowfd3 + 1);
|
||||
+ xclose (lowfd3 + 3);
|
||||
+ xclose (lowfd3 + 5);
|
||||
+ xclose (lowfd3 + 7);
|
||||
+ xclose (lowfd3 + 9);
|
||||
+ xclose (lowfd3 + 11);
|
||||
+ xclose (lowfd3 + 13);
|
||||
+
|
||||
+ const int nfds4 = 16;
|
||||
+ int lowfd4 = support_open_dev_null_range (nfds4, O_RDONLY, 0600);
|
||||
+ for (int i = 0; i < nfds4; i++)
|
||||
+ {
|
||||
+ TEST_VERIFY (fcntl (lowfd4 + i, F_GETFL) > -1);
|
||||
+ check_path (lowfd4 + i);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
204
glibc-upstream-2.34-25.patch
Normal file
204
glibc-upstream-2.34-25.patch
Normal file
@ -0,0 +1,204 @@
|
||||
commit 772e33411bc730f832f415f93eb3e7c67e4d5488
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Tue Aug 24 16:15:50 2021 -0300
|
||||
|
||||
Use support_open_dev_null_range io/tst-closefrom, misc/tst-close_range, and posix/tst-spawn5 (BZ #28260)
|
||||
|
||||
It ensures a continuous range of file descriptor and avoid hitting
|
||||
the RLIMIT_NOFILE.
|
||||
|
||||
Checked on x86_64-linux-gnu.
|
||||
|
||||
(cherry picked from commit 6b20880b22d1d0fce7e9f506baa6fe2d5c7fcfdc)
|
||||
|
||||
diff --git a/io/tst-closefrom.c b/io/tst-closefrom.c
|
||||
index d4c187073c7280e9..395ec0d894101a47 100644
|
||||
--- a/io/tst-closefrom.c
|
||||
+++ b/io/tst-closefrom.c
|
||||
@@ -24,31 +24,22 @@
|
||||
#include <support/check.h>
|
||||
#include <support/descriptors.h>
|
||||
#include <support/xunistd.h>
|
||||
+#include <support/support.h>
|
||||
|
||||
#include <array_length.h>
|
||||
|
||||
#define NFDS 100
|
||||
|
||||
-static int
|
||||
-open_multiple_temp_files (void)
|
||||
-{
|
||||
- /* Check if the temporary file descriptor has no no gaps. */
|
||||
- int lowfd = xopen ("/dev/null", O_RDONLY, 0600);
|
||||
- for (int i = 1; i <= NFDS; i++)
|
||||
- TEST_COMPARE (xopen ("/dev/null", O_RDONLY, 0600), lowfd + i);
|
||||
- return lowfd;
|
||||
-}
|
||||
-
|
||||
static int
|
||||
closefrom_test (void)
|
||||
{
|
||||
struct support_descriptors *descrs = support_descriptors_list ();
|
||||
|
||||
- int lowfd = open_multiple_temp_files ();
|
||||
+ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600);
|
||||
|
||||
- const int maximum_fd = lowfd + NFDS;
|
||||
+ const int maximum_fd = lowfd + NFDS - 1;
|
||||
const int half_fd = lowfd + NFDS / 2;
|
||||
- const int gap = maximum_fd / 4;
|
||||
+ const int gap = lowfd + NFDS / 4;
|
||||
|
||||
/* Close half of the descriptors and check result. */
|
||||
closefrom (half_fd);
|
||||
@@ -58,7 +49,7 @@ closefrom_test (void)
|
||||
TEST_COMPARE (fcntl (i, F_GETFL), -1);
|
||||
TEST_COMPARE (errno, EBADF);
|
||||
}
|
||||
- for (int i = 0; i < half_fd; i++)
|
||||
+ for (int i = lowfd; i < half_fd; i++)
|
||||
TEST_VERIFY (fcntl (i, F_GETFL) > -1);
|
||||
|
||||
/* Create some gaps, close up to a threshold, and check result. */
|
||||
@@ -74,7 +65,7 @@ closefrom_test (void)
|
||||
TEST_COMPARE (fcntl (i, F_GETFL), -1);
|
||||
TEST_COMPARE (errno, EBADF);
|
||||
}
|
||||
- for (int i = 0; i < gap; i++)
|
||||
+ for (int i = lowfd; i < gap; i++)
|
||||
TEST_VERIFY (fcntl (i, F_GETFL) > -1);
|
||||
|
||||
/* Close the remmaining but the last one. */
|
||||
diff --git a/posix/tst-spawn5.c b/posix/tst-spawn5.c
|
||||
index ac6673800464ce72..a95199af6b3b7c9a 100644
|
||||
--- a/posix/tst-spawn5.c
|
||||
+++ b/posix/tst-spawn5.c
|
||||
@@ -47,17 +47,6 @@ static int initial_argv_count;
|
||||
|
||||
#define NFDS 100
|
||||
|
||||
-static int
|
||||
-open_multiple_temp_files (void)
|
||||
-{
|
||||
- /* Check if the temporary file descriptor has no no gaps. */
|
||||
- int lowfd = xopen ("/dev/null", O_RDONLY, 0600);
|
||||
- for (int i = 1; i <= NFDS; i++)
|
||||
- TEST_COMPARE (xopen ("/dev/null", O_RDONLY, 0600),
|
||||
- lowfd + i);
|
||||
- return lowfd;
|
||||
-}
|
||||
-
|
||||
static int
|
||||
parse_fd (const char *str)
|
||||
{
|
||||
@@ -185,7 +174,7 @@ spawn_closefrom_test (posix_spawn_file_actions_t *fa, int lowfd, int highfd,
|
||||
static void
|
||||
do_test_closefrom (void)
|
||||
{
|
||||
- int lowfd = open_multiple_temp_files ();
|
||||
+ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600);
|
||||
const int half_fd = lowfd + NFDS / 2;
|
||||
|
||||
/* Close half of the descriptors and check result. */
|
||||
diff --git a/sysdeps/unix/sysv/linux/tst-close_range.c b/sysdeps/unix/sysv/linux/tst-close_range.c
|
||||
index dccb6189c53fcb90..f5069d1b8a067241 100644
|
||||
--- a/sysdeps/unix/sysv/linux/tst-close_range.c
|
||||
+++ b/sysdeps/unix/sysv/linux/tst-close_range.c
|
||||
@@ -36,23 +36,12 @@
|
||||
|
||||
#define NFDS 100
|
||||
|
||||
-static int
|
||||
-open_multiple_temp_files (void)
|
||||
-{
|
||||
- /* Check if the temporary file descriptor has no no gaps. */
|
||||
- int lowfd = xopen ("/dev/null", O_RDONLY, 0600);
|
||||
- for (int i = 1; i <= NFDS; i++)
|
||||
- TEST_COMPARE (xopen ("/dev/null", O_RDONLY, 0600),
|
||||
- lowfd + i);
|
||||
- return lowfd;
|
||||
-}
|
||||
-
|
||||
static void
|
||||
close_range_test_max_upper_limit (void)
|
||||
{
|
||||
struct support_descriptors *descrs = support_descriptors_list ();
|
||||
|
||||
- int lowfd = open_multiple_temp_files ();
|
||||
+ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600);
|
||||
|
||||
{
|
||||
int r = close_range (lowfd, ~0U, 0);
|
||||
@@ -68,7 +57,7 @@ close_range_test_max_upper_limit (void)
|
||||
static void
|
||||
close_range_test_common (int lowfd, unsigned int flags)
|
||||
{
|
||||
- const int maximum_fd = lowfd + NFDS;
|
||||
+ const int maximum_fd = lowfd + NFDS - 1;
|
||||
const int half_fd = lowfd + NFDS / 2;
|
||||
const int gap_1 = maximum_fd - 8;
|
||||
|
||||
@@ -121,7 +110,7 @@ close_range_test (void)
|
||||
struct support_descriptors *descrs = support_descriptors_list ();
|
||||
|
||||
/* Check if the temporary file descriptor has no no gaps. */
|
||||
- int lowfd = open_multiple_temp_files ();
|
||||
+ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600);
|
||||
|
||||
close_range_test_common (lowfd, 0);
|
||||
|
||||
@@ -146,7 +135,7 @@ close_range_test_subprocess (void)
|
||||
struct support_descriptors *descrs = support_descriptors_list ();
|
||||
|
||||
/* Check if the temporary file descriptor has no no gaps. */
|
||||
- int lowfd = open_multiple_temp_files ();
|
||||
+ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600);
|
||||
|
||||
struct support_stack stack = support_stack_alloc (4096);
|
||||
|
||||
@@ -184,7 +173,7 @@ close_range_unshare_test (void)
|
||||
struct support_descriptors *descrs1 = support_descriptors_list ();
|
||||
|
||||
/* Check if the temporary file descriptor has no no gaps. */
|
||||
- int lowfd = open_multiple_temp_files ();
|
||||
+ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600);
|
||||
|
||||
struct support_descriptors *descrs2 = support_descriptors_list ();
|
||||
|
||||
@@ -200,7 +189,7 @@ close_range_unshare_test (void)
|
||||
|
||||
support_stack_free (&stack);
|
||||
|
||||
- for (int i = 0; i < NFDS; i++)
|
||||
+ for (int i = lowfd; i < lowfd + NFDS; i++)
|
||||
TEST_VERIFY (fcntl (i, F_GETFL) > -1);
|
||||
|
||||
support_descriptors_check (descrs2);
|
||||
@@ -226,9 +215,9 @@ static void
|
||||
close_range_cloexec_test (void)
|
||||
{
|
||||
/* Check if the temporary file descriptor has no no gaps. */
|
||||
- const int lowfd = open_multiple_temp_files ();
|
||||
+ int lowfd = support_open_dev_null_range (NFDS, O_RDONLY, 0600);
|
||||
|
||||
- const int maximum_fd = lowfd + NFDS;
|
||||
+ const int maximum_fd = lowfd + NFDS - 1;
|
||||
const int half_fd = lowfd + NFDS / 2;
|
||||
const int gap_1 = maximum_fd - 8;
|
||||
|
||||
@@ -251,13 +240,13 @@ close_range_cloexec_test (void)
|
||||
/* Create some gaps, close up to a threshold, and check result. */
|
||||
static int gap_close[] = { 57, 78, 81, 82, 84, 90 };
|
||||
for (int i = 0; i < array_length (gap_close); i++)
|
||||
- xclose (gap_close[i]);
|
||||
+ xclose (lowfd + gap_close[i]);
|
||||
|
||||
TEST_COMPARE (close_range (half_fd + 1, gap_1, CLOSE_RANGE_CLOEXEC), 0);
|
||||
for (int i = half_fd + 1; i < gap_1; i++)
|
||||
{
|
||||
int flags = fcntl (i, F_GETFD);
|
||||
- if (is_in_array (gap_close, array_length (gap_close), i))
|
||||
+ if (is_in_array (gap_close, array_length (gap_close), i - lowfd))
|
||||
TEST_COMPARE (flags, -1);
|
||||
else
|
||||
{
|
129
glibc-upstream-2.34-26.patch
Normal file
129
glibc-upstream-2.34-26.patch
Normal file
@ -0,0 +1,129 @@
|
||||
commit 33adeaa3e2b9143c38884bc5aa65ded222ed274e
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Sep 23 09:55:54 2021 +0200
|
||||
|
||||
nptl: Avoid setxid deadlock with blocked signals in thread exit [BZ #28361]
|
||||
|
||||
As part of the fix for bug 12889, signals are blocked during
|
||||
thread exit, so that application code cannot run on the thread that
|
||||
is about to exit. This would cause problems if the application
|
||||
expected signals to be delivered after the signal handler revealed
|
||||
the thread to still exist, despite pthread_kill can no longer be used
|
||||
to send signals to it. However, glibc internally uses the SIGSETXID
|
||||
signal in a way that is incompatible with signal blocking, due to the
|
||||
way the setxid handshake delays thread exit until the setxid operation
|
||||
has completed. With a blocked SIGSETXID, the handshake can never
|
||||
complete, causing a deadlock.
|
||||
|
||||
As a band-aid, restore the previous handshake protocol by not blocking
|
||||
SIGSETXID during thread exit.
|
||||
|
||||
The new test sysdeps/pthread/tst-pthread-setuid-loop.c is based on
|
||||
a downstream test by Martin Osvald.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
Tested-by: Carlos O'Donell <carlos@redhat.com>
|
||||
(cherry picked from commit 2849e2f53311b66853cb5159b64cba2bddbfb854)
|
||||
|
||||
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
|
||||
index 33b426fc682300dc..bc213f0bc4e948bd 100644
|
||||
--- a/nptl/pthread_create.c
|
||||
+++ b/nptl/pthread_create.c
|
||||
@@ -488,8 +488,16 @@ start_thread (void *arg)
|
||||
|
||||
/* This prevents sending a signal from this thread to itself during
|
||||
its final stages. This must come after the exit call above
|
||||
- because atexit handlers must not run with signals blocked. */
|
||||
- __libc_signal_block_all (NULL);
|
||||
+ because atexit handlers must not run with signals blocked.
|
||||
+
|
||||
+ Do not block SIGSETXID. The setxid handshake below expects the
|
||||
+ signal to be delivered. (SIGSETXID cannot run application code,
|
||||
+ nor does it use pthread_kill.) Reuse the pd->sigmask space for
|
||||
+ computing the signal mask, to save stack space. */
|
||||
+ __sigfillset (&pd->sigmask);
|
||||
+ __sigdelset (&pd->sigmask, SIGSETXID);
|
||||
+ INTERNAL_SYSCALL_CALL (rt_sigprocmask, SIG_BLOCK, &pd->sigmask, NULL,
|
||||
+ __NSIG_BYTES);
|
||||
|
||||
/* Tell __pthread_kill_internal that this thread is about to exit.
|
||||
If there is a __pthread_kill_internal in progress, this delays
|
||||
diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile
|
||||
index 48dba717a1cdc20a..d4bd2d4e3ee6a496 100644
|
||||
--- a/sysdeps/pthread/Makefile
|
||||
+++ b/sysdeps/pthread/Makefile
|
||||
@@ -118,6 +118,7 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \
|
||||
tst-unload \
|
||||
tst-unwind-thread \
|
||||
tst-pt-vfork1 tst-pt-vfork2 tst-vfork1x tst-vfork2x \
|
||||
+ tst-pthread-setuid-loop \
|
||||
tst-pthread_cancel-exited \
|
||||
tst-pthread_cancel-select-loop \
|
||||
tst-pthread_kill-exited \
|
||||
diff --git a/sysdeps/pthread/tst-pthread-setuid-loop.c b/sysdeps/pthread/tst-pthread-setuid-loop.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..fda2a49b7f0ccf81
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/pthread/tst-pthread-setuid-loop.c
|
||||
@@ -0,0 +1,61 @@
|
||||
+/* Test that setuid, pthread_create, thread exit do not deadlock (bug 28361).
|
||||
+ 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 <support/check.h>
|
||||
+#include <support/xthread.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+/* How many threads to launch during each iteration. */
|
||||
+enum { threads = 4 };
|
||||
+
|
||||
+/* How many iterations to perform. This value seems to reproduce
|
||||
+ bug 28361 in a bout one in three runs. */
|
||||
+enum { iterations = 5000 };
|
||||
+
|
||||
+/* Cache of the real user ID used by setuid_thread. */
|
||||
+static uid_t uid;
|
||||
+
|
||||
+/* Start routine for the threads. */
|
||||
+static void *
|
||||
+setuid_thread (void *closure)
|
||||
+{
|
||||
+ TEST_COMPARE (setuid (uid), 0);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ /* The setxid machinery is still invoked even if the UID is
|
||||
+ unchanged. (The kernel might reset other credentials as part of
|
||||
+ the system call.) */
|
||||
+ uid = getuid ();
|
||||
+
|
||||
+ for (int i = 0; i < iterations; ++i)
|
||||
+ {
|
||||
+ pthread_t thread_ids[threads];
|
||||
+ for (int j = 0; j < threads; ++j)
|
||||
+ thread_ids[j] = xpthread_create (NULL, setuid_thread, NULL);
|
||||
+ for (int j = 0; j < threads; ++j)
|
||||
+ xpthread_join (thread_ids[j]);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
25
glibc.spec
25
glibc.spec
@ -151,7 +151,7 @@ end \
|
||||
Summary: The GNU libc libraries
|
||||
Name: glibc
|
||||
Version: %{glibcversion}
|
||||
Release: 5%{?dist}
|
||||
Release: 6%{?dist}
|
||||
|
||||
# In general, GPLv2+ is used by programs, LGPLv2+ is used for
|
||||
# libraries.
|
||||
@ -251,9 +251,15 @@ Patch48: glibc-upstream-2.34-17.patch
|
||||
Patch49: glibc-upstream-2.34-18.patch
|
||||
Patch50: glibc-upstream-2.34-19.patch
|
||||
Patch51: glibc-upstream-2.34-20.patch
|
||||
Patch52: glibc-rh1992702-1.patch
|
||||
Patch53: glibc-rh1992702-2.patch
|
||||
Patch54: glibc-rh1992702-3.patch
|
||||
Patch52: glibc-upstream-2.34-21.patch
|
||||
Patch53: glibc-upstream-2.34-22.patch
|
||||
Patch54: glibc-upstream-2.34-23.patch
|
||||
Patch55: glibc-upstream-2.34-24.patch
|
||||
Patch56: glibc-upstream-2.34-25.patch
|
||||
Patch57: glibc-upstream-2.34-26.patch
|
||||
Patch1001: glibc-rh1992702-1.patch
|
||||
Patch1002: glibc-rh1992702-2.patch
|
||||
Patch1003: glibc-rh1992702-3.patch
|
||||
|
||||
##############################################################################
|
||||
# Continued list of core "glibc" package information:
|
||||
@ -2285,6 +2291,17 @@ fi
|
||||
%files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared
|
||||
|
||||
%changelog
|
||||
* Thu Sep 23 2021 Florian Weimer <fweimer@redhat.com> - 2.34-6
|
||||
- Sync with upstream branch release/2.34/master,
|
||||
commit 33adeaa3e2b9143c38884bc5aa65ded222ed274e:
|
||||
- nptl: Avoid setxid deadlock with blocked signals in thread exit [BZ #28361]
|
||||
- Use support_open_dev_null_range io/tst-closefrom, misc/tst-close_range, and
|
||||
posix/tst-spawn5 (BZ #28260)
|
||||
- support: Add support_open_dev_null_range
|
||||
- nptl: Fix type of pthread_mutexattr_getrobust_np,
|
||||
pthread_mutexattr_setrobust_np (bug 28036)
|
||||
- nptl: pthread_kill needs to return ESRCH for old programs (bug 19193)
|
||||
|
||||
* Wed Sep 15 2021 Florian Weimer <fweimer@redhat.com> - 2.34-5
|
||||
- Use system CPU count for sysconf(_SC_NPROCESSORS_*) (#1992702)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user