You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
141 lines
6.1 KiB
141 lines
6.1 KiB
1 month ago
|
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)
|