forked from rpms/glibc
141 lines
6.1 KiB
Diff
141 lines
6.1 KiB
Diff
commit 6a04404521ac4119ae36827eeb288ea84eee7cf6
|
|
Author: Florian Weimer <fweimer@redhat.com>
|
|
Date: Sat Feb 17 09:17:04 2024 +0100
|
|
|
|
Linux: Switch back to assembly syscall wrapper for prctl (bug 29770)
|
|
|
|
Commit ff026950e280bc3e9487b41b460fb31bc5b57721 ("Add a C wrapper for
|
|
prctl [BZ #25896]") replaced the assembler wrapper with a C function.
|
|
However, on powerpc64le-linux-gnu, the C variadic function
|
|
implementation requires extra work in the caller to set up the
|
|
parameter save area. Calling a function that needs a parameter save
|
|
area without one (because the prototype used indicates the function is
|
|
not variadic) corrupts the caller's stack. The Linux manual pages
|
|
project documents prctl as a non-variadic function. This has resulted
|
|
in various projects over the years using non-variadic prototypes,
|
|
including the sanitizer libraries in LLVm and GCC (GCC PR 113728).
|
|
|
|
This commit switches back to the assembler implementation on most
|
|
targets and only keeps the C implementation for x86-64 x32.
|
|
|
|
Also add the __prctl_time64 alias from commit
|
|
b39ffab860cd743a82c91946619f1b8158b0b65e ("Linux: Add time64 alias for
|
|
prctl") to sysdeps/unix/sysv/linux/syscalls.list; it was not yet
|
|
present in commit ff026950e280bc3e9487b41b460fb31bc5b57721.
|
|
|
|
This restores the old ABI on powerpc64le-linux-gnu, thus fixing
|
|
bug 29770.
|
|
|
|
Reviewed-By: Simon Chopin <simon.chopin@canonical.com>
|
|
|
|
Resolved conflicts:
|
|
sysdeps/unix/sysv/linux/syscalls.list
|
|
sysdeps/unix/sysv/linux/x86_64/x32/prctl.c
|
|
|
|
diff -Nrup a/sysdeps/unix/sysv/linux/prctl.c b/sysdeps/unix/sysv/linux/prctl.c
|
|
--- a/sysdeps/unix/sysv/linux/prctl.c 2021-08-01 21:33:43.000000000 -0400
|
|
+++ b/sysdeps/unix/sysv/linux/prctl.c 1969-12-31 19:00:00.000000000 -0500
|
|
@@ -1,45 +0,0 @@
|
|
-/* prctl - Linux specific syscall.
|
|
- Copyright (C) 2020-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 <sysdep.h>
|
|
-#include <stdarg.h>
|
|
-#include <sys/prctl.h>
|
|
-
|
|
-/* Unconditionally read all potential arguments. This may pass
|
|
- garbage values to the kernel, but avoids the need for teaching
|
|
- glibc the argument counts of individual options (including ones
|
|
- that are added to the kernel in the future). */
|
|
-
|
|
-int
|
|
-__prctl (int option, ...)
|
|
-{
|
|
- va_list arg;
|
|
- va_start (arg, option);
|
|
- unsigned long int arg2 = va_arg (arg, unsigned long int);
|
|
- unsigned long int arg3 = va_arg (arg, unsigned long int);
|
|
- unsigned long int arg4 = va_arg (arg, unsigned long int);
|
|
- unsigned long int arg5 = va_arg (arg, unsigned long int);
|
|
- va_end (arg);
|
|
- return INLINE_SYSCALL_CALL (prctl, option, arg2, arg3, arg4, arg5);
|
|
-}
|
|
-
|
|
-libc_hidden_def (__prctl)
|
|
-weak_alias (__prctl, prctl)
|
|
-#if __TIMESIZE != 64
|
|
-weak_alias (__prctl, __prctl_time64)
|
|
-#endif
|
|
diff -Nrup a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
|
|
--- a/sysdeps/unix/sysv/linux/syscalls.list 2021-08-01 21:33:43.000000000 -0400
|
|
+++ b/sysdeps/unix/sysv/linux/syscalls.list 2024-02-27 14:33:01.594782897 -0500
|
|
@@ -41,6 +41,7 @@ munlockall - munlockall i: munlockall
|
|
nfsservctl EXTRA nfsservctl i:ipp __compat_nfsservctl nfsservctl@GLIBC_2.0:GLIBC_2.28
|
|
pipe - pipe i:f __pipe pipe
|
|
pipe2 - pipe2 i:fi __pipe2 pipe2
|
|
+prctl EXTRA prctl i:iiiii __prctl prctl __prctl_time64
|
|
pivot_root EXTRA pivot_root i:ss pivot_root
|
|
query_module EXTRA query_module i:sipip __compat_query_module query_module@GLIBC_2.0:GLIBC_2.23
|
|
quotactl EXTRA quotactl i:isip quotactl
|
|
diff -Nrup a/sysdeps/unix/sysv/linux/x86_64/x32/prctl.c b/sysdeps/unix/sysv/linux/x86_64/x32/prctl.c
|
|
--- a/sysdeps/unix/sysv/linux/x86_64/x32/prctl.c 1969-12-31 19:00:00.000000000 -0500
|
|
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/prctl.c 2024-02-27 14:35:03.388602623 -0500
|
|
@@ -0,0 +1,42 @@
|
|
+/* prctl - Linux specific syscall. x86-64 x32 version.
|
|
+ Copyright (C) 2020-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 <sysdep.h>
|
|
+#include <stdarg.h>
|
|
+#include <sys/prctl.h>
|
|
+
|
|
+/* Unconditionally read all potential arguments. This may pass
|
|
+ garbage values to the kernel, but avoids the need for teaching
|
|
+ glibc the argument counts of individual options (including ones
|
|
+ that are added to the kernel in the future). */
|
|
+
|
|
+int
|
|
+__prctl (int option, ...)
|
|
+{
|
|
+ va_list arg;
|
|
+ va_start (arg, option);
|
|
+ unsigned long int arg2 = va_arg (arg, unsigned long int);
|
|
+ unsigned long int arg3 = va_arg (arg, unsigned long int);
|
|
+ unsigned long int arg4 = va_arg (arg, unsigned long int);
|
|
+ unsigned long int arg5 = va_arg (arg, unsigned long int);
|
|
+ va_end (arg);
|
|
+ return INLINE_SYSCALL_CALL (prctl, option, arg2, arg3, arg4, arg5);
|
|
+}
|
|
+
|
|
+libc_hidden_def (__prctl)
|
|
+weak_alias (__prctl, prctl)
|