diff --git a/glibc.spec b/glibc.spec index 564e1a043b3732dc6c7233ab69177b4ca6e4974e..5e984c94d5236a3ac122bed14098b9f1a21f7574 100644 --- a/glibc.spec +++ b/glibc.spec @@ -139,6 +139,7 @@ Patch55: backport-ldconfig-avoid-leak-on-empty-paths-in-config-file.patch Patch56: backport-rtld-copy-terminating-null-in-tunables_strdup-bug-28.patch Patch57: backport-gconv-Do-not-emit-spurious-NUL-character-in-ISO-2022.patch Patch58: backport-nss-make-sure-startp_initialized-do-first.patch +Patch59: move-syscall-getpid-into-VDSO.patch Provides: ldconfig rtld(GNU_HASH) bundled(gnulib) diff --git a/move-syscall-getpid-into-VDSO.patch b/move-syscall-getpid-into-VDSO.patch new file mode 100644 index 0000000000000000000000000000000000000000..0d384a7a946aae930e6c6aafec9ab52cdb8bd440 --- /dev/null +++ b/move-syscall-getpid-into-VDSO.patch @@ -0,0 +1,105 @@ +From df6037caf21df6102ba56abbfbd22417438fb9cd Mon Sep 17 00:00:00 2001 +From: Yang Yanchao +Date: Tue, 12 Oct 2021 10:56:58 +0800 +Subject: [PATCH] move the syscall getpid into VDSO + +early in program startup, the program uses _dl_vdso_vsym to load the +wrong address,cause getpid call fails. There is also a __getpid() +before setup_vdso, which is called before the vdso.so is loaded. +Trigger scenario: +LD_DEBUG=files LD_DEBUG_OUTPUT=/home/test.c ls +LD_DEBUG=files ls +These correspond to two different call points + +--- + elf/dl-misc.c | 2 +- + elf/rtld.c | 2 +- + sysdeps/unix/sysv/linux/x86/getpid.c | 50 ++++++++++++++++++++++++++++ + 3 files changed, 52 insertions(+), 2 deletions(-) + create mode 100644 sysdeps/unix/sysv/linux/x86/getpid.c + +diff --git a/elf/dl-misc.c b/elf/dl-misc.c +index 2eb81eeb..3a851ba3 100644 +--- a/elf/dl-misc.c ++++ b/elf/dl-misc.c +@@ -94,7 +94,7 @@ _dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg) + if (pid == 0) + { + char *p; +- pid = __getpid (); ++ pid = INLINE_SYSCALL (getpid, 0); + assert (pid >= 0 && sizeof (pid_t) <= 4); + p = _itoa (pid, &pidbuf[10], 10, 0); + while (p > pidbuf) +diff --git a/elf/rtld.c b/elf/rtld.c +index b9077441..d5c1f056 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -2675,7 +2675,7 @@ process_envvars (enum mode *modep) + char *startp; + + buf[name_len + 11] = '\0'; +- startp = _itoa (__getpid (), &buf[name_len + 11], 10, 0); ++ startp = _itoa (INLINE_SYSCALL (getpid, 0), &buf[name_len + 11], 10, 0); + *--startp = '.'; + startp = memcpy (startp - name_len, debug_output, name_len); + +diff --git a/sysdeps/unix/sysv/linux/x86/getpid.c b/sysdeps/unix/sysv/linux/x86/getpid.c +new file mode 100644 +index 00000000..27e7d09e +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/x86/getpid.c +@@ -0,0 +1,50 @@ ++/* Copyright (C) 1991-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 ++ . */ ++ ++#include ++#include ++ ++#ifdef SHARED ++ ++# include ++ ++static int ++__getpid_syscall (void) ++{ ++ return INLINE_SYSCALL (getpid, 0); ++} ++ ++# undef INIT_ARCH ++# define INIT_ARCH() PREPARE_VERSION_KNOWN (linux26, LINUX_2_6) ++/* If the vDSO is not available we fall back to syscall. */ ++libc_ifunc_hidden (__getpid, __getpid, ++ (_dl_vdso_vsym ("__vdso_getpid", &linux26) ++ ?: &__getpid_syscall)) ++libc_hidden_def (__getpid) ++ ++#else ++ ++int ++__getpid (void) ++{ ++ return INLINE_SYSCALL (getpid, 0); ++} ++libc_hidden_def (__getpid) ++ ++#endif ++weak_alias (__getpid, getpid) ++libc_hidden_weak (getpid) +-- +2.27.0 +