Message ID | 20190730123030.3376-4-adhemerval.zanella@linaro.org |
---|---|
State | New |
Headers | show |
Series | [v2,1/4] arm: Split BE/LE abilist | expand |
On Tue, 30 Jul 2019, Adhemerval Zanella wrote: > diff --git a/conform/data/sys/ipc.h-data b/conform/data/sys/ipc.h-data > index 09e8f68f8e..e6582c7cae 100644 > --- a/conform/data/sys/ipc.h-data > +++ b/conform/data/sys/ipc.h-data > @@ -7,7 +7,7 @@ xfail[i386-gnu]-element {struct ipc_perm} gid_t gid > xfail[i386-gnu]-element {struct ipc_perm} uid_t cuid > xfail[i386-gnu]-element {struct ipc_perm} gid_t cgid > // Bug 18231: wrong type for mode member. > -xfail-element {struct ipc_perm} mode_t mode > +xfail[i386-gnu]-element {struct ipc_perm} mode_t mode I wouldn't expect the Bug 18231 comment to remain when fixing this for non-Hurd, as Hurd is covered by bug 23082. -- Joseph S. Myers joseph@codesourcery.com
On 30/07/2019 16:53, Joseph Myers wrote: > On Tue, 30 Jul 2019, Adhemerval Zanella wrote: > >> diff --git a/conform/data/sys/ipc.h-data b/conform/data/sys/ipc.h-data >> index 09e8f68f8e..e6582c7cae 100644 >> --- a/conform/data/sys/ipc.h-data >> +++ b/conform/data/sys/ipc.h-data >> @@ -7,7 +7,7 @@ xfail[i386-gnu]-element {struct ipc_perm} gid_t gid >> xfail[i386-gnu]-element {struct ipc_perm} uid_t cuid >> xfail[i386-gnu]-element {struct ipc_perm} gid_t cgid >> // Bug 18231: wrong type for mode member. >> -xfail-element {struct ipc_perm} mode_t mode >> +xfail[i386-gnu]-element {struct ipc_perm} mode_t mode > > I wouldn't expect the Bug 18231 comment to remain when fixing this for > non-Hurd, as Hurd is covered by bug 23082. > Right, I removed the comment.
Ping, with Joseph's comment removal applied. On 30/07/2019 09:30, Adhemerval Zanella wrote: > Changes from previous version: > > - Add m68k ABIs. > > - XFAIL ipc_perm mode on conform/data/sys/ipc.h-data just for Hurd. > > -- > > This patch sets the mode field in ipc_perm as mode_t for all architectures, > as POSIX specification [1]. The changes required are as follow: > > 1. It moves the ipc_perm definition out of ipc.h to its own header > ipc_perm.h. It also allows consolidate the IPC_* definition on > only one header. > > 2. The generic implementation follow the kernel ipc64_perm size so the > syscall can be made directly without temporary buffer copy. However, > since glibc defines the MODE field as mode_t, it omits the __PAD1 field > (since glibc does not export mode_t as 16-bit for any architecture). > > It is a two-fold improvement: > > 2.1. New implementation which follow Linux UAPI will not need to > provide an arch-specific ipc-perm.h header neither wrongly > use the wrong 16-bit definition from previous default ipc.h > (as csky did). > > 2.1. It allows consolidate ipc_perm definition for architectures that > already provide mode_t as 32-bit. > > 3. All kernel ABIs for the supported architectures already provides the > expected padding for mode type extension to 32-bit. However, some > architectures the padding has the wrong placement, so it requires > the ipc control routines (msgctl, semctl, and shmctl) to adjust the > mode field accordingly. Currently they are armeb, microblaze, m68k, > s390, and sheb. > > A new assume is added, __ASSUME_SYSVIPC_SUPPORT_MODE32, which the > required architecture undefine. > > 4. For the architecture that undefined __ASSUME_SYSVIPC_SUPPORT_MODE32, > it also requires compat symbols that do not adjust the mode field. > > Checked on arm-linux-gnueabihf, aarch64-linux-gnu, powerpc64le-linux-gnu, > and x86_64-linux-gnu. I also checked the sysvipc tests on hppa-linux-gnu, > sh4-linux-gnu, s390x-linux-gnu, and s390-linux-gnu. > > [BZ #18231] > * sysdeps/unix/sysv/linux/Makefile (sysdep_headers): Add > bits/ipc-perm.h. > * sysdeps/unix/sysv/linux/aarch64/bits/ipc.h: Remove file. > * sysdeps/unix/sysv/linux/alpha/bits/ipc.h: Likewise. > * sysdeps/unix/sysv/linux/hppa/bits/ipc.h: Likewise. > * sysdeps/unix/sysv/linux/ia64/bits/ipc.h: Likewise. > * sysdeps/unix/sysv/linux/mips/bits/ipc.h: Likewise. > * sysdeps/unix/sysv/linux/powerpc/bits/ipc.h: Likewise. > * sysdeps/unix/sysv/linux/s390/bits/ipc.h: Likewise. > * sysdeps/unix/sysv/linux/sparc/bits/ipc.h: Likewise. > * sysdeps/unix/sysv/linux/arm/kernel-features.h > [__BYTE_ORDER == __BIG_ENDIAN] (__ASSUME_SYSVIPC_SUPPORT_MODE32): > Undefine. > * sysdeps/sysv/linux/microblaze/kernel-features.h: Likewise. > * sysdeps/unix/sysv/linux/s390/kernel-features.h > [!__s390x__] (__ASSUME_SYSVIPC_SUPPORT_MODE32): Define. > * sysdeps/unix/sysv/linux/sh/kernel-features.h > (__ASSUME_SYSVIPC_SUPPORT_MODE32): Define. > * sysdeps/unix/sysv/linux/m68k/kernel-features.h: Likewise. > * sysdeps/unix/sysv/linux/bits/ipc-perm.h: New file. > * sysdeps/unix/sysv/linux/powerpc/bits/ipc-perm.h: Likewise. > * sysdeps/unix/sysv/linux/sparc/bits/ipc-perm.h: Likewise. > * sysdeps/unix/sysv/linux/bits/ipc.h (ipc_perm): Move to > bits/ipc-perm.h. > * sysdeps/unix/sysv/linux/hppa/bits/ipc-perm.h: New file. > * sysdeps/unix/sysv/linux/kernel-features.h > (__ASSUME_SYSVIPC_SUPPORT_MODE32): Define. > * sysdeps/unix/sysv/linux/msgctl.c (DEFAULT_VERSION): Define as > 2.30 if __ASSUME_SYSVIPC_SUPPORT_MODE32 is not defined. > (msgctl_syscall, __msgctl_mode16): New symbol. > (__new_msgctl): Handle if __ASSUME_SYSVIPC_SUPPORT_MODE32 is not > defined. > * sysdeps/unix/sysv/linux/semctl.c: Likewise. > * sysdeps/unix/sysv/linux/shmctl.c: Likewise. > * sysdeps/unix/sysv/linux/arm/be/libc.abilist (GLIBC_2.30): Add > msgctl, semctl, and shmctl. > * sysdeps/sysv/linux/microblaze/be/libc.abilist: Likewise. > * conform/data/sys/ipc.h-data: Only xfail {struct ipc_perm} mode_t > mode for Hurd. > * sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist: Likewise. > * sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist: Likewise. > * sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist: Likewise. > * sysdeps/unix/sysv/linux/sh/be/libc.abilist: Likewise. > > [1] http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_ipc.h.html > --- > conform/data/sys/ipc.h-data | 2 +- > sysdeps/unix/sysv/linux/Makefile | 3 +- > sysdeps/unix/sysv/linux/aarch64/bits/ipc.h | 54 ------------ > sysdeps/unix/sysv/linux/alpha/bits/ipc.h | 54 ------------ > sysdeps/unix/sysv/linux/arm/be/libc.abilist | 3 + > sysdeps/unix/sysv/linux/arm/kernel-features.h | 4 + > sysdeps/unix/sysv/linux/bits/ipc-perm.h | 40 +++++++++ > sysdeps/unix/sysv/linux/bits/ipc.h | 17 +--- > sysdeps/unix/sysv/linux/hppa/bits/ipc-perm.h | 37 ++++++++ > sysdeps/unix/sysv/linux/hppa/bits/ipc.h | 62 -------------- > sysdeps/unix/sysv/linux/ia64/bits/ipc.h | 53 ------------ > sysdeps/unix/sysv/linux/kernel-features.h | 9 ++ > .../sysv/linux/m68k/coldfire/libc.abilist | 3 + > .../unix/sysv/linux/m68k/kernel-features.h | 1 + > .../unix/sysv/linux/m68k/m680x0/libc.abilist | 3 + > .../sysv/linux/microblaze/be/libc.abilist | 3 + > .../sysv/linux/microblaze/kernel-features.h | 4 + > sysdeps/unix/sysv/linux/mips/bits/ipc.h | 54 ------------ > sysdeps/unix/sysv/linux/msgctl.c | 56 ++++++++++++- > .../linux/powerpc/bits/{ipc.h => ipc-perm.h} | 24 +----- > sysdeps/unix/sysv/linux/s390/bits/ipc.h | 60 ------------- > .../unix/sysv/linux/s390/kernel-features.h | 3 + > .../unix/sysv/linux/s390/s390-32/libc.abilist | 3 + > sysdeps/unix/sysv/linux/semctl.c | 84 +++++++++++++++++-- > sysdeps/unix/sysv/linux/sh/be/libc.abilist | 3 + > sysdeps/unix/sysv/linux/sh/kernel-features.h | 5 ++ > sysdeps/unix/sysv/linux/shmctl.c | 60 +++++++++++-- > .../linux/sparc/bits/{ipc.h => ipc-perm.h} | 31 +------ > 28 files changed, 315 insertions(+), 420 deletions(-) > delete mode 100644 sysdeps/unix/sysv/linux/aarch64/bits/ipc.h > delete mode 100644 sysdeps/unix/sysv/linux/alpha/bits/ipc.h > create mode 100644 sysdeps/unix/sysv/linux/bits/ipc-perm.h > create mode 100644 sysdeps/unix/sysv/linux/hppa/bits/ipc-perm.h > delete mode 100644 sysdeps/unix/sysv/linux/hppa/bits/ipc.h > delete mode 100644 sysdeps/unix/sysv/linux/ia64/bits/ipc.h > delete mode 100644 sysdeps/unix/sysv/linux/mips/bits/ipc.h > rename sysdeps/unix/sysv/linux/powerpc/bits/{ipc.h => ipc-perm.h} (62%) > delete mode 100644 sysdeps/unix/sysv/linux/s390/bits/ipc.h > rename sysdeps/unix/sysv/linux/sparc/bits/{ipc.h => ipc-perm.h} (59%) > > diff --git a/conform/data/sys/ipc.h-data b/conform/data/sys/ipc.h-data > index 09e8f68f8e..e6582c7cae 100644 > --- a/conform/data/sys/ipc.h-data > +++ b/conform/data/sys/ipc.h-data > @@ -7,7 +7,7 @@ xfail[i386-gnu]-element {struct ipc_perm} gid_t gid > xfail[i386-gnu]-element {struct ipc_perm} uid_t cuid > xfail[i386-gnu]-element {struct ipc_perm} gid_t cgid > // Bug 18231: wrong type for mode member. > -xfail-element {struct ipc_perm} mode_t mode > +xfail[i386-gnu]-element {struct ipc_perm} mode_t mode > > type uid_t > type gid_t > diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile > index afcdc658b5..4baf9d8f4a 100644 > --- a/sysdeps/unix/sysv/linux/Makefile > +++ b/sysdeps/unix/sysv/linux/Makefile > @@ -48,7 +48,8 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \ > bits/termios-c_iflag.h bits/termios-c_oflag.h \ > bits/termios-baud.h bits/termios-c_cflag.h \ > bits/termios-c_lflag.h bits/termios-tcflow.h \ > - bits/termios-misc.h > + bits/termios-misc.h \ > + bits/ipc-perm.h > > tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \ > tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \ > diff --git a/sysdeps/unix/sysv/linux/aarch64/bits/ipc.h b/sysdeps/unix/sysv/linux/aarch64/bits/ipc.h > deleted file mode 100644 > index b91377402c..0000000000 > --- a/sysdeps/unix/sysv/linux/aarch64/bits/ipc.h > +++ /dev/null > @@ -1,54 +0,0 @@ > -/* Copyright (C) 1995-2019 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 > - <http://www.gnu.org/licenses/>. */ > - > -#ifndef _SYS_IPC_H > -# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead." > -#endif > - > -#include <bits/types.h> > - > -/* Mode bits for `msgget', `semget', and `shmget'. */ > -#define IPC_CREAT 01000 /* Create key if key does not exist. */ > -#define IPC_EXCL 02000 /* Fail if key exists. */ > -#define IPC_NOWAIT 04000 /* Return error on wait. */ > - > -/* Control commands for `msgctl', `semctl', and `shmctl'. */ > -#define IPC_RMID 0 /* Remove identifier. */ > -#define IPC_SET 1 /* Set `ipc_perm' options. */ > -#define IPC_STAT 2 /* Get `ipc_perm' options. */ > -#ifdef __USE_GNU > -# define IPC_INFO 3 /* See ipcs. */ > -#endif > - > -/* Special key values. */ > -#define IPC_PRIVATE ((__key_t) 0) /* Private key. */ > - > - > -/* Data structure used to pass permission information to IPC operations. */ > -struct ipc_perm > - { > - __key_t __key; /* Key. */ > - __uid_t uid; /* Owner's user ID. */ > - __gid_t gid; /* Owner's group ID. */ > - __uid_t cuid; /* Creator's user ID. */ > - __gid_t cgid; /* Creator's group ID. */ > - unsigned int mode; /* Read/write permission. */ > - unsigned short int __seq; /* Sequence number. */ > - unsigned short int __pad1; > - __syscall_ulong_t __glibc_reserved1; > - __syscall_ulong_t __glibc_reserved2; > - }; > diff --git a/sysdeps/unix/sysv/linux/alpha/bits/ipc.h b/sysdeps/unix/sysv/linux/alpha/bits/ipc.h > deleted file mode 100644 > index 52ebcc7e97..0000000000 > --- a/sysdeps/unix/sysv/linux/alpha/bits/ipc.h > +++ /dev/null > @@ -1,54 +0,0 @@ > -/* Copyright (C) 1995-2019 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 > - <http://www.gnu.org/licenses/>. */ > - > -#ifndef _SYS_IPC_H > -# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead." > -#endif > - > -#include <bits/types.h> > - > -/* Mode bits for `msgget', `semget', and `shmget'. */ > -#define IPC_CREAT 01000 /* Create key if key does not exist. */ > -#define IPC_EXCL 02000 /* Fail if key exists. */ > -#define IPC_NOWAIT 04000 /* Return error on wait. */ > - > -/* Control commands for `msgctl', `semctl', and `shmctl'. */ > -#define IPC_RMID 0 /* Remove identifier. */ > -#define IPC_SET 1 /* Set `ipc_perm' options. */ > -#define IPC_STAT 2 /* Get `ipc_perm' options. */ > -#ifdef __USE_GNU > -# define IPC_INFO 3 /* See ipcs. */ > -#endif > - > -/* Special key values. */ > -#define IPC_PRIVATE ((__key_t) 0) /* Private key. */ > - > - > -/* Data structure used to pass permission information to IPC operations. */ > -struct ipc_perm > - { > - __key_t __key; /* Key. */ > - unsigned int uid; /* Owner's user ID. */ > - unsigned int gid; /* Owner's group ID. */ > - unsigned int cuid; /* Creator's user ID. */ > - unsigned int cgid; /* Creator's group ID. */ > - unsigned int mode; /* Read/write permission. */ > - unsigned short int __seq; /* Sequence number. */ > - unsigned short int __pad1; > - unsigned long int __glibc_reserved1; > - unsigned long int __glibc_reserved2; > - }; > diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist > index bc3df8dcea..f908657f99 100644 > --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist > +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist > @@ -128,6 +128,9 @@ GLIBC_2.29 posix_spawn_file_actions_addchdir_np F > GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F > GLIBC_2.30 getdents64 F > GLIBC_2.30 gettid F > +GLIBC_2.30 msgctl F > +GLIBC_2.30 semctl F > +GLIBC_2.30 shmctl F > GLIBC_2.30 tgkill F > GLIBC_2.30 twalk_r F > GLIBC_2.4 _Exit F > diff --git a/sysdeps/unix/sysv/linux/arm/kernel-features.h b/sysdeps/unix/sysv/linux/arm/kernel-features.h > index c6604a8f6a..220152fa1c 100644 > --- a/sysdeps/unix/sysv/linux/arm/kernel-features.h > +++ b/sysdeps/unix/sysv/linux/arm/kernel-features.h > @@ -17,6 +17,7 @@ > License along with the GNU C Library. If not, see > <http://www.gnu.org/licenses/>. */ > > +#include <endian.h> > #include_next <kernel-features.h> > > /* The ARM kernel before 3.14.3 may or may not support > @@ -51,3 +52,6 @@ > #define __ASSUME_CLONE_BACKWARDS 1 > > #undef __ASSUME_SYSVIPC_DEFAULT_IPC_64 > +#if __BYTE_ORDER == __BIG_ENDIAN > +# undef __ASSUME_SYSVIPC_SUPPORT_MODE32 > +#endif > diff --git a/sysdeps/unix/sysv/linux/bits/ipc-perm.h b/sysdeps/unix/sysv/linux/bits/ipc-perm.h > new file mode 100644 > index 0000000000..2c3f49f292 > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/bits/ipc-perm.h > @@ -0,0 +1,40 @@ > +/* struct ipc_perm definition. > + Copyright (C) 2019 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 > + <http://www.gnu.org/licenses/>. */ > + > +#ifndef _SYS_IPC_H > +# error "Never use <bits/ipc-perm.h> directly; include <sys/ipc.h> instead." > +#endif > + > +/* Data structure used to pass permission information to IPC operations. > + It follows the kernel ipc64_perm size so the syscall can be made directly > + without temporary buffer copy. However, since glibc defines the MODE > + field as mode_t per POSIX definition (BZ#18231), it omits the __PAD1 field > + (since glibc does not export mode_t as 16-bit for any architecture). */ > +struct ipc_perm > +{ > + __key_t __key; /* Key. */ > + __uid_t uid; /* Owner's user ID. */ > + __gid_t gid; /* Owner's group ID. */ > + __uid_t cuid; /* Creator's user ID. */ > + __gid_t cgid; /* Creator's group ID. */ > + __mode_t mode; /* Read/write permission. */ > + unsigned short int __seq; /* Sequence number. */ > + unsigned short int __pad2; > + __syscall_ulong_t __glibc_reserved1; > + __syscall_ulong_t __glibc_reserved2; > +}; > diff --git a/sysdeps/unix/sysv/linux/bits/ipc.h b/sysdeps/unix/sysv/linux/bits/ipc.h > index 6868b3eb45..af2098c942 100644 > --- a/sysdeps/unix/sysv/linux/bits/ipc.h > +++ b/sysdeps/unix/sysv/linux/bits/ipc.h > @@ -37,19 +37,4 @@ > /* Special key values. */ > #define IPC_PRIVATE ((__key_t) 0) /* Private key. */ > > - > -/* Data structure used to pass permission information to IPC operations. */ > -struct ipc_perm > - { > - __key_t __key; /* Key. */ > - __uid_t uid; /* Owner's user ID. */ > - __gid_t gid; /* Owner's group ID. */ > - __uid_t cuid; /* Creator's user ID. */ > - __gid_t cgid; /* Creator's group ID. */ > - unsigned short int mode; /* Read/write permission. */ > - unsigned short int __pad1; > - unsigned short int __seq; /* Sequence number. */ > - unsigned short int __pad2; > - __syscall_ulong_t __glibc_reserved1; > - __syscall_ulong_t __glibc_reserved2; > - }; > +#include <bits/ipc-perm.h> > diff --git a/sysdeps/unix/sysv/linux/hppa/bits/ipc-perm.h b/sysdeps/unix/sysv/linux/hppa/bits/ipc-perm.h > new file mode 100644 > index 0000000000..f29fc1689c > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/hppa/bits/ipc-perm.h > @@ -0,0 +1,37 @@ > +/* struct ipc_perm definition. > + Copyright (C) 2019 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 > + <http://www.gnu.org/licenses/>. */ > + > +#ifndef _SYS_IPC_H > +# error "Never use <bits/ipc-perm.h> directly; include <sys/ipc.h> instead." > +#endif > + > +/* Data structure used to pass permission information to IPC operations. */ > +struct ipc_perm > + { > + __key_t __key; /* Key. */ > + __uid_t uid; /* Owner's user ID. */ > + __gid_t gid; /* Owner's group ID. */ > + __uid_t cuid; /* Creator's user ID. */ > + __gid_t cgid; /* Creator's group ID. */ > + __mode_t mode; /* Read/write permission. */ > + unsigned short int __pad2; > + unsigned short int __seq; /* Sequence number. */ > + unsigned int __pad3; > + __extension__ unsigned long long int __glibc_reserved1; > + __extension__ unsigned long long int __glibc_reserved2; > + }; > diff --git a/sysdeps/unix/sysv/linux/hppa/bits/ipc.h b/sysdeps/unix/sysv/linux/hppa/bits/ipc.h > deleted file mode 100644 > index 889f882415..0000000000 > --- a/sysdeps/unix/sysv/linux/hppa/bits/ipc.h > +++ /dev/null > @@ -1,62 +0,0 @@ > -/* Copyright (C) 1995-2019 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 > - <http://www.gnu.org/licenses/>. */ > - > -#ifndef _SYS_IPC_H > -# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead." > -#endif > - > -#include <bits/types.h> > -#include <bits/wordsize.h> > - > -/* Mode bits for `msgget', `semget', and `shmget'. */ > -#define IPC_CREAT 01000 /* Create key if key does not exist. */ > -#define IPC_EXCL 02000 /* Fail if key exists. */ > -#define IPC_NOWAIT 04000 /* Return error on wait. */ > - > -/* Control commands for `msgctl', `semctl', and `shmctl'. */ > -#define IPC_RMID 0 /* Remove identifier. */ > -#define IPC_SET 1 /* Set `ipc_perm' options. */ > -#define IPC_STAT 2 /* Get `ipc_perm' options. */ > -#ifdef __USE_GNU > -# define IPC_INFO 3 /* See ipcs. */ > -#endif > - > -/* Special key values. */ > -#define IPC_PRIVATE ((__key_t) 0) /* Private key. */ > - > - > -/* Data structure used to pass permission information to IPC operations. */ > -struct ipc_perm > - { > - __key_t __key; /* Key. */ > - __uid_t uid; /* Owner's user ID. */ > - __gid_t gid; /* Owner's group ID. */ > - __uid_t cuid; /* Creator's user ID. */ > - __gid_t cgid; /* Creator's group ID. */ > -#if __WORDSIZE == 32 > - unsigned short int __pad1; > - unsigned short int mode; /* Read/write permission. */ > - unsigned short int __pad2; > -#else > - __mode_t mode; /* Read/write permission. */ > - unsigned short int __pad2; > -#endif > - unsigned short int __seq; /* Sequence number. */ > - unsigned int __pad3; > - __extension__ unsigned long long int __glibc_reserved1; > - __extension__ unsigned long long int __glibc_reserved2; > - }; > diff --git a/sysdeps/unix/sysv/linux/ia64/bits/ipc.h b/sysdeps/unix/sysv/linux/ia64/bits/ipc.h > deleted file mode 100644 > index 6f9705e28a..0000000000 > --- a/sysdeps/unix/sysv/linux/ia64/bits/ipc.h > +++ /dev/null > @@ -1,53 +0,0 @@ > -/* Copyright (C) 2000-2019 Free Software Foundation, Inc. > - This file is part of the GNU C Library. > - Contributed by David Mosberger-Tang <davidm@hpl.hp.com> > - > - 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 > - <http://www.gnu.org/licenses/>. */ > - > -#ifndef _SYS_IPC_H > -# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead." > -#endif > - > -#include <sys/types.h> > - > -/* Mode bits for `msgget', `semget', and `shmget'. */ > -#define IPC_CREAT 01000 /* Create key if key does not exist. */ > -#define IPC_EXCL 02000 /* Fail if key exists. */ > -#define IPC_NOWAIT 04000 /* Return error on wait. */ > - > -/* Control commands for `msgctl', `semctl', and `shmctl'. */ > -#define IPC_RMID 0 /* Remove identifier. */ > -#define IPC_SET 1 /* Set `ipc_perm' options. */ > -#define IPC_STAT 2 /* Get `ipc_perm' options. */ > -#define IPC_INFO 3 /* See ipcs. */ > - > -/* Special key values. */ > -#define IPC_PRIVATE ((__key_t) 0) /* Private key. */ > - > - > -/* Data structure used to pass permission information to IPC operations. */ > -struct ipc_perm > - { > - __key_t __key; /* Key. */ > - __uid_t uid; /* Owner's user ID. */ > - __gid_t gid; /* Owner's group ID. */ > - __uid_t cuid; /* Creator's user ID. */ > - __gid_t cgid; /* Creator's group ID. */ > - __mode_t mode; /* Read/write permission. */ > - unsigned short int __seq; /* Sequence number. */ > - unsigned short int __pad1; > - unsigned long int __glibc_reserved1; > - unsigned long int __glibc_reserved2; > - }; > diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h > index 42df1260c3..8b437e8e4e 100644 > --- a/sysdeps/unix/sysv/linux/kernel-features.h > +++ b/sysdeps/unix/sysv/linux/kernel-features.h > @@ -83,6 +83,15 @@ > /* The generic default __IPC_64 value is 0x0, however some architectures > require a different value of 0x100. */ > #define __ASSUME_SYSVIPC_DEFAULT_IPC_64 1 > +/* Assume that ipc_perm MODE kernel ABI has a 32-bit size or it is has padding > + on the correct place (so if userland defines it as 32-bit, large values > + will use the padding). > + All supported architectures reserve 32-bit MODE space with extra padding. > + However, some kernel ABI interfaces still expected a 16-bit field. This > + is only an issue is arch-defined IPC_PERM padding is on a wrong position > + regarding endianness. For this case, the IPC control routines (msgctl, > + semctl, and semctl) requires to shift the value for the correct place. */ > +#define __ASSUME_SYSVIPC_SUPPORT_MODE32 1 > > /* Support for p{read,write}v2 was added in 4.6. However Linux default > implementation does not assume the __ASSUME_* and instead use a fallback > diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist > index 05633b3cb8..a2be040dfc 100644 > --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist > +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist > @@ -129,6 +129,9 @@ GLIBC_2.29 posix_spawn_file_actions_addchdir_np F > GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F > GLIBC_2.30 getdents64 F > GLIBC_2.30 gettid F > +GLIBC_2.30 msgctl F > +GLIBC_2.30 semctl F > +GLIBC_2.30 shmctl F > GLIBC_2.30 tgkill F > GLIBC_2.30 twalk_r F > GLIBC_2.4 _Exit F > diff --git a/sysdeps/unix/sysv/linux/m68k/kernel-features.h b/sysdeps/unix/sysv/linux/m68k/kernel-features.h > index c9be6bc167..dbf1bad597 100644 > --- a/sysdeps/unix/sysv/linux/m68k/kernel-features.h > +++ b/sysdeps/unix/sysv/linux/m68k/kernel-features.h > @@ -55,3 +55,4 @@ > # undef __ASSUME_DIRECT_SYSVIPC_SYSCALLS > # undef __ASSUME_SYSVIPC_DEFAULT_IPC_64 > #endif > +#undef __ASSUME_SYSVIPC_SUPPORT_MODE32 > diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist > index 47eb7b4608..6f8f77de1d 100644 > --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist > +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist > @@ -2148,6 +2148,9 @@ GLIBC_2.3.4 xdr_quad_t F > GLIBC_2.3.4 xdr_u_quad_t F > GLIBC_2.30 getdents64 F > GLIBC_2.30 gettid F > +GLIBC_2.30 msgctl F > +GLIBC_2.30 semctl F > +GLIBC_2.30 shmctl F > GLIBC_2.30 tgkill F > GLIBC_2.30 twalk_r F > GLIBC_2.4 __confstr_chk F > diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist > index f7ced487f7..2f7302165e 100644 > --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist > +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist > @@ -2135,5 +2135,8 @@ GLIBC_2.29 posix_spawn_file_actions_addchdir_np F > GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F > GLIBC_2.30 getdents64 F > GLIBC_2.30 gettid F > +GLIBC_2.30 msgctl F > +GLIBC_2.30 semctl F > +GLIBC_2.30 shmctl F > GLIBC_2.30 tgkill F > GLIBC_2.30 twalk_r F > diff --git a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h > index 3575818e1b..d2027706bc 100644 > --- a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h > +++ b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h > @@ -15,6 +15,7 @@ > License along with the GNU C Library. If not, see > <http://www.gnu.org/licenses/>. */ > > +#include <endian.h> > > /* All supported kernel versions for MicroBlaze have these syscalls. */ > #define __ASSUME_SOCKET_SYSCALL 1 > @@ -69,3 +70,6 @@ > #define __ASSUME_CLONE_BACKWARDS3 > > #undef __ASSUME_SYSVIPC_DEFAULT_IPC_64 > +#if __BYTE_ORDER == __BIG_ENDIAN > +# undef __ASSUME_SYSVIPC_SUPPORT_MODE32 > +#endif > diff --git a/sysdeps/unix/sysv/linux/mips/bits/ipc.h b/sysdeps/unix/sysv/linux/mips/bits/ipc.h > deleted file mode 100644 > index 5f8985fadd..0000000000 > --- a/sysdeps/unix/sysv/linux/mips/bits/ipc.h > +++ /dev/null > @@ -1,54 +0,0 @@ > -/* Copyright (C) 1995-2019 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 > - <http://www.gnu.org/licenses/>. */ > - > -#ifndef _SYS_IPC_H > -# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead." > -#endif > - > -#include <bits/types.h> > - > -/* Mode bits for `msgget', `semget', and `shmget'. */ > -#define IPC_CREAT 01000 /* Create key if key does not exist. */ > -#define IPC_EXCL 02000 /* Fail if key exists. */ > -#define IPC_NOWAIT 04000 /* Return error on wait. */ > - > -/* Control commands for `msgctl', `semctl', and `shmctl'. */ > -#define IPC_RMID 0 /* Remove identifier. */ > -#define IPC_SET 1 /* Set `ipc_perm' options. */ > -#define IPC_STAT 2 /* Get `ipc_perm' options. */ > -#ifdef __USE_GNU > -# define IPC_INFO 3 /* See ipcs. */ > -#endif > - > -/* Special key values. */ > -#define IPC_PRIVATE ((__key_t) 0) /* Private key. */ > - > - > -/* Data structure used to pass permission information to IPC operations. */ > -struct ipc_perm > - { > - __key_t __key; /* Key. */ > - unsigned int uid; /* Owner's user ID. */ > - unsigned int gid; /* Owner's group ID. */ > - unsigned int cuid; /* Creator's user ID. */ > - unsigned int cgid; /* Creator's group ID. */ > - unsigned int mode; /* Read/write permission. */ > - unsigned short int __seq; /* Sequence number. */ > - unsigned short int __pad1; > - unsigned long int __glibc_reserved1; > - unsigned long int __glibc_reserved2; > -}; > diff --git a/sysdeps/unix/sysv/linux/msgctl.c b/sysdeps/unix/sysv/linux/msgctl.c > index 852c66884f..5034a88969 100644 > --- a/sysdeps/unix/sysv/linux/msgctl.c > +++ b/sysdeps/unix/sysv/linux/msgctl.c > @@ -23,11 +23,15 @@ > #include <errno.h> > > #ifndef DEFAULT_VERSION > -# define DEFAULT_VERSION GLIBC_2_2 > +# ifdef __ASSUME_SYSVIPC_SUPPORT_MODE32 > +# define DEFAULT_VERSION GLIBC_2_2 > +# else > +# define DEFAULT_VERSION GLIBC_2_30 > +# endif > #endif > > -int > -__new_msgctl (int msqid, int cmd, struct msqid_ds *buf) > +static int > +msgctl_syscall (int msqid, int cmd, struct msqid_ds *buf) > { > #ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS > return INLINE_SYSCALL_CALL (msgctl, msqid, cmd | __IPC_64, buf); > @@ -36,8 +40,54 @@ __new_msgctl (int msqid, int cmd, struct msqid_ds *buf) > buf); > #endif > } > + > +int > +__new_msgctl (int msqid, int cmd, struct msqid_ds *buf) > +{ > + /* POSIX states ipc_perm mode should have type of mode_t. */ > + _Static_assert (sizeof ((struct msqid_ds){0}.msg_perm.mode) > + == sizeof (mode_t), > + "sizeof (msqid_ds.msg_perm.mode) != sizeof (mode_t)"); > + > +#ifndef __ASSUME_SYSVIPC_SUPPORT_MODE32 > + struct msqid_ds tmpds; > + if (cmd == IPC_SET) > + { > + tmpds = *buf; > + tmpds.msg_perm.mode *= 0x10000U; > + buf = &tmpds; > + } > +#endif > + > + int ret = msgctl_syscall (msqid, cmd, buf); > + > +#ifndef __ASSUME_SYSVIPC_SUPPORT_MODE32 > + if (ret >= 0) > + { > + switch (cmd) > + { > + case IPC_STAT: > + case MSG_STAT: > + case MSG_STAT_ANY: > + buf->msg_perm.mode >>= 16; > + } > + } > +#endif > + > + return ret; > +} > versioned_symbol (libc, __new_msgctl, msgctl, DEFAULT_VERSION); > > +#if !defined __ASSUME_SYSVIPC_SUPPORT_MODE32 \ > + && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_30) > +int > +attribute_compat_text_section > +__msgctl_mode16 (int msqid, int cmd, struct msqid_ds *buf) > +{ > + return msgctl_syscall (msqid, cmd, buf); > +} > +compat_symbol (libc, __msgctl_mode16, msgctl, GLIBC_2_2); > +#endif > > #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) > struct __old_msqid_ds > diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/ipc.h b/sysdeps/unix/sysv/linux/powerpc/bits/ipc-perm.h > similarity index 62% > rename from sysdeps/unix/sysv/linux/powerpc/bits/ipc.h > rename to sysdeps/unix/sysv/linux/powerpc/bits/ipc-perm.h > index f237c8ed10..022b337764 100644 > --- a/sysdeps/unix/sysv/linux/powerpc/bits/ipc.h > +++ b/sysdeps/unix/sysv/linux/powerpc/bits/ipc-perm.h > @@ -1,4 +1,5 @@ > -/* Copyright (C) 1995-2019 Free Software Foundation, Inc. > +/* struct ipc_perm definition. > + Copyright (C) 1995-2019 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 > @@ -16,28 +17,9 @@ > <http://www.gnu.org/licenses/>. */ > > #ifndef _SYS_IPC_H > -# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead." > +# error "Never use <bits/ipc-perm.h> directly; include <sys/ipc.h> instead." > #endif > > -#include <bits/types.h> > - > -/* Mode bits for `msgget', `semget', and `shmget'. */ > -#define IPC_CREAT 01000 /* Create key if key does not exist. */ > -#define IPC_EXCL 02000 /* Fail if key exists. */ > -#define IPC_NOWAIT 04000 /* Return error on wait. */ > - > -/* Control commands for `msgctl', `semctl', and `shmctl'. */ > -#define IPC_RMID 0 /* Remove identifier. */ > -#define IPC_SET 1 /* Set `ipc_perm' options. */ > -#define IPC_STAT 2 /* Get `ipc_perm' options. */ > -#ifdef __USE_GNU > -# define IPC_INFO 3 /* See ipcs. */ > -#endif > - > -/* Special key values. */ > -#define IPC_PRIVATE ((__key_t) 0) /* Private key. */ > - > - > /* Data structure used to pass permission information to IPC operations. */ > struct ipc_perm > { > diff --git a/sysdeps/unix/sysv/linux/s390/bits/ipc.h b/sysdeps/unix/sysv/linux/s390/bits/ipc.h > deleted file mode 100644 > index 8cc7ed9abb..0000000000 > --- a/sysdeps/unix/sysv/linux/s390/bits/ipc.h > +++ /dev/null > @@ -1,60 +0,0 @@ > -/* Copyright (C) 2001-2019 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 > - <http://www.gnu.org/licenses/>. */ > - > -#ifndef _SYS_IPC_H > -# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead." > -#endif > - > -#include <bits/types.h> > -#include <bits/wordsize.h> > - > -/* Mode bits for `msgget', `semget', and `shmget'. */ > -#define IPC_CREAT 01000 /* Create key if key does not exist. */ > -#define IPC_EXCL 02000 /* Fail if key exists. */ > -#define IPC_NOWAIT 04000 /* Return error on wait. */ > - > -/* Control commands for `msgctl', `semctl', and `shmctl'. */ > -#define IPC_RMID 0 /* Remove identifier. */ > -#define IPC_SET 1 /* Set `ipc_perm' options. */ > -#define IPC_STAT 2 /* Get `ipc_perm' options. */ > -#ifdef __USE_GNU > -#define IPC_INFO 3 /* See ipcs. */ > -#endif > - > -/* Special key values. */ > -#define IPC_PRIVATE ((__key_t) 0) /* Private key. */ > - > - > -/* Data structure used to pass permission information to IPC operations. */ > -struct ipc_perm > - { > - __key_t __key; /* Key. */ > - __uid_t uid; /* Owner's user ID. */ > - __gid_t gid; /* Owner's group ID. */ > - __uid_t cuid; /* Creator's user ID. */ > - __gid_t cgid; /* Creator's group ID. */ > -#if __WORDSIZE == 64 > - __mode_t mode; /* Read/write permission. */ > -#else > - unsigned short int mode; /* Read/write permission. */ > - unsigned short int __pad1; > -#endif > - unsigned short int __seq; /* Sequence number. */ > - unsigned short int __pad2; > - unsigned long int __glibc_reserved1; > - unsigned long int __glibc_reserved2; > - }; > diff --git a/sysdeps/unix/sysv/linux/s390/kernel-features.h b/sysdeps/unix/sysv/linux/s390/kernel-features.h > index 7997a78e1d..8b43b372fc 100644 > --- a/sysdeps/unix/sysv/linux/s390/kernel-features.h > +++ b/sysdeps/unix/sysv/linux/s390/kernel-features.h > @@ -50,6 +50,9 @@ > # undef __ASSUME_DIRECT_SYSVIPC_SYSCALLS > # undef __ASSUME_SYSVIPC_DEFAULT_IPC_64 > #endif > +#ifndef __s390x__ > +# undef __ASSUME_SYSVIPC_SUPPORT_MODE32 > +#endif > > #undef __ASSUME_CLONE_DEFAULT > #define __ASSUME_CLONE_BACKWARDS2 > diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist > index 576295deff..3aa48fc87c 100644 > --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist > +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist > @@ -2173,6 +2173,9 @@ GLIBC_2.30 __nldbl_warn F > GLIBC_2.30 __nldbl_warnx F > GLIBC_2.30 getdents64 F > GLIBC_2.30 gettid F > +GLIBC_2.30 msgctl F > +GLIBC_2.30 semctl F > +GLIBC_2.30 shmctl F > GLIBC_2.30 tgkill F > GLIBC_2.30 twalk_r F > GLIBC_2.4 _IO_fprintf F > diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c > index 6f4e46dde3..7131f85326 100644 > --- a/sysdeps/unix/sysv/linux/semctl.c > +++ b/sysdeps/unix/sysv/linux/semctl.c > @@ -33,12 +33,33 @@ union semun > }; > > #ifndef DEFAULT_VERSION > -# define DEFAULT_VERSION GLIBC_2_2 > +# ifdef __ASSUME_SYSVIPC_SUPPORT_MODE32 > +# define DEFAULT_VERSION GLIBC_2_2 > +# else > +# define DEFAULT_VERSION GLIBC_2_30 > +# endif > #endif > > +static int > +semctl_syscall (int semid, int semnum, int cmd, union semun arg) > +{ > +#ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS > + return INLINE_SYSCALL_CALL (semctl, semid, semnum, cmd | __IPC_64, > + arg.array); > +#else > + return INLINE_SYSCALL_CALL (ipc, IPCOP_semctl, semid, semnum, cmd | __IPC_64, > + SEMCTL_ARG_ADDRESS (arg)); > +#endif > +} > + > int > __new_semctl (int semid, int semnum, int cmd, ...) > { > + /* POSIX states ipc_perm mode should have type of mode_t. */ > + _Static_assert (sizeof ((struct semid_ds){0}.sem_perm.mode) > + == sizeof (mode_t), > + "sizeof (msqid_ds.msg_perm.mode) != sizeof (mode_t)"); > + > union semun arg = { 0 }; > va_list ap; > > @@ -59,16 +80,65 @@ __new_semctl (int semid, int semnum, int cmd, ...) > break; > } > > -#ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS > - return INLINE_SYSCALL_CALL (semctl, semid, semnum, cmd | __IPC_64, > - arg.array); > -#else > - return INLINE_SYSCALL_CALL (ipc, IPCOP_semctl, semid, semnum, cmd | __IPC_64, > - SEMCTL_ARG_ADDRESS (arg)); > +#ifndef __ASSUME_SYSVIPC_SUPPORT_MODE32 > + struct semid_ds tmpds; > + if (cmd == IPC_SET) > + { > + tmpds = *arg.buf; > + tmpds.sem_perm.mode *= 0x10000U; > + arg.buf = &tmpds; > + } > +#endif > + > + int ret = semctl_syscall (semid, semnum, cmd, arg); > + > +#ifndef __ASSUME_SYSVIPC_SUPPORT_MODE32 > + if (ret >= 0) > + { > + switch (cmd) > + { > + case IPC_STAT: > + case SEM_STAT: > + case SEM_STAT_ANY: > + arg.buf->sem_perm.mode >>= 16; > + } > + } > #endif > + > + return ret; > } > versioned_symbol (libc, __new_semctl, semctl, DEFAULT_VERSION); > > +#if !defined __ASSUME_SYSVIPC_SUPPORT_MODE32 \ > + && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_30) > +int > +attribute_compat_text_section > +__semctl_mode16 (int semid, int semnum, int cmd, ...) > +{ > + union semun arg = { 0 }; > + va_list ap; > + > + /* Get the argument only if required. */ > + switch (cmd) > + { > + case SETVAL: /* arg.val */ > + case GETALL: /* arg.array */ > + case SETALL: > + case IPC_STAT: /* arg.buf */ > + case IPC_SET: > + case SEM_STAT: > + case IPC_INFO: /* arg.__buf */ > + case SEM_INFO: > + va_start (ap, cmd); > + arg = va_arg (ap, union semun); > + va_end (ap); > + break; > + } > + > + return semctl_syscall (semid, semnum, cmd, arg); > +} > +compat_symbol (libc, __semctl_mode16, semctl, GLIBC_2_2); > +#endif > > #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) > /* Since semctl use a variadic argument for semid_ds there is not need to > diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist > index 41977f6e9c..aa59e3bc34 100644 > --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist > +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist > @@ -2043,6 +2043,9 @@ GLIBC_2.3.4 xdr_quad_t F > GLIBC_2.3.4 xdr_u_quad_t F > GLIBC_2.30 getdents64 F > GLIBC_2.30 gettid F > +GLIBC_2.30 msgctl F > +GLIBC_2.30 semctl F > +GLIBC_2.30 shmctl F > GLIBC_2.30 tgkill F > GLIBC_2.30 twalk_r F > GLIBC_2.4 __confstr_chk F > diff --git a/sysdeps/unix/sysv/linux/sh/kernel-features.h b/sysdeps/unix/sysv/linux/sh/kernel-features.h > index e793a83a6f..e584b5218b 100644 > --- a/sysdeps/unix/sysv/linux/sh/kernel-features.h > +++ b/sysdeps/unix/sysv/linux/sh/kernel-features.h > @@ -20,6 +20,8 @@ > #ifndef __KERNEL_FEATURES_SH__ > # define __KERNEL_FEATURES_SH__ > > +#include <endian.h> > + > /* These syscalls were added for SH in 2.6.37. */ > #define __ASSUME_SOCKET_SYSCALL 1 > #define __ASSUME_BIND_SYSCALL 1 > @@ -46,6 +48,9 @@ > # undef __ASSUME_DIRECT_SYSVIPC_SYSCALLS > # undef __ASSUME_SYSVIPC_DEFAULT_IPC_64 > #endif > +#if __BYTE_ORDER == __BIG_ENDIAN > +# undef __ASSUME_SYSVIPC_SUPPORT_MODE32 > +#endif > > /* Support for several syscalls was added in 4.8. */ > #if __LINUX_KERNEL_VERSION < 0x040800 > diff --git a/sysdeps/unix/sysv/linux/shmctl.c b/sysdeps/unix/sysv/linux/shmctl.c > index ba1dc28376..234fb363b8 100644 > --- a/sysdeps/unix/sysv/linux/shmctl.c > +++ b/sysdeps/unix/sysv/linux/shmctl.c > @@ -23,15 +23,16 @@ > #include <shlib-compat.h> > #include <errno.h> > > - > #ifndef DEFAULT_VERSION > -# define DEFAULT_VERSION GLIBC_2_2 > +# ifdef __ASSUME_SYSVIPC_SUPPORT_MODE32 > +# define DEFAULT_VERSION GLIBC_2_2 > +# else > +# define DEFAULT_VERSION GLIBC_2_30 > +# endif > #endif > > - > -/* Provide operations to control over shared memory segments. */ > -int > -__new_shmctl (int shmid, int cmd, struct shmid_ds *buf) > +static int > +shmctl_syscall (int shmid, int cmd, struct shmid_ds *buf) > { > #ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS > return INLINE_SYSCALL_CALL (shmctl, shmid, cmd | __IPC_64, buf); > @@ -40,8 +41,55 @@ __new_shmctl (int shmid, int cmd, struct shmid_ds *buf) > buf); > #endif > } > + > +/* Provide operations to control over shared memory segments. */ > +int > +__new_shmctl (int shmid, int cmd, struct shmid_ds *buf) > +{ > + /* POSIX states ipc_perm mode should have type of mode_t. */ > + _Static_assert (sizeof ((struct shmid_ds){0}.shm_perm.mode) > + == sizeof (mode_t), > + "sizeof (msqid_ds.msg_perm.mode) != sizeof (mode_t)"); > + > +#ifndef __ASSUME_SYSVIPC_SUPPORT_MODE32 > + struct shmid_ds tmpds; > + if (cmd == IPC_SET) > + { > + tmpds = *buf; > + tmpds.shm_perm.mode *= 0x10000U; > + buf = &tmpds; > + } > +#endif > + > + int ret = shmctl_syscall (shmid, cmd, buf); > + > +#ifndef __ASSUME_SYSVIPC_SUPPORT_MODE32 > + if (ret >= 0) > + { > + switch (cmd) > + { > + case IPC_STAT: > + case SHM_STAT: > + case SHM_STAT_ANY: > + buf->shm_perm.mode >>= 16; > + } > + } > +#endif > + > + return ret; > +} > versioned_symbol (libc, __new_shmctl, shmctl, DEFAULT_VERSION); > > +#if !defined __ASSUME_SYSVIPC_SUPPORT_MODE32 \ > + && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_30) > +int > +attribute_compat_text_section > +__shmctl_mode16 (int shmid, int cmd, struct shmid_ds *buf) > +{ > + return shmctl_syscall (shmid, cmd, buf); > +} > +compat_symbol (libc, __shmctl_mode16, shmctl, GLIBC_2_2); > +#endif > > #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) > struct __old_shmid_ds > diff --git a/sysdeps/unix/sysv/linux/sparc/bits/ipc.h b/sysdeps/unix/sysv/linux/sparc/bits/ipc-perm.h > similarity index 59% > rename from sysdeps/unix/sysv/linux/sparc/bits/ipc.h > rename to sysdeps/unix/sysv/linux/sparc/bits/ipc-perm.h > index b67c25ec61..95ac584752 100644 > --- a/sysdeps/unix/sysv/linux/sparc/bits/ipc.h > +++ b/sysdeps/unix/sysv/linux/sparc/bits/ipc-perm.h > @@ -1,4 +1,5 @@ > -/* Copyright (C) 1995-2019 Free Software Foundation, Inc. > +/* struct ipc_perm definition. > + Copyright (C) 1995-2019 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 > @@ -16,29 +17,9 @@ > <http://www.gnu.org/licenses/>. */ > > #ifndef _SYS_IPC_H > -# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead." > +# error "Never use <bits/ipc-perm.h> directly; include <sys/ipc.h> instead." > #endif > > -#include <bits/types.h> > -#include <bits/wordsize.h> > - > -/* Mode bits for `msgget', `semget', and `shmget'. */ > -#define IPC_CREAT 01000 /* Create key if key does not exist. */ > -#define IPC_EXCL 02000 /* Fail if key exists. */ > -#define IPC_NOWAIT 04000 /* Return error on wait. */ > - > -/* Control commands for `msgctl', `semctl', and `shmctl'. */ > -#define IPC_RMID 0 /* Remove identifier. */ > -#define IPC_SET 1 /* Set `ipc_perm' options. */ > -#define IPC_STAT 2 /* Get `ipc_perm' options. */ > -#ifdef __USE_GNU > -# define IPC_INFO 3 /* See ipcs. */ > -#endif > - > -/* Special key values. */ > -#define IPC_PRIVATE ((__key_t) 0) /* Private key. */ > - > - > /* Data structure used to pass permission information to IPC operations. */ > struct ipc_perm > { > @@ -47,14 +28,8 @@ struct ipc_perm > __gid_t gid; /* Owner's group ID. */ > __uid_t cuid; /* Creator's user ID. */ > __gid_t cgid; /* Creator's group ID. */ > -#if __WORDSIZE == 32 > - unsigned short int __pad1; > - unsigned short int mode; /* Read/write permission. */ > - unsigned short int __pad2; > -#else > __mode_t mode; /* Read/write permission. */ > unsigned short int __pad1; > -#endif > unsigned short int __seq; /* Sequence number. */ > __extension__ unsigned long long int __glibc_reserved1; > __extension__ unsigned long long int __glibc_reserved2; >
On Tue, Jul 30, 2019 at 09:30:30AM -0300, Adhemerval Zanella wrote: > Changes from previous version: > > - Add m68k ABIs. > > - XFAIL ipc_perm mode on conform/data/sys/ipc.h-data just for Hurd. > > -- > > This patch sets the mode field in ipc_perm as mode_t for all architectures, > as POSIX specification [1]. The changes required are as follow: > > 1. It moves the ipc_perm definition out of ipc.h to its own header > ipc_perm.h. It also allows consolidate the IPC_* definition on > only one header. > > 2. The generic implementation follow the kernel ipc64_perm size so the > syscall can be made directly without temporary buffer copy. However, > since glibc defines the MODE field as mode_t, it omits the __PAD1 field > (since glibc does not export mode_t as 16-bit for any architecture). > > It is a two-fold improvement: > > 2.1. New implementation which follow Linux UAPI will not need to > provide an arch-specific ipc-perm.h header neither wrongly > use the wrong 16-bit definition from previous default ipc.h > (as csky did). > > 2.1. It allows consolidate ipc_perm definition for architectures that > already provide mode_t as 32-bit. > > 3. All kernel ABIs for the supported architectures already provides the > expected padding for mode type extension to 32-bit. However, some > architectures the padding has the wrong placement, so it requires > the ipc control routines (msgctl, semctl, and shmctl) to adjust the > mode field accordingly. Currently they are armeb, microblaze, m68k, > s390, and sheb. > > A new assume is added, __ASSUME_SYSVIPC_SUPPORT_MODE32, which the > required architecture undefine. > > 4. For the architecture that undefined __ASSUME_SYSVIPC_SUPPORT_MODE32, > it also requires compat symbols that do not adjust the mode field. Overall this looks good to me. I find the macro name __ASSUME_SYSVIPC_SUPPORT_MODE32 confusing though; my understanding of "assume" in glibc conventions is that it's just a hint that fallbacks aren't needed, not a hard change in behavior. Here, you've used __ASSUME_SYSVIPC_SUPPORT_MODE32 to mean !__ARCH_HAS_REVERSED_HALFWORD_IPC_PERM_MODE. I think it would be a lot more readable to have the archs that need handling for broken mode field define a macro indicating that the syscall interface has it backwards, rather than the default assumption being that it's backwards. For comparison, musl has a macro named SYSCALL_IPC_BROKEN_MODE for the affected archs. In any case, as noted on bz #18231, I'd really like to see this applied so that the same bug doesn't keep getting copied to new archs. Rich
On Tue, 27 Aug 2019, Adhemerval Zanella wrote:
> Ping, with Joseph's comment removal applied.
And with all the versions updated to 2.31?
--
Joseph S. Myers
joseph@codesourcery.com
On 27/08/2019 13:41, Joseph Myers wrote: > On Tue, 27 Aug 2019, Adhemerval Zanella wrote: > >> Ping, with Joseph's comment removal applied. > > And with all the versions updated to 2.31? > Indeed, I am just rechecking on 2.31 for the all affected ABIs.
On 27/08/2019 11:30, Rich Felker wrote: > On Tue, Jul 30, 2019 at 09:30:30AM -0300, Adhemerval Zanella wrote: >> Changes from previous version: >> >> - Add m68k ABIs. >> >> - XFAIL ipc_perm mode on conform/data/sys/ipc.h-data just for Hurd. >> >> -- >> >> This patch sets the mode field in ipc_perm as mode_t for all architectures, >> as POSIX specification [1]. The changes required are as follow: >> >> 1. It moves the ipc_perm definition out of ipc.h to its own header >> ipc_perm.h. It also allows consolidate the IPC_* definition on >> only one header. >> >> 2. The generic implementation follow the kernel ipc64_perm size so the >> syscall can be made directly without temporary buffer copy. However, >> since glibc defines the MODE field as mode_t, it omits the __PAD1 field >> (since glibc does not export mode_t as 16-bit for any architecture). >> >> It is a two-fold improvement: >> >> 2.1. New implementation which follow Linux UAPI will not need to >> provide an arch-specific ipc-perm.h header neither wrongly >> use the wrong 16-bit definition from previous default ipc.h >> (as csky did). >> >> 2.1. It allows consolidate ipc_perm definition for architectures that >> already provide mode_t as 32-bit. >> >> 3. All kernel ABIs for the supported architectures already provides the >> expected padding for mode type extension to 32-bit. However, some >> architectures the padding has the wrong placement, so it requires >> the ipc control routines (msgctl, semctl, and shmctl) to adjust the >> mode field accordingly. Currently they are armeb, microblaze, m68k, >> s390, and sheb. >> >> A new assume is added, __ASSUME_SYSVIPC_SUPPORT_MODE32, which the >> required architecture undefine. >> >> 4. For the architecture that undefined __ASSUME_SYSVIPC_SUPPORT_MODE32, >> it also requires compat symbols that do not adjust the mode field. > > Overall this looks good to me. I find the macro name > __ASSUME_SYSVIPC_SUPPORT_MODE32 confusing though; my understanding of > "assume" in glibc conventions is that it's just a hint that fallbacks > aren't needed, not a hard change in behavior. Here, you've used > __ASSUME_SYSVIPC_SUPPORT_MODE32 to mean > !__ARCH_HAS_REVERSED_HALFWORD_IPC_PERM_MODE. I think it would be a lot > more readable to have the archs that need handling for broken mode > field define a macro indicating that the syscall interface has it > backwards, rather than the default assumption being that it's > backwards. > > For comparison, musl has a macro named SYSCALL_IPC_BROKEN_MODE for > the affected archs. We also use __ASSUME macros to define arch-specific kernel ABI for some syscalls (fadvise or clone for instance). I don't have a strong opinion here and I see that by not checking the required macro enable compat mode is somewhat confusing. I don't think __ARCH_HAS_REVERSED_HALFWORD_IPC_PERM_MODE really express the issue (also for other sysvipc idiosyncrasies glibc uses SYSVIPC on its name). So I think the macro __ARCH_SYSVIPC_BROKEN_MODE_T is a better name. I will updating the patch to take in consideration newer symbols since 2.31 release and I will send an updated version. > > In any case, as noted on bz #18231, I'd really like to see this > applied so that the same bug doesn't keep getting copied to new archs. > > Rich > Thanks for checking on it.
diff --git a/conform/data/sys/ipc.h-data b/conform/data/sys/ipc.h-data index 09e8f68f8e..e6582c7cae 100644 --- a/conform/data/sys/ipc.h-data +++ b/conform/data/sys/ipc.h-data @@ -7,7 +7,7 @@ xfail[i386-gnu]-element {struct ipc_perm} gid_t gid xfail[i386-gnu]-element {struct ipc_perm} uid_t cuid xfail[i386-gnu]-element {struct ipc_perm} gid_t cgid // Bug 18231: wrong type for mode member. -xfail-element {struct ipc_perm} mode_t mode +xfail[i386-gnu]-element {struct ipc_perm} mode_t mode type uid_t type gid_t diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index afcdc658b5..4baf9d8f4a 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -48,7 +48,8 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \ bits/termios-c_iflag.h bits/termios-c_oflag.h \ bits/termios-baud.h bits/termios-c_cflag.h \ bits/termios-c_lflag.h bits/termios-tcflow.h \ - bits/termios-misc.h + bits/termios-misc.h \ + bits/ipc-perm.h tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \ tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \ diff --git a/sysdeps/unix/sysv/linux/aarch64/bits/ipc.h b/sysdeps/unix/sysv/linux/aarch64/bits/ipc.h deleted file mode 100644 index b91377402c..0000000000 --- a/sysdeps/unix/sysv/linux/aarch64/bits/ipc.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (C) 1995-2019 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 - <http://www.gnu.org/licenses/>. */ - -#ifndef _SYS_IPC_H -# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead." -#endif - -#include <bits/types.h> - -/* Mode bits for `msgget', `semget', and `shmget'. */ -#define IPC_CREAT 01000 /* Create key if key does not exist. */ -#define IPC_EXCL 02000 /* Fail if key exists. */ -#define IPC_NOWAIT 04000 /* Return error on wait. */ - -/* Control commands for `msgctl', `semctl', and `shmctl'. */ -#define IPC_RMID 0 /* Remove identifier. */ -#define IPC_SET 1 /* Set `ipc_perm' options. */ -#define IPC_STAT 2 /* Get `ipc_perm' options. */ -#ifdef __USE_GNU -# define IPC_INFO 3 /* See ipcs. */ -#endif - -/* Special key values. */ -#define IPC_PRIVATE ((__key_t) 0) /* Private key. */ - - -/* Data structure used to pass permission information to IPC operations. */ -struct ipc_perm - { - __key_t __key; /* Key. */ - __uid_t uid; /* Owner's user ID. */ - __gid_t gid; /* Owner's group ID. */ - __uid_t cuid; /* Creator's user ID. */ - __gid_t cgid; /* Creator's group ID. */ - unsigned int mode; /* Read/write permission. */ - unsigned short int __seq; /* Sequence number. */ - unsigned short int __pad1; - __syscall_ulong_t __glibc_reserved1; - __syscall_ulong_t __glibc_reserved2; - }; diff --git a/sysdeps/unix/sysv/linux/alpha/bits/ipc.h b/sysdeps/unix/sysv/linux/alpha/bits/ipc.h deleted file mode 100644 index 52ebcc7e97..0000000000 --- a/sysdeps/unix/sysv/linux/alpha/bits/ipc.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (C) 1995-2019 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 - <http://www.gnu.org/licenses/>. */ - -#ifndef _SYS_IPC_H -# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead." -#endif - -#include <bits/types.h> - -/* Mode bits for `msgget', `semget', and `shmget'. */ -#define IPC_CREAT 01000 /* Create key if key does not exist. */ -#define IPC_EXCL 02000 /* Fail if key exists. */ -#define IPC_NOWAIT 04000 /* Return error on wait. */ - -/* Control commands for `msgctl', `semctl', and `shmctl'. */ -#define IPC_RMID 0 /* Remove identifier. */ -#define IPC_SET 1 /* Set `ipc_perm' options. */ -#define IPC_STAT 2 /* Get `ipc_perm' options. */ -#ifdef __USE_GNU -# define IPC_INFO 3 /* See ipcs. */ -#endif - -/* Special key values. */ -#define IPC_PRIVATE ((__key_t) 0) /* Private key. */ - - -/* Data structure used to pass permission information to IPC operations. */ -struct ipc_perm - { - __key_t __key; /* Key. */ - unsigned int uid; /* Owner's user ID. */ - unsigned int gid; /* Owner's group ID. */ - unsigned int cuid; /* Creator's user ID. */ - unsigned int cgid; /* Creator's group ID. */ - unsigned int mode; /* Read/write permission. */ - unsigned short int __seq; /* Sequence number. */ - unsigned short int __pad1; - unsigned long int __glibc_reserved1; - unsigned long int __glibc_reserved2; - }; diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist index bc3df8dcea..f908657f99 100644 --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist @@ -128,6 +128,9 @@ GLIBC_2.29 posix_spawn_file_actions_addchdir_np F GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 msgctl F +GLIBC_2.30 semctl F +GLIBC_2.30 shmctl F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.4 _Exit F diff --git a/sysdeps/unix/sysv/linux/arm/kernel-features.h b/sysdeps/unix/sysv/linux/arm/kernel-features.h index c6604a8f6a..220152fa1c 100644 --- a/sysdeps/unix/sysv/linux/arm/kernel-features.h +++ b/sysdeps/unix/sysv/linux/arm/kernel-features.h @@ -17,6 +17,7 @@ License along with the GNU C Library. If not, see <http://www.gnu.org/licenses/>. */ +#include <endian.h> #include_next <kernel-features.h> /* The ARM kernel before 3.14.3 may or may not support @@ -51,3 +52,6 @@ #define __ASSUME_CLONE_BACKWARDS 1 #undef __ASSUME_SYSVIPC_DEFAULT_IPC_64 +#if __BYTE_ORDER == __BIG_ENDIAN +# undef __ASSUME_SYSVIPC_SUPPORT_MODE32 +#endif diff --git a/sysdeps/unix/sysv/linux/bits/ipc-perm.h b/sysdeps/unix/sysv/linux/bits/ipc-perm.h new file mode 100644 index 0000000000..2c3f49f292 --- /dev/null +++ b/sysdeps/unix/sysv/linux/bits/ipc-perm.h @@ -0,0 +1,40 @@ +/* struct ipc_perm definition. + Copyright (C) 2019 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 + <http://www.gnu.org/licenses/>. */ + +#ifndef _SYS_IPC_H +# error "Never use <bits/ipc-perm.h> directly; include <sys/ipc.h> instead." +#endif + +/* Data structure used to pass permission information to IPC operations. + It follows the kernel ipc64_perm size so the syscall can be made directly + without temporary buffer copy. However, since glibc defines the MODE + field as mode_t per POSIX definition (BZ#18231), it omits the __PAD1 field + (since glibc does not export mode_t as 16-bit for any architecture). */ +struct ipc_perm +{ + __key_t __key; /* Key. */ + __uid_t uid; /* Owner's user ID. */ + __gid_t gid; /* Owner's group ID. */ + __uid_t cuid; /* Creator's user ID. */ + __gid_t cgid; /* Creator's group ID. */ + __mode_t mode; /* Read/write permission. */ + unsigned short int __seq; /* Sequence number. */ + unsigned short int __pad2; + __syscall_ulong_t __glibc_reserved1; + __syscall_ulong_t __glibc_reserved2; +}; diff --git a/sysdeps/unix/sysv/linux/bits/ipc.h b/sysdeps/unix/sysv/linux/bits/ipc.h index 6868b3eb45..af2098c942 100644 --- a/sysdeps/unix/sysv/linux/bits/ipc.h +++ b/sysdeps/unix/sysv/linux/bits/ipc.h @@ -37,19 +37,4 @@ /* Special key values. */ #define IPC_PRIVATE ((__key_t) 0) /* Private key. */ - -/* Data structure used to pass permission information to IPC operations. */ -struct ipc_perm - { - __key_t __key; /* Key. */ - __uid_t uid; /* Owner's user ID. */ - __gid_t gid; /* Owner's group ID. */ - __uid_t cuid; /* Creator's user ID. */ - __gid_t cgid; /* Creator's group ID. */ - unsigned short int mode; /* Read/write permission. */ - unsigned short int __pad1; - unsigned short int __seq; /* Sequence number. */ - unsigned short int __pad2; - __syscall_ulong_t __glibc_reserved1; - __syscall_ulong_t __glibc_reserved2; - }; +#include <bits/ipc-perm.h> diff --git a/sysdeps/unix/sysv/linux/hppa/bits/ipc-perm.h b/sysdeps/unix/sysv/linux/hppa/bits/ipc-perm.h new file mode 100644 index 0000000000..f29fc1689c --- /dev/null +++ b/sysdeps/unix/sysv/linux/hppa/bits/ipc-perm.h @@ -0,0 +1,37 @@ +/* struct ipc_perm definition. + Copyright (C) 2019 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 + <http://www.gnu.org/licenses/>. */ + +#ifndef _SYS_IPC_H +# error "Never use <bits/ipc-perm.h> directly; include <sys/ipc.h> instead." +#endif + +/* Data structure used to pass permission information to IPC operations. */ +struct ipc_perm + { + __key_t __key; /* Key. */ + __uid_t uid; /* Owner's user ID. */ + __gid_t gid; /* Owner's group ID. */ + __uid_t cuid; /* Creator's user ID. */ + __gid_t cgid; /* Creator's group ID. */ + __mode_t mode; /* Read/write permission. */ + unsigned short int __pad2; + unsigned short int __seq; /* Sequence number. */ + unsigned int __pad3; + __extension__ unsigned long long int __glibc_reserved1; + __extension__ unsigned long long int __glibc_reserved2; + }; diff --git a/sysdeps/unix/sysv/linux/hppa/bits/ipc.h b/sysdeps/unix/sysv/linux/hppa/bits/ipc.h deleted file mode 100644 index 889f882415..0000000000 --- a/sysdeps/unix/sysv/linux/hppa/bits/ipc.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright (C) 1995-2019 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 - <http://www.gnu.org/licenses/>. */ - -#ifndef _SYS_IPC_H -# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead." -#endif - -#include <bits/types.h> -#include <bits/wordsize.h> - -/* Mode bits for `msgget', `semget', and `shmget'. */ -#define IPC_CREAT 01000 /* Create key if key does not exist. */ -#define IPC_EXCL 02000 /* Fail if key exists. */ -#define IPC_NOWAIT 04000 /* Return error on wait. */ - -/* Control commands for `msgctl', `semctl', and `shmctl'. */ -#define IPC_RMID 0 /* Remove identifier. */ -#define IPC_SET 1 /* Set `ipc_perm' options. */ -#define IPC_STAT 2 /* Get `ipc_perm' options. */ -#ifdef __USE_GNU -# define IPC_INFO 3 /* See ipcs. */ -#endif - -/* Special key values. */ -#define IPC_PRIVATE ((__key_t) 0) /* Private key. */ - - -/* Data structure used to pass permission information to IPC operations. */ -struct ipc_perm - { - __key_t __key; /* Key. */ - __uid_t uid; /* Owner's user ID. */ - __gid_t gid; /* Owner's group ID. */ - __uid_t cuid; /* Creator's user ID. */ - __gid_t cgid; /* Creator's group ID. */ -#if __WORDSIZE == 32 - unsigned short int __pad1; - unsigned short int mode; /* Read/write permission. */ - unsigned short int __pad2; -#else - __mode_t mode; /* Read/write permission. */ - unsigned short int __pad2; -#endif - unsigned short int __seq; /* Sequence number. */ - unsigned int __pad3; - __extension__ unsigned long long int __glibc_reserved1; - __extension__ unsigned long long int __glibc_reserved2; - }; diff --git a/sysdeps/unix/sysv/linux/ia64/bits/ipc.h b/sysdeps/unix/sysv/linux/ia64/bits/ipc.h deleted file mode 100644 index 6f9705e28a..0000000000 --- a/sysdeps/unix/sysv/linux/ia64/bits/ipc.h +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (C) 2000-2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by David Mosberger-Tang <davidm@hpl.hp.com> - - 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 - <http://www.gnu.org/licenses/>. */ - -#ifndef _SYS_IPC_H -# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead." -#endif - -#include <sys/types.h> - -/* Mode bits for `msgget', `semget', and `shmget'. */ -#define IPC_CREAT 01000 /* Create key if key does not exist. */ -#define IPC_EXCL 02000 /* Fail if key exists. */ -#define IPC_NOWAIT 04000 /* Return error on wait. */ - -/* Control commands for `msgctl', `semctl', and `shmctl'. */ -#define IPC_RMID 0 /* Remove identifier. */ -#define IPC_SET 1 /* Set `ipc_perm' options. */ -#define IPC_STAT 2 /* Get `ipc_perm' options. */ -#define IPC_INFO 3 /* See ipcs. */ - -/* Special key values. */ -#define IPC_PRIVATE ((__key_t) 0) /* Private key. */ - - -/* Data structure used to pass permission information to IPC operations. */ -struct ipc_perm - { - __key_t __key; /* Key. */ - __uid_t uid; /* Owner's user ID. */ - __gid_t gid; /* Owner's group ID. */ - __uid_t cuid; /* Creator's user ID. */ - __gid_t cgid; /* Creator's group ID. */ - __mode_t mode; /* Read/write permission. */ - unsigned short int __seq; /* Sequence number. */ - unsigned short int __pad1; - unsigned long int __glibc_reserved1; - unsigned long int __glibc_reserved2; - }; diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h index 42df1260c3..8b437e8e4e 100644 --- a/sysdeps/unix/sysv/linux/kernel-features.h +++ b/sysdeps/unix/sysv/linux/kernel-features.h @@ -83,6 +83,15 @@ /* The generic default __IPC_64 value is 0x0, however some architectures require a different value of 0x100. */ #define __ASSUME_SYSVIPC_DEFAULT_IPC_64 1 +/* Assume that ipc_perm MODE kernel ABI has a 32-bit size or it is has padding + on the correct place (so if userland defines it as 32-bit, large values + will use the padding). + All supported architectures reserve 32-bit MODE space with extra padding. + However, some kernel ABI interfaces still expected a 16-bit field. This + is only an issue is arch-defined IPC_PERM padding is on a wrong position + regarding endianness. For this case, the IPC control routines (msgctl, + semctl, and semctl) requires to shift the value for the correct place. */ +#define __ASSUME_SYSVIPC_SUPPORT_MODE32 1 /* Support for p{read,write}v2 was added in 4.6. However Linux default implementation does not assume the __ASSUME_* and instead use a fallback diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 05633b3cb8..a2be040dfc 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -129,6 +129,9 @@ GLIBC_2.29 posix_spawn_file_actions_addchdir_np F GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 msgctl F +GLIBC_2.30 semctl F +GLIBC_2.30 shmctl F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.4 _Exit F diff --git a/sysdeps/unix/sysv/linux/m68k/kernel-features.h b/sysdeps/unix/sysv/linux/m68k/kernel-features.h index c9be6bc167..dbf1bad597 100644 --- a/sysdeps/unix/sysv/linux/m68k/kernel-features.h +++ b/sysdeps/unix/sysv/linux/m68k/kernel-features.h @@ -55,3 +55,4 @@ # undef __ASSUME_DIRECT_SYSVIPC_SYSCALLS # undef __ASSUME_SYSVIPC_DEFAULT_IPC_64 #endif +#undef __ASSUME_SYSVIPC_SUPPORT_MODE32 diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index 47eb7b4608..6f8f77de1d 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -2148,6 +2148,9 @@ GLIBC_2.3.4 xdr_quad_t F GLIBC_2.3.4 xdr_u_quad_t F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 msgctl F +GLIBC_2.30 semctl F +GLIBC_2.30 shmctl F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist index f7ced487f7..2f7302165e 100644 --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist @@ -2135,5 +2135,8 @@ GLIBC_2.29 posix_spawn_file_actions_addchdir_np F GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 msgctl F +GLIBC_2.30 semctl F +GLIBC_2.30 shmctl F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F diff --git a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h index 3575818e1b..d2027706bc 100644 --- a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h +++ b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h @@ -15,6 +15,7 @@ License along with the GNU C Library. If not, see <http://www.gnu.org/licenses/>. */ +#include <endian.h> /* All supported kernel versions for MicroBlaze have these syscalls. */ #define __ASSUME_SOCKET_SYSCALL 1 @@ -69,3 +70,6 @@ #define __ASSUME_CLONE_BACKWARDS3 #undef __ASSUME_SYSVIPC_DEFAULT_IPC_64 +#if __BYTE_ORDER == __BIG_ENDIAN +# undef __ASSUME_SYSVIPC_SUPPORT_MODE32 +#endif diff --git a/sysdeps/unix/sysv/linux/mips/bits/ipc.h b/sysdeps/unix/sysv/linux/mips/bits/ipc.h deleted file mode 100644 index 5f8985fadd..0000000000 --- a/sysdeps/unix/sysv/linux/mips/bits/ipc.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (C) 1995-2019 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 - <http://www.gnu.org/licenses/>. */ - -#ifndef _SYS_IPC_H -# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead." -#endif - -#include <bits/types.h> - -/* Mode bits for `msgget', `semget', and `shmget'. */ -#define IPC_CREAT 01000 /* Create key if key does not exist. */ -#define IPC_EXCL 02000 /* Fail if key exists. */ -#define IPC_NOWAIT 04000 /* Return error on wait. */ - -/* Control commands for `msgctl', `semctl', and `shmctl'. */ -#define IPC_RMID 0 /* Remove identifier. */ -#define IPC_SET 1 /* Set `ipc_perm' options. */ -#define IPC_STAT 2 /* Get `ipc_perm' options. */ -#ifdef __USE_GNU -# define IPC_INFO 3 /* See ipcs. */ -#endif - -/* Special key values. */ -#define IPC_PRIVATE ((__key_t) 0) /* Private key. */ - - -/* Data structure used to pass permission information to IPC operations. */ -struct ipc_perm - { - __key_t __key; /* Key. */ - unsigned int uid; /* Owner's user ID. */ - unsigned int gid; /* Owner's group ID. */ - unsigned int cuid; /* Creator's user ID. */ - unsigned int cgid; /* Creator's group ID. */ - unsigned int mode; /* Read/write permission. */ - unsigned short int __seq; /* Sequence number. */ - unsigned short int __pad1; - unsigned long int __glibc_reserved1; - unsigned long int __glibc_reserved2; -}; diff --git a/sysdeps/unix/sysv/linux/msgctl.c b/sysdeps/unix/sysv/linux/msgctl.c index 852c66884f..5034a88969 100644 --- a/sysdeps/unix/sysv/linux/msgctl.c +++ b/sysdeps/unix/sysv/linux/msgctl.c @@ -23,11 +23,15 @@ #include <errno.h> #ifndef DEFAULT_VERSION -# define DEFAULT_VERSION GLIBC_2_2 +# ifdef __ASSUME_SYSVIPC_SUPPORT_MODE32 +# define DEFAULT_VERSION GLIBC_2_2 +# else +# define DEFAULT_VERSION GLIBC_2_30 +# endif #endif -int -__new_msgctl (int msqid, int cmd, struct msqid_ds *buf) +static int +msgctl_syscall (int msqid, int cmd, struct msqid_ds *buf) { #ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS return INLINE_SYSCALL_CALL (msgctl, msqid, cmd | __IPC_64, buf); @@ -36,8 +40,54 @@ __new_msgctl (int msqid, int cmd, struct msqid_ds *buf) buf); #endif } + +int +__new_msgctl (int msqid, int cmd, struct msqid_ds *buf) +{ + /* POSIX states ipc_perm mode should have type of mode_t. */ + _Static_assert (sizeof ((struct msqid_ds){0}.msg_perm.mode) + == sizeof (mode_t), + "sizeof (msqid_ds.msg_perm.mode) != sizeof (mode_t)"); + +#ifndef __ASSUME_SYSVIPC_SUPPORT_MODE32 + struct msqid_ds tmpds; + if (cmd == IPC_SET) + { + tmpds = *buf; + tmpds.msg_perm.mode *= 0x10000U; + buf = &tmpds; + } +#endif + + int ret = msgctl_syscall (msqid, cmd, buf); + +#ifndef __ASSUME_SYSVIPC_SUPPORT_MODE32 + if (ret >= 0) + { + switch (cmd) + { + case IPC_STAT: + case MSG_STAT: + case MSG_STAT_ANY: + buf->msg_perm.mode >>= 16; + } + } +#endif + + return ret; +} versioned_symbol (libc, __new_msgctl, msgctl, DEFAULT_VERSION); +#if !defined __ASSUME_SYSVIPC_SUPPORT_MODE32 \ + && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_30) +int +attribute_compat_text_section +__msgctl_mode16 (int msqid, int cmd, struct msqid_ds *buf) +{ + return msgctl_syscall (msqid, cmd, buf); +} +compat_symbol (libc, __msgctl_mode16, msgctl, GLIBC_2_2); +#endif #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) struct __old_msqid_ds diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/ipc.h b/sysdeps/unix/sysv/linux/powerpc/bits/ipc-perm.h similarity index 62% rename from sysdeps/unix/sysv/linux/powerpc/bits/ipc.h rename to sysdeps/unix/sysv/linux/powerpc/bits/ipc-perm.h index f237c8ed10..022b337764 100644 --- a/sysdeps/unix/sysv/linux/powerpc/bits/ipc.h +++ b/sysdeps/unix/sysv/linux/powerpc/bits/ipc-perm.h @@ -1,4 +1,5 @@ -/* Copyright (C) 1995-2019 Free Software Foundation, Inc. +/* struct ipc_perm definition. + Copyright (C) 1995-2019 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 @@ -16,28 +17,9 @@ <http://www.gnu.org/licenses/>. */ #ifndef _SYS_IPC_H -# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead." +# error "Never use <bits/ipc-perm.h> directly; include <sys/ipc.h> instead." #endif -#include <bits/types.h> - -/* Mode bits for `msgget', `semget', and `shmget'. */ -#define IPC_CREAT 01000 /* Create key if key does not exist. */ -#define IPC_EXCL 02000 /* Fail if key exists. */ -#define IPC_NOWAIT 04000 /* Return error on wait. */ - -/* Control commands for `msgctl', `semctl', and `shmctl'. */ -#define IPC_RMID 0 /* Remove identifier. */ -#define IPC_SET 1 /* Set `ipc_perm' options. */ -#define IPC_STAT 2 /* Get `ipc_perm' options. */ -#ifdef __USE_GNU -# define IPC_INFO 3 /* See ipcs. */ -#endif - -/* Special key values. */ -#define IPC_PRIVATE ((__key_t) 0) /* Private key. */ - - /* Data structure used to pass permission information to IPC operations. */ struct ipc_perm { diff --git a/sysdeps/unix/sysv/linux/s390/bits/ipc.h b/sysdeps/unix/sysv/linux/s390/bits/ipc.h deleted file mode 100644 index 8cc7ed9abb..0000000000 --- a/sysdeps/unix/sysv/linux/s390/bits/ipc.h +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (C) 2001-2019 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 - <http://www.gnu.org/licenses/>. */ - -#ifndef _SYS_IPC_H -# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead." -#endif - -#include <bits/types.h> -#include <bits/wordsize.h> - -/* Mode bits for `msgget', `semget', and `shmget'. */ -#define IPC_CREAT 01000 /* Create key if key does not exist. */ -#define IPC_EXCL 02000 /* Fail if key exists. */ -#define IPC_NOWAIT 04000 /* Return error on wait. */ - -/* Control commands for `msgctl', `semctl', and `shmctl'. */ -#define IPC_RMID 0 /* Remove identifier. */ -#define IPC_SET 1 /* Set `ipc_perm' options. */ -#define IPC_STAT 2 /* Get `ipc_perm' options. */ -#ifdef __USE_GNU -#define IPC_INFO 3 /* See ipcs. */ -#endif - -/* Special key values. */ -#define IPC_PRIVATE ((__key_t) 0) /* Private key. */ - - -/* Data structure used to pass permission information to IPC operations. */ -struct ipc_perm - { - __key_t __key; /* Key. */ - __uid_t uid; /* Owner's user ID. */ - __gid_t gid; /* Owner's group ID. */ - __uid_t cuid; /* Creator's user ID. */ - __gid_t cgid; /* Creator's group ID. */ -#if __WORDSIZE == 64 - __mode_t mode; /* Read/write permission. */ -#else - unsigned short int mode; /* Read/write permission. */ - unsigned short int __pad1; -#endif - unsigned short int __seq; /* Sequence number. */ - unsigned short int __pad2; - unsigned long int __glibc_reserved1; - unsigned long int __glibc_reserved2; - }; diff --git a/sysdeps/unix/sysv/linux/s390/kernel-features.h b/sysdeps/unix/sysv/linux/s390/kernel-features.h index 7997a78e1d..8b43b372fc 100644 --- a/sysdeps/unix/sysv/linux/s390/kernel-features.h +++ b/sysdeps/unix/sysv/linux/s390/kernel-features.h @@ -50,6 +50,9 @@ # undef __ASSUME_DIRECT_SYSVIPC_SYSCALLS # undef __ASSUME_SYSVIPC_DEFAULT_IPC_64 #endif +#ifndef __s390x__ +# undef __ASSUME_SYSVIPC_SUPPORT_MODE32 +#endif #undef __ASSUME_CLONE_DEFAULT #define __ASSUME_CLONE_BACKWARDS2 diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index 576295deff..3aa48fc87c 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -2173,6 +2173,9 @@ GLIBC_2.30 __nldbl_warn F GLIBC_2.30 __nldbl_warnx F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 msgctl F +GLIBC_2.30 semctl F +GLIBC_2.30 shmctl F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.4 _IO_fprintf F diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c index 6f4e46dde3..7131f85326 100644 --- a/sysdeps/unix/sysv/linux/semctl.c +++ b/sysdeps/unix/sysv/linux/semctl.c @@ -33,12 +33,33 @@ union semun }; #ifndef DEFAULT_VERSION -# define DEFAULT_VERSION GLIBC_2_2 +# ifdef __ASSUME_SYSVIPC_SUPPORT_MODE32 +# define DEFAULT_VERSION GLIBC_2_2 +# else +# define DEFAULT_VERSION GLIBC_2_30 +# endif #endif +static int +semctl_syscall (int semid, int semnum, int cmd, union semun arg) +{ +#ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS + return INLINE_SYSCALL_CALL (semctl, semid, semnum, cmd | __IPC_64, + arg.array); +#else + return INLINE_SYSCALL_CALL (ipc, IPCOP_semctl, semid, semnum, cmd | __IPC_64, + SEMCTL_ARG_ADDRESS (arg)); +#endif +} + int __new_semctl (int semid, int semnum, int cmd, ...) { + /* POSIX states ipc_perm mode should have type of mode_t. */ + _Static_assert (sizeof ((struct semid_ds){0}.sem_perm.mode) + == sizeof (mode_t), + "sizeof (msqid_ds.msg_perm.mode) != sizeof (mode_t)"); + union semun arg = { 0 }; va_list ap; @@ -59,16 +80,65 @@ __new_semctl (int semid, int semnum, int cmd, ...) break; } -#ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS - return INLINE_SYSCALL_CALL (semctl, semid, semnum, cmd | __IPC_64, - arg.array); -#else - return INLINE_SYSCALL_CALL (ipc, IPCOP_semctl, semid, semnum, cmd | __IPC_64, - SEMCTL_ARG_ADDRESS (arg)); +#ifndef __ASSUME_SYSVIPC_SUPPORT_MODE32 + struct semid_ds tmpds; + if (cmd == IPC_SET) + { + tmpds = *arg.buf; + tmpds.sem_perm.mode *= 0x10000U; + arg.buf = &tmpds; + } +#endif + + int ret = semctl_syscall (semid, semnum, cmd, arg); + +#ifndef __ASSUME_SYSVIPC_SUPPORT_MODE32 + if (ret >= 0) + { + switch (cmd) + { + case IPC_STAT: + case SEM_STAT: + case SEM_STAT_ANY: + arg.buf->sem_perm.mode >>= 16; + } + } #endif + + return ret; } versioned_symbol (libc, __new_semctl, semctl, DEFAULT_VERSION); +#if !defined __ASSUME_SYSVIPC_SUPPORT_MODE32 \ + && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_30) +int +attribute_compat_text_section +__semctl_mode16 (int semid, int semnum, int cmd, ...) +{ + union semun arg = { 0 }; + va_list ap; + + /* Get the argument only if required. */ + switch (cmd) + { + case SETVAL: /* arg.val */ + case GETALL: /* arg.array */ + case SETALL: + case IPC_STAT: /* arg.buf */ + case IPC_SET: + case SEM_STAT: + case IPC_INFO: /* arg.__buf */ + case SEM_INFO: + va_start (ap, cmd); + arg = va_arg (ap, union semun); + va_end (ap); + break; + } + + return semctl_syscall (semid, semnum, cmd, arg); +} +compat_symbol (libc, __semctl_mode16, semctl, GLIBC_2_2); +#endif #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) /* Since semctl use a variadic argument for semid_ds there is not need to diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist index 41977f6e9c..aa59e3bc34 100644 --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist @@ -2043,6 +2043,9 @@ GLIBC_2.3.4 xdr_quad_t F GLIBC_2.3.4 xdr_u_quad_t F GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F +GLIBC_2.30 msgctl F +GLIBC_2.30 semctl F +GLIBC_2.30 shmctl F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/sh/kernel-features.h b/sysdeps/unix/sysv/linux/sh/kernel-features.h index e793a83a6f..e584b5218b 100644 --- a/sysdeps/unix/sysv/linux/sh/kernel-features.h +++ b/sysdeps/unix/sysv/linux/sh/kernel-features.h @@ -20,6 +20,8 @@ #ifndef __KERNEL_FEATURES_SH__ # define __KERNEL_FEATURES_SH__ +#include <endian.h> + /* These syscalls were added for SH in 2.6.37. */ #define __ASSUME_SOCKET_SYSCALL 1 #define __ASSUME_BIND_SYSCALL 1 @@ -46,6 +48,9 @@ # undef __ASSUME_DIRECT_SYSVIPC_SYSCALLS # undef __ASSUME_SYSVIPC_DEFAULT_IPC_64 #endif +#if __BYTE_ORDER == __BIG_ENDIAN +# undef __ASSUME_SYSVIPC_SUPPORT_MODE32 +#endif /* Support for several syscalls was added in 4.8. */ #if __LINUX_KERNEL_VERSION < 0x040800 diff --git a/sysdeps/unix/sysv/linux/shmctl.c b/sysdeps/unix/sysv/linux/shmctl.c index ba1dc28376..234fb363b8 100644 --- a/sysdeps/unix/sysv/linux/shmctl.c +++ b/sysdeps/unix/sysv/linux/shmctl.c @@ -23,15 +23,16 @@ #include <shlib-compat.h> #include <errno.h> - #ifndef DEFAULT_VERSION -# define DEFAULT_VERSION GLIBC_2_2 +# ifdef __ASSUME_SYSVIPC_SUPPORT_MODE32 +# define DEFAULT_VERSION GLIBC_2_2 +# else +# define DEFAULT_VERSION GLIBC_2_30 +# endif #endif - -/* Provide operations to control over shared memory segments. */ -int -__new_shmctl (int shmid, int cmd, struct shmid_ds *buf) +static int +shmctl_syscall (int shmid, int cmd, struct shmid_ds *buf) { #ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS return INLINE_SYSCALL_CALL (shmctl, shmid, cmd | __IPC_64, buf); @@ -40,8 +41,55 @@ __new_shmctl (int shmid, int cmd, struct shmid_ds *buf) buf); #endif } + +/* Provide operations to control over shared memory segments. */ +int +__new_shmctl (int shmid, int cmd, struct shmid_ds *buf) +{ + /* POSIX states ipc_perm mode should have type of mode_t. */ + _Static_assert (sizeof ((struct shmid_ds){0}.shm_perm.mode) + == sizeof (mode_t), + "sizeof (msqid_ds.msg_perm.mode) != sizeof (mode_t)"); + +#ifndef __ASSUME_SYSVIPC_SUPPORT_MODE32 + struct shmid_ds tmpds; + if (cmd == IPC_SET) + { + tmpds = *buf; + tmpds.shm_perm.mode *= 0x10000U; + buf = &tmpds; + } +#endif + + int ret = shmctl_syscall (shmid, cmd, buf); + +#ifndef __ASSUME_SYSVIPC_SUPPORT_MODE32 + if (ret >= 0) + { + switch (cmd) + { + case IPC_STAT: + case SHM_STAT: + case SHM_STAT_ANY: + buf->shm_perm.mode >>= 16; + } + } +#endif + + return ret; +} versioned_symbol (libc, __new_shmctl, shmctl, DEFAULT_VERSION); +#if !defined __ASSUME_SYSVIPC_SUPPORT_MODE32 \ + && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_30) +int +attribute_compat_text_section +__shmctl_mode16 (int shmid, int cmd, struct shmid_ds *buf) +{ + return shmctl_syscall (shmid, cmd, buf); +} +compat_symbol (libc, __shmctl_mode16, shmctl, GLIBC_2_2); +#endif #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) struct __old_shmid_ds diff --git a/sysdeps/unix/sysv/linux/sparc/bits/ipc.h b/sysdeps/unix/sysv/linux/sparc/bits/ipc-perm.h similarity index 59% rename from sysdeps/unix/sysv/linux/sparc/bits/ipc.h rename to sysdeps/unix/sysv/linux/sparc/bits/ipc-perm.h index b67c25ec61..95ac584752 100644 --- a/sysdeps/unix/sysv/linux/sparc/bits/ipc.h +++ b/sysdeps/unix/sysv/linux/sparc/bits/ipc-perm.h @@ -1,4 +1,5 @@ -/* Copyright (C) 1995-2019 Free Software Foundation, Inc. +/* struct ipc_perm definition. + Copyright (C) 1995-2019 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 @@ -16,29 +17,9 @@ <http://www.gnu.org/licenses/>. */ #ifndef _SYS_IPC_H -# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead." +# error "Never use <bits/ipc-perm.h> directly; include <sys/ipc.h> instead." #endif -#include <bits/types.h> -#include <bits/wordsize.h> - -/* Mode bits for `msgget', `semget', and `shmget'. */ -#define IPC_CREAT 01000 /* Create key if key does not exist. */ -#define IPC_EXCL 02000 /* Fail if key exists. */ -#define IPC_NOWAIT 04000 /* Return error on wait. */ - -/* Control commands for `msgctl', `semctl', and `shmctl'. */ -#define IPC_RMID 0 /* Remove identifier. */ -#define IPC_SET 1 /* Set `ipc_perm' options. */ -#define IPC_STAT 2 /* Get `ipc_perm' options. */ -#ifdef __USE_GNU -# define IPC_INFO 3 /* See ipcs. */ -#endif - -/* Special key values. */ -#define IPC_PRIVATE ((__key_t) 0) /* Private key. */ - - /* Data structure used to pass permission information to IPC operations. */ struct ipc_perm { @@ -47,14 +28,8 @@ struct ipc_perm __gid_t gid; /* Owner's group ID. */ __uid_t cuid; /* Creator's user ID. */ __gid_t cgid; /* Creator's group ID. */ -#if __WORDSIZE == 32 - unsigned short int __pad1; - unsigned short int mode; /* Read/write permission. */ - unsigned short int __pad2; -#else __mode_t mode; /* Read/write permission. */ unsigned short int __pad1; -#endif unsigned short int __seq; /* Sequence number. */ __extension__ unsigned long long int __glibc_reserved1; __extension__ unsigned long long int __glibc_reserved2;