Message ID | 20171230184441.25392-3-aurelien@aurel32.net |
---|---|
State | New |
Headers | show |
Series | Alpha: Fix getrlimit/setrlimit with RLIM_INFINITY | expand |
On 30/12/2017 16:44, Aurelien Jarno wrote: > Fix the RLIM_INFINITY and RLIM64_INFINITY constants on alpha to match > the kernel one and all other architectures. Change the getrlimit, > getrlimit64, setrlimit, setrlimit64 into old compat symbols, and provide > the Linux generic functions as GLIBC_2_27 version. > > Note that the alpha implementation does not include the generic > getrlimit64.c or setrlimit64.c as they: > - redefine SHLIB_COMPAT when __RLIM_T_MATCHES_RLIM64_T == 1 > - redefine getrlimit or setrlimit, not allowing to rename them into > __new_getrlimit or __new_setrlimit. I think we can work this around to avoid code duplication with the following patch (based on this one plus the previous one you posted). Basically: * it adds a new define, USE_VERSIONED_RLIMIT, which supress the alias to the exported symbols on generic implementation (since alpha will add the versioned one instead). * it simplifies the SHLIB_COMPAT macros on alpha since there is no need to check for both GLIBC_2_0 and GLIBC_2_1 (it is already an arch-specific file which assumes an already defined ABI, in this case GLIBC_2_0). * it adds a weak_alias alias between __getrlimit64 and __GI_getrlimit64 for alpha case to follow generic case with libc_hidden_weak definition. What do you think? --- diff --git a/sysdeps/unix/sysv/linux/alpha/getrlimit64.c b/sysdeps/unix/sysv/linux/alpha/getrlimit64.c index 25cf4aa..d8ac917 100644 --- a/sysdeps/unix/sysv/linux/alpha/getrlimit64.c +++ b/sysdeps/unix/sysv/linux/alpha/getrlimit64.c @@ -15,40 +15,12 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include <errno.h> -#include <sys/types.h> -#include <shlib-compat.h> - -/* Add this redirection so the strong_alias for __RLIM_T_MATCHES_RLIM64_T - linking getrlimit64 to {__}getrlimit does not throw a type error. */ -#undef getrlimit -#undef __getrlimit -#define getrlimit getrlimit_redirect -#define __getrlimit __getrlimit_redirect -#include <sys/resource.h> -#undef getrlimit -#undef __getrlimit - - -/* Put the soft and hard limits for RESOURCE in *RLIMITS. - Returns 0 if successful, -1 if not (and sets errno). */ -int -__getrlimit64 (enum __rlimit_resource resource, struct rlimit64 *rlimits) -{ - return INLINE_SYSCALL_CALL (prlimit64, 0, resource, NULL, rlimits); -} -libc_hidden_def (__getrlimit64) - -strong_alias (__getrlimit64, __GI_getrlimit) -strong_alias (__getrlimit64, __GI_getrlimit64) -strong_alias (__getrlimit64, __GI___getrlimit) -strong_alias (__getrlimit64, __getrlimit) - +#define USE_VERSIONED_RLIMIT +#include <sysdeps/unix/sysv/linux/getrlimit64.c> versioned_symbol (libc, __getrlimit, getrlimit, GLIBC_2_27); versioned_symbol (libc, __getrlimit64, getrlimit64, GLIBC_2_27); -#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_27) \ - || SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_27) +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_27) /* RLIM64_INFINITY was supposed to be a glibc convention rather than anything seen by the kernel, but it ended being passed to the kernel through the prlimit64 syscall. Given that a lot of binaries with @@ -78,11 +50,7 @@ __old_getrlimit64 (enum __rlimit_resource resource, return 0; } -# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_27) strong_alias (__old_getrlimit64, __old_getrlimit) compat_symbol (libc, __old_getrlimit, getrlimit, GLIBC_2_0); -# endif -# if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_27) compat_symbol (libc, __old_getrlimit64, getrlimit64, GLIBC_2_1); -# endif #endif diff --git a/sysdeps/unix/sysv/linux/alpha/setrlimit64.c b/sysdeps/unix/sysv/linux/alpha/setrlimit64.c index b8074d2..1735f68 100644 --- a/sysdeps/unix/sysv/linux/alpha/setrlimit64.c +++ b/sysdeps/unix/sysv/linux/alpha/setrlimit64.c @@ -15,38 +15,12 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include <errno.h> -#include <sys/types.h> -#include <shlib-compat.h> - -/* Add this redirection so the strong_alias for __RLIM_T_MATCHES_RLIM64_T - linking setrlimit64 to {__}setrlimit does not throw a type error. */ -#undef setrlimit -#undef __setrlimit -#define setrlimit setrlimit_redirect -#define __setrlimit __setrlimit_redirect -#include <sys/resource.h> -#undef setrlimit -#undef __setrlimit - -/* Set the soft and hard limits for RESOURCE to *RLIMITS. - Only the super-user can increase hard limits. - Return 0 if successful, -1 if not (and sets errno). */ -int -__setrlimit64 (enum __rlimit_resource resource, const struct rlimit64 *rlimits) -{ - return INLINE_SYSCALL_CALL (prlimit64, 0, resource, rlimits, NULL); -} -strong_alias (__setrlimit64, __setrlimit) -# ifdef SHARED -__hidden_ver1 (__setrlimit64, __GI___setrlimit, __setrlimit64); -# endif - +#define USE_VERSIONED_RLIMIT +#include <sysdeps/unix/sysv/linux/setrlimit64.c> versioned_symbol (libc, __setrlimit, setrlimit, GLIBC_2_27); versioned_symbol (libc, __setrlimit64, setrlimit64, GLIBC_2_27); -#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_27) \ - || SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_27) +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_27) /* RLIM64_INFINITY was supposed to be a glibc convention rather than anything seen by the kernel, but it ended being passed to the kernel through the prlimit64 syscall. Given that a lot of binaries with @@ -73,11 +47,7 @@ __old_setrlimit64 (enum __rlimit_resource resource, return __setrlimit64 (resource, &krlimits); } -# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_27) strong_alias (__old_setrlimit64, __old_setrlimit) compat_symbol (libc, __old_setrlimit, setrlimit, GLIBC_2_0); -# endif -# if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_27) compat_symbol (libc, __old_setrlimit64, setrlimit64, GLIBC_2_1); -# endif #endif diff --git a/sysdeps/unix/sysv/linux/getrlimit64.c b/sysdeps/unix/sysv/linux/getrlimit64.c index 37827e5..d14fc63 100644 --- a/sysdeps/unix/sysv/linux/getrlimit64.c +++ b/sysdeps/unix/sysv/linux/getrlimit64.c @@ -45,13 +45,16 @@ libc_hidden_def (__getrlimit64) strong_alias (__getrlimit64, __GI_getrlimit) strong_alias (__getrlimit64, __GI___getrlimit) strong_alias (__getrlimit64, __getrlimit) +/* Alpha defines a versioned getrlimit{64}. */ +# ifndef USE_VERSIONED_RLIMIT weak_alias (__getrlimit64, getrlimit) -/* And there is no need for compat symbols. */ -# undef SHLIB_COMPAT -# define SHLIB_COMPAT(a, b, c) 0 -#endif +weak_alias (__getrlimit64, getrlimit64) +libc_hidden_weak (getrlimit64) +# else +weak_alias (__getrlimit64, __GI_getrlimit64) +# endif -#if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_2) +#elif if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_2) /* Back compatible 2GiB limited rlimit. */ extern int __new_getrlimit (enum __rlimit_resource, struct rlimit *) attribute_hidden; @@ -82,7 +85,4 @@ __old_getrlimit64 (enum __rlimit_resource resource, struct rlimit64 *rlimits) } versioned_symbol (libc, __getrlimit64, getrlimit64, GLIBC_2_2); compat_symbol (libc, __old_getrlimit64, getrlimit64, GLIBC_2_1); -#else -weak_alias (__getrlimit64, getrlimit64) -libc_hidden_weak (getrlimit64) -#endif +#endif /* __RLIM_T_MATCHES_RLIM64_T */ diff --git a/sysdeps/unix/sysv/linux/setrlimit64.c b/sysdeps/unix/sysv/linux/setrlimit64.c index ff835c8..0f5cc85 100644 --- a/sysdeps/unix/sysv/linux/setrlimit64.c +++ b/sysdeps/unix/sysv/linux/setrlimit64.c @@ -38,11 +38,16 @@ __setrlimit64 (enum __rlimit_resource resource, const struct rlimit64 *rlimits) { return INLINE_SYSCALL_CALL (prlimit64, 0, resource, rlimits, NULL); } +/* Alpha defines a versioned setrlimit{64}. */ +#ifndef USE_VERSIONED_RLIMIT weak_alias (__setrlimit64, setrlimit64) +#endif #if __RLIM_T_MATCHES_RLIM64_T strong_alias (__setrlimit64, __setrlimit) +# ifndef USE_VERSIONED_RLIMIT weak_alias (__setrlimit64, setrlimit) +# endif # ifdef SHARED __hidden_ver1 (__setrlimit64, __GI___setrlimit, __setrlimit64); # endif --- > > Changelog: > * sysdeps/unix/sysv/linux/alpha/bits/resource.h (RLIM_INFINITY, > RLIM64_INFINITY): Fix values to match the kernel ones. > * sysdeps/unix/sysv/linux/alpha/getrlimit64.c: Rename __getrlimit64 > into __old_getrlimit64 and provide it as getrlimit@@GLIBC_2_0 and > getrlimit64@@GLIBC_2_1. Add a __getrlimit64 function and provide it > as getrlimit@@GLIBC_2_27 and getrlimit64@@GLIBC_2_27. > * sysdeps/unix/sysv/linux/alpha/setrlimit64.c: Ditto with setrlimit > and setrlimit64. > * sysdeps/unix/sysv/linux/alpha/libc.abilist (GLIBC_2.27): Add > getrlimit, setrlimit, getrlimit64 and setrlimit64. > * sysdeps/unix/sysv/linux/alpha/Versions (libc): Add getrlimit, > setrlimit, getrlimit64 and setrlimit64. > --- > ChangeLog | 15 +++++++ > sysdeps/unix/sysv/linux/alpha/Versions | 3 ++ > sysdeps/unix/sysv/linux/alpha/bits/resource.h | 6 +-- > sysdeps/unix/sysv/linux/alpha/getrlimit64.c | 56 +++++++++++++++++++-------- > sysdeps/unix/sysv/linux/alpha/libc.abilist | 4 ++ > sysdeps/unix/sysv/linux/alpha/setrlimit64.c | 52 ++++++++++++++++++------- > 6 files changed, 102 insertions(+), 34 deletions(-) > > diff --git a/ChangeLog b/ChangeLog > index 433b10145d..1e8740530d 100644 > --- a/ChangeLog > +++ b/ChangeLog > @@ -1,3 +1,18 @@ > +2017-12-30 Aurelien Jarno <aurelien@aurel32.net> > + > + * sysdeps/unix/sysv/linux/alpha/bits/resource.h (RLIM_INFINITY, > + RLIM64_INFINITY): Fix values to match the kernel ones. > + * sysdeps/unix/sysv/linux/alpha/getrlimit64.c: Rename __getrlimit64 > + into __old_getrlimit64 and provide it as getrlimit@@GLIBC_2_0 and > + getrlimit64@@GLIBC_2_1. Add a __getrlimit64 function and provide it > + as getrlimit@@GLIBC_2_27 and getrlimit64@@GLIBC_2_27. > + * sysdeps/unix/sysv/linux/alpha/setrlimit64.c: Ditto with setrlimit > + and setrlimit64. > + * sysdeps/unix/sysv/linux/alpha/libc.abilist (GLIBC_2.27): Add > + getrlimit, setrlimit, getrlimit64 and setrlimit64. > + * sysdeps/unix/sysv/linux/alpha/Versions (libc): Add getrlimit, > + setrlimit, getrlimit64 and setrlimit64. > + > 2017-12-30 Aurelien Jarno <aurelien@aurel32.net> > > [BZ #22648] > diff --git a/sysdeps/unix/sysv/linux/alpha/Versions b/sysdeps/unix/sysv/linux/alpha/Versions > index 29b82f999b..3b7971c2a3 100644 > --- a/sysdeps/unix/sysv/linux/alpha/Versions > +++ b/sysdeps/unix/sysv/linux/alpha/Versions > @@ -85,6 +85,9 @@ libc { > #errlist-compat 140 > _sys_errlist; sys_errlist; _sys_nerr; sys_nerr; > } > + GLIBC_2.27 { > + getrlimit; setrlimit; getrlimit64; setrlimit64; > + } > GLIBC_PRIVATE { > __libc_alpha_cache_shape; > } Ok. > diff --git a/sysdeps/unix/sysv/linux/alpha/bits/resource.h b/sysdeps/unix/sysv/linux/alpha/bits/resource.h > index bd5142caa4..749703b716 100644 > --- a/sysdeps/unix/sysv/linux/alpha/bits/resource.h > +++ b/sysdeps/unix/sysv/linux/alpha/bits/resource.h > @@ -112,13 +112,13 @@ enum __rlimit_resource > > /* Value to indicate that there is no limit. */ > #ifndef __USE_FILE_OFFSET64 > -# define RLIM_INFINITY ((long int)(~0UL >> 1)) > +# define RLIM_INFINITY ((__rlim_t) -1) > #else > -# define RLIM_INFINITY 0x7fffffffffffffffLL > +# define RLIM_INFINITY 0xffffffffffffffffuLL > #endif > > #ifdef __USE_LARGEFILE64 > -# define RLIM64_INFINITY 0x7fffffffffffffffLL > +# define RLIM64_INFINITY 0xffffffffffffffffuLL > #endif > > /* We can represent all limits. */ Ok. > diff --git a/sysdeps/unix/sysv/linux/alpha/getrlimit64.c b/sysdeps/unix/sysv/linux/alpha/getrlimit64.c > index ad398a136f..25cf4aa555 100644 > --- a/sysdeps/unix/sysv/linux/alpha/getrlimit64.c > +++ b/sysdeps/unix/sysv/linux/alpha/getrlimit64.c > @@ -17,9 +17,10 @@ > > #include <errno.h> > #include <sys/types.h> > +#include <shlib-compat.h> > > -/* Add this redirection so the strong_alias linking getrlimit64 to > - {__}getrlimit does not throw a type error. */ > +/* Add this redirection so the strong_alias for __RLIM_T_MATCHES_RLIM64_T > + linking getrlimit64 to {__}getrlimit does not throw a type error. */ > #undef getrlimit > #undef __getrlimit > #define getrlimit getrlimit_redirect > @@ -28,37 +29,60 @@ > #undef getrlimit > #undef __getrlimit > > + > +/* Put the soft and hard limits for RESOURCE in *RLIMITS. > + Returns 0 if successful, -1 if not (and sets errno). */ > +int > +__getrlimit64 (enum __rlimit_resource resource, struct rlimit64 *rlimits) > +{ > + return INLINE_SYSCALL_CALL (prlimit64, 0, resource, NULL, rlimits); > +} > +libc_hidden_def (__getrlimit64) > + > +strong_alias (__getrlimit64, __GI_getrlimit) > +strong_alias (__getrlimit64, __GI_getrlimit64) > +strong_alias (__getrlimit64, __GI___getrlimit) > +strong_alias (__getrlimit64, __getrlimit) > + > +versioned_symbol (libc, __getrlimit, getrlimit, GLIBC_2_27); > +versioned_symbol (libc, __getrlimit64, getrlimit64, GLIBC_2_27); > + > +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_27) \ > + || SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_27) > /* RLIM64_INFINITY was supposed to be a glibc convention rather than > anything seen by the kernel, but it ended being passed to the kernel > through the prlimit64 syscall. Given that a lot of binaries with > the wrong constant value are in the wild, provide a wrapper function > fixing the value after the syscall. */ > -#define KERNEL_RLIM64_INFINITY 0xffffffffffffffffULL > +# define OLD_RLIM64_INFINITY 0x7fffffffffffffffULL > > int > -__getrlimit64 (enum __rlimit_resource resource, struct rlimit64 *rlimits) > +attribute_compat_text_section > +__old_getrlimit64 (enum __rlimit_resource resource, > + struct rlimit64 *rlimits) > { > struct rlimit64 krlimits; > > - if (INLINE_SYSCALL_CALL (prlimit64, 0, resource, NULL, &krlimits) < 0) > + if (__getrlimit64 (resource, &krlimits) < 0) > return -1; > > - if (krlimits.rlim_cur == KERNEL_RLIM64_INFINITY) > - rlimits->rlim_cur = RLIM64_INFINITY; > + if (krlimits.rlim_cur == RLIM64_INFINITY) > + rlimits->rlim_cur = OLD_RLIM64_INFINITY; > else > rlimits->rlim_cur = krlimits.rlim_cur; > - if (krlimits.rlim_max == KERNEL_RLIM64_INFINITY) > - rlimits->rlim_max = RLIM64_INFINITY; > + if (krlimits.rlim_max == RLIM64_INFINITY) > + rlimits->rlim_max = OLD_RLIM64_INFINITY; > else > rlimits->rlim_max = krlimits.rlim_max; > > return 0; > } > -libc_hidden_def (__getrlimit64) > -strong_alias (__getrlimit64, __GI_getrlimit) > -strong_alias (__getrlimit64, __GI___getrlimit) > -strong_alias (__getrlimit64, __getrlimit) > -weak_alias (__getrlimit64, getrlimit) > > -weak_alias (__getrlimit64, getrlimit64) > -libc_hidden_weak (getrlimit64) > +# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_27) > +strong_alias (__old_getrlimit64, __old_getrlimit) > +compat_symbol (libc, __old_getrlimit, getrlimit, GLIBC_2_0); > +# endif > +# if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_27) > +compat_symbol (libc, __old_getrlimit64, getrlimit64, GLIBC_2_1); > +# endif > +#endif > diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist > index fd2d81fb68..8674a874b4 100644 > --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist > +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist > @@ -2016,6 +2016,8 @@ GLIBC_2.26 pwritev64v2 F > GLIBC_2.26 reallocarray F > GLIBC_2.27 GLIBC_2.27 A > GLIBC_2.27 copy_file_range F > +GLIBC_2.27 getrlimit F > +GLIBC_2.27 getrlimit64 F > GLIBC_2.27 glob F > GLIBC_2.27 glob64 F > GLIBC_2.27 memfd_create F > @@ -2025,6 +2027,8 @@ GLIBC_2.27 pkey_free F > GLIBC_2.27 pkey_get F > GLIBC_2.27 pkey_mprotect F > GLIBC_2.27 pkey_set F > +GLIBC_2.27 setrlimit F > +GLIBC_2.27 setrlimit64 F > GLIBC_2.27 strfromf128 F > GLIBC_2.27 strfromf32 F > GLIBC_2.27 strfromf32x F Ok. > diff --git a/sysdeps/unix/sysv/linux/alpha/setrlimit64.c b/sysdeps/unix/sysv/linux/alpha/setrlimit64.c > index a5f7907afd..b8074d2df6 100644 > --- a/sysdeps/unix/sysv/linux/alpha/setrlimit64.c > +++ b/sysdeps/unix/sysv/linux/alpha/setrlimit64.c > @@ -17,9 +17,10 @@ > > #include <errno.h> > #include <sys/types.h> > +#include <shlib-compat.h> > > -/* Add this redirection so the strong_alias linking setrlimit64 to > - {__}setrlimit does not throw a type error. */ > +/* Add this redirection so the strong_alias for __RLIM_T_MATCHES_RLIM64_T > + linking setrlimit64 to {__}setrlimit does not throw a type error. */ > #undef setrlimit > #undef __setrlimit > #define setrlimit setrlimit_redirect > @@ -28,34 +29,55 @@ > #undef setrlimit > #undef __setrlimit > > +/* Set the soft and hard limits for RESOURCE to *RLIMITS. > + Only the super-user can increase hard limits. > + Return 0 if successful, -1 if not (and sets errno). */ > +int > +__setrlimit64 (enum __rlimit_resource resource, const struct rlimit64 *rlimits) > +{ > + return INLINE_SYSCALL_CALL (prlimit64, 0, resource, rlimits, NULL); > +} > +strong_alias (__setrlimit64, __setrlimit) > +# ifdef SHARED > +__hidden_ver1 (__setrlimit64, __GI___setrlimit, __setrlimit64); > +# endif > + > +versioned_symbol (libc, __setrlimit, setrlimit, GLIBC_2_27); > +versioned_symbol (libc, __setrlimit64, setrlimit64, GLIBC_2_27); > + > +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_27) \ > + || SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_27) > /* RLIM64_INFINITY was supposed to be a glibc convention rather than > anything seen by the kernel, but it ended being passed to the kernel > through the prlimit64 syscall. Given that a lot of binaries with > the wrong constant value are in the wild, provide a wrapper function > fixing the value before the syscall. */ > -#define KERNEL_RLIM64_INFINITY 0xffffffffffffffffULL > +# define OLD_RLIM64_INFINITY 0x7fffffffffffffffULL > > int > -__setrlimit64 (enum __rlimit_resource resource, const struct rlimit64 *rlimits) > +attribute_compat_text_section > +__old_setrlimit64 (enum __rlimit_resource resource, > + const struct rlimit64 *rlimits) > { > struct rlimit64 krlimits; > > - if (rlimits->rlim_cur == RLIM64_INFINITY) > - krlimits.rlim_cur = KERNEL_RLIM64_INFINITY; > + if (rlimits->rlim_cur == OLD_RLIM64_INFINITY) > + krlimits.rlim_cur = RLIM64_INFINITY; > else > krlimits.rlim_cur = rlimits->rlim_cur; > - if (rlimits->rlim_max == RLIM64_INFINITY) > - krlimits.rlim_max = KERNEL_RLIM64_INFINITY; > + if (rlimits->rlim_max == OLD_RLIM64_INFINITY) > + krlimits.rlim_max = RLIM64_INFINITY; > else > krlimits.rlim_max = rlimits->rlim_max; > > - return INLINE_SYSCALL_CALL (prlimit64, 0, resource, &krlimits, NULL); > + return __setrlimit64 (resource, &krlimits); > } > > -weak_alias (__setrlimit64, setrlimit64) > - > -strong_alias (__setrlimit64, __setrlimit) > -weak_alias (__setrlimit64, setrlimit) > -#ifdef SHARED > -__hidden_ver1 (__setrlimit64, __GI___setrlimit, __setrlimit64); > +# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_27) > +strong_alias (__old_setrlimit64, __old_setrlimit) > +compat_symbol (libc, __old_setrlimit, setrlimit, GLIBC_2_0); > +# endif > +# if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_27) > +compat_symbol (libc, __old_setrlimit64, setrlimit64, GLIBC_2_1); > +# endif > #endif >
On 2017-12-31 17:33, Adhemerval Zanella wrote: > > > On 30/12/2017 16:44, Aurelien Jarno wrote: > > Fix the RLIM_INFINITY and RLIM64_INFINITY constants on alpha to match > > the kernel one and all other architectures. Change the getrlimit, > > getrlimit64, setrlimit, setrlimit64 into old compat symbols, and provide > > the Linux generic functions as GLIBC_2_27 version. > > > > Note that the alpha implementation does not include the generic > > getrlimit64.c or setrlimit64.c as they: > > - redefine SHLIB_COMPAT when __RLIM_T_MATCHES_RLIM64_T == 1 > > - redefine getrlimit or setrlimit, not allowing to rename them into > > __new_getrlimit or __new_setrlimit. > > I think we can work this around to avoid code duplication with the following > patch (based on this one plus the previous one you posted). Basically: > > * it adds a new define, USE_VERSIONED_RLIMIT, which supress the alias to the > exported symbols on generic implementation (since alpha will add the > versioned one instead). > > * it simplifies the SHLIB_COMPAT macros on alpha since there is no need to > check for both GLIBC_2_0 and GLIBC_2_1 (it is already an arch-specific > file which assumes an already defined ABI, in this case GLIBC_2_0). > > * it adds a weak_alias alias between __getrlimit64 and __GI_getrlimit64 > for alpha case to follow generic case with libc_hidden_weak definition. > > What do you think? Thanks, this looks all good to me, and works as expected. I am currently writing a test to catch this kind of issues. I'll send the new patches when it's done. I have already committed the patches 3 & 4. Aurelien
diff --git a/ChangeLog b/ChangeLog index 433b10145d..1e8740530d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2017-12-30 Aurelien Jarno <aurelien@aurel32.net> + + * sysdeps/unix/sysv/linux/alpha/bits/resource.h (RLIM_INFINITY, + RLIM64_INFINITY): Fix values to match the kernel ones. + * sysdeps/unix/sysv/linux/alpha/getrlimit64.c: Rename __getrlimit64 + into __old_getrlimit64 and provide it as getrlimit@@GLIBC_2_0 and + getrlimit64@@GLIBC_2_1. Add a __getrlimit64 function and provide it + as getrlimit@@GLIBC_2_27 and getrlimit64@@GLIBC_2_27. + * sysdeps/unix/sysv/linux/alpha/setrlimit64.c: Ditto with setrlimit + and setrlimit64. + * sysdeps/unix/sysv/linux/alpha/libc.abilist (GLIBC_2.27): Add + getrlimit, setrlimit, getrlimit64 and setrlimit64. + * sysdeps/unix/sysv/linux/alpha/Versions (libc): Add getrlimit, + setrlimit, getrlimit64 and setrlimit64. + 2017-12-30 Aurelien Jarno <aurelien@aurel32.net> [BZ #22648] diff --git a/sysdeps/unix/sysv/linux/alpha/Versions b/sysdeps/unix/sysv/linux/alpha/Versions index 29b82f999b..3b7971c2a3 100644 --- a/sysdeps/unix/sysv/linux/alpha/Versions +++ b/sysdeps/unix/sysv/linux/alpha/Versions @@ -85,6 +85,9 @@ libc { #errlist-compat 140 _sys_errlist; sys_errlist; _sys_nerr; sys_nerr; } + GLIBC_2.27 { + getrlimit; setrlimit; getrlimit64; setrlimit64; + } GLIBC_PRIVATE { __libc_alpha_cache_shape; } diff --git a/sysdeps/unix/sysv/linux/alpha/bits/resource.h b/sysdeps/unix/sysv/linux/alpha/bits/resource.h index bd5142caa4..749703b716 100644 --- a/sysdeps/unix/sysv/linux/alpha/bits/resource.h +++ b/sysdeps/unix/sysv/linux/alpha/bits/resource.h @@ -112,13 +112,13 @@ enum __rlimit_resource /* Value to indicate that there is no limit. */ #ifndef __USE_FILE_OFFSET64 -# define RLIM_INFINITY ((long int)(~0UL >> 1)) +# define RLIM_INFINITY ((__rlim_t) -1) #else -# define RLIM_INFINITY 0x7fffffffffffffffLL +# define RLIM_INFINITY 0xffffffffffffffffuLL #endif #ifdef __USE_LARGEFILE64 -# define RLIM64_INFINITY 0x7fffffffffffffffLL +# define RLIM64_INFINITY 0xffffffffffffffffuLL #endif /* We can represent all limits. */ diff --git a/sysdeps/unix/sysv/linux/alpha/getrlimit64.c b/sysdeps/unix/sysv/linux/alpha/getrlimit64.c index ad398a136f..25cf4aa555 100644 --- a/sysdeps/unix/sysv/linux/alpha/getrlimit64.c +++ b/sysdeps/unix/sysv/linux/alpha/getrlimit64.c @@ -17,9 +17,10 @@ #include <errno.h> #include <sys/types.h> +#include <shlib-compat.h> -/* Add this redirection so the strong_alias linking getrlimit64 to - {__}getrlimit does not throw a type error. */ +/* Add this redirection so the strong_alias for __RLIM_T_MATCHES_RLIM64_T + linking getrlimit64 to {__}getrlimit does not throw a type error. */ #undef getrlimit #undef __getrlimit #define getrlimit getrlimit_redirect @@ -28,37 +29,60 @@ #undef getrlimit #undef __getrlimit + +/* Put the soft and hard limits for RESOURCE in *RLIMITS. + Returns 0 if successful, -1 if not (and sets errno). */ +int +__getrlimit64 (enum __rlimit_resource resource, struct rlimit64 *rlimits) +{ + return INLINE_SYSCALL_CALL (prlimit64, 0, resource, NULL, rlimits); +} +libc_hidden_def (__getrlimit64) + +strong_alias (__getrlimit64, __GI_getrlimit) +strong_alias (__getrlimit64, __GI_getrlimit64) +strong_alias (__getrlimit64, __GI___getrlimit) +strong_alias (__getrlimit64, __getrlimit) + +versioned_symbol (libc, __getrlimit, getrlimit, GLIBC_2_27); +versioned_symbol (libc, __getrlimit64, getrlimit64, GLIBC_2_27); + +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_27) \ + || SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_27) /* RLIM64_INFINITY was supposed to be a glibc convention rather than anything seen by the kernel, but it ended being passed to the kernel through the prlimit64 syscall. Given that a lot of binaries with the wrong constant value are in the wild, provide a wrapper function fixing the value after the syscall. */ -#define KERNEL_RLIM64_INFINITY 0xffffffffffffffffULL +# define OLD_RLIM64_INFINITY 0x7fffffffffffffffULL int -__getrlimit64 (enum __rlimit_resource resource, struct rlimit64 *rlimits) +attribute_compat_text_section +__old_getrlimit64 (enum __rlimit_resource resource, + struct rlimit64 *rlimits) { struct rlimit64 krlimits; - if (INLINE_SYSCALL_CALL (prlimit64, 0, resource, NULL, &krlimits) < 0) + if (__getrlimit64 (resource, &krlimits) < 0) return -1; - if (krlimits.rlim_cur == KERNEL_RLIM64_INFINITY) - rlimits->rlim_cur = RLIM64_INFINITY; + if (krlimits.rlim_cur == RLIM64_INFINITY) + rlimits->rlim_cur = OLD_RLIM64_INFINITY; else rlimits->rlim_cur = krlimits.rlim_cur; - if (krlimits.rlim_max == KERNEL_RLIM64_INFINITY) - rlimits->rlim_max = RLIM64_INFINITY; + if (krlimits.rlim_max == RLIM64_INFINITY) + rlimits->rlim_max = OLD_RLIM64_INFINITY; else rlimits->rlim_max = krlimits.rlim_max; return 0; } -libc_hidden_def (__getrlimit64) -strong_alias (__getrlimit64, __GI_getrlimit) -strong_alias (__getrlimit64, __GI___getrlimit) -strong_alias (__getrlimit64, __getrlimit) -weak_alias (__getrlimit64, getrlimit) -weak_alias (__getrlimit64, getrlimit64) -libc_hidden_weak (getrlimit64) +# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_27) +strong_alias (__old_getrlimit64, __old_getrlimit) +compat_symbol (libc, __old_getrlimit, getrlimit, GLIBC_2_0); +# endif +# if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_27) +compat_symbol (libc, __old_getrlimit64, getrlimit64, GLIBC_2_1); +# endif +#endif diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index fd2d81fb68..8674a874b4 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -2016,6 +2016,8 @@ GLIBC_2.26 pwritev64v2 F GLIBC_2.26 reallocarray F GLIBC_2.27 GLIBC_2.27 A GLIBC_2.27 copy_file_range F +GLIBC_2.27 getrlimit F +GLIBC_2.27 getrlimit64 F GLIBC_2.27 glob F GLIBC_2.27 glob64 F GLIBC_2.27 memfd_create F @@ -2025,6 +2027,8 @@ GLIBC_2.27 pkey_free F GLIBC_2.27 pkey_get F GLIBC_2.27 pkey_mprotect F GLIBC_2.27 pkey_set F +GLIBC_2.27 setrlimit F +GLIBC_2.27 setrlimit64 F GLIBC_2.27 strfromf128 F GLIBC_2.27 strfromf32 F GLIBC_2.27 strfromf32x F diff --git a/sysdeps/unix/sysv/linux/alpha/setrlimit64.c b/sysdeps/unix/sysv/linux/alpha/setrlimit64.c index a5f7907afd..b8074d2df6 100644 --- a/sysdeps/unix/sysv/linux/alpha/setrlimit64.c +++ b/sysdeps/unix/sysv/linux/alpha/setrlimit64.c @@ -17,9 +17,10 @@ #include <errno.h> #include <sys/types.h> +#include <shlib-compat.h> -/* Add this redirection so the strong_alias linking setrlimit64 to - {__}setrlimit does not throw a type error. */ +/* Add this redirection so the strong_alias for __RLIM_T_MATCHES_RLIM64_T + linking setrlimit64 to {__}setrlimit does not throw a type error. */ #undef setrlimit #undef __setrlimit #define setrlimit setrlimit_redirect @@ -28,34 +29,55 @@ #undef setrlimit #undef __setrlimit +/* Set the soft and hard limits for RESOURCE to *RLIMITS. + Only the super-user can increase hard limits. + Return 0 if successful, -1 if not (and sets errno). */ +int +__setrlimit64 (enum __rlimit_resource resource, const struct rlimit64 *rlimits) +{ + return INLINE_SYSCALL_CALL (prlimit64, 0, resource, rlimits, NULL); +} +strong_alias (__setrlimit64, __setrlimit) +# ifdef SHARED +__hidden_ver1 (__setrlimit64, __GI___setrlimit, __setrlimit64); +# endif + +versioned_symbol (libc, __setrlimit, setrlimit, GLIBC_2_27); +versioned_symbol (libc, __setrlimit64, setrlimit64, GLIBC_2_27); + +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_27) \ + || SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_27) /* RLIM64_INFINITY was supposed to be a glibc convention rather than anything seen by the kernel, but it ended being passed to the kernel through the prlimit64 syscall. Given that a lot of binaries with the wrong constant value are in the wild, provide a wrapper function fixing the value before the syscall. */ -#define KERNEL_RLIM64_INFINITY 0xffffffffffffffffULL +# define OLD_RLIM64_INFINITY 0x7fffffffffffffffULL int -__setrlimit64 (enum __rlimit_resource resource, const struct rlimit64 *rlimits) +attribute_compat_text_section +__old_setrlimit64 (enum __rlimit_resource resource, + const struct rlimit64 *rlimits) { struct rlimit64 krlimits; - if (rlimits->rlim_cur == RLIM64_INFINITY) - krlimits.rlim_cur = KERNEL_RLIM64_INFINITY; + if (rlimits->rlim_cur == OLD_RLIM64_INFINITY) + krlimits.rlim_cur = RLIM64_INFINITY; else krlimits.rlim_cur = rlimits->rlim_cur; - if (rlimits->rlim_max == RLIM64_INFINITY) - krlimits.rlim_max = KERNEL_RLIM64_INFINITY; + if (rlimits->rlim_max == OLD_RLIM64_INFINITY) + krlimits.rlim_max = RLIM64_INFINITY; else krlimits.rlim_max = rlimits->rlim_max; - return INLINE_SYSCALL_CALL (prlimit64, 0, resource, &krlimits, NULL); + return __setrlimit64 (resource, &krlimits); } -weak_alias (__setrlimit64, setrlimit64) - -strong_alias (__setrlimit64, __setrlimit) -weak_alias (__setrlimit64, setrlimit) -#ifdef SHARED -__hidden_ver1 (__setrlimit64, __GI___setrlimit, __setrlimit64); +# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_27) +strong_alias (__old_setrlimit64, __old_setrlimit) +compat_symbol (libc, __old_setrlimit, setrlimit, GLIBC_2_0); +# endif +# if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_27) +compat_symbol (libc, __old_setrlimit64, setrlimit64, GLIBC_2_1); +# endif #endif