Message ID | 20190829163631.13647-1-adhemerval.zanella@linaro.org |
---|---|
State | Accepted |
Commit | 2f959dfe849e0646e27403f2e4091536496ac0f0 |
Headers | show |
Series | [v5] sysvipc: Set ipc_perm mode as mode_t (BZ#18231) | expand |
If no one opposes I will commit this. On 29/08/2019 13:36, Adhemerval Zanella wrote: > Changes from previous version: > > - Fixed symbols versioning for m68k and s390. > > -- > > 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_BROKEN_MODE_T, which the > required ABIs define. > > 4. For the ABIs that define __ASSUME_SYSVIPC_BROKEN_MODE_T, it also > require 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. > > I also did a sanity test against armeb qemu usermode for the sysvipc > tests. > > [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_BROKEN_MODE_T): > Define. > * sysdeps/sysv/linux/microblaze/kernel-features.h: Likewise. > * sysdeps/unix/sysv/linux/s390/kernel-features.h > [!__s390x__] (__ASSUME_SYSVIPC_BROKEN_MODE_T): Define. > * sysdeps/unix/sysv/linux/sh/kernel-features.h > (__ASSUME_SYSVIPC_BROKEN_MODE_T): 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: Add comment about > __ASSUME_SYSVIPC_BROKEN_MODE_T semantic. > * sysdeps/unix/sysv/linux/msgctl.c (DEFAULT_VERSION): Define as > 2.31 if __ASSUME_SYSVIPC_BROKEN_MODE_T is defined. > (msgctl_syscall, __msgctl_mode16): New symbol. > (__new_msgctl): Add bits for __ASSUME_SYSVIPC_BROKEN_MODE_T. > * sysdeps/unix/sysv/linux/semctl.c: Likewise. > * sysdeps/unix/sysv/linux/shmctl.c: Likewise. > * sysdeps/unix/sysv/linux/arm/be/libc.abilist (GLIBC_2.31): Add > msgctl, semctl, and shmctl. > * sysdeps/sysv/linux/microblaze/be/libc.abilist: Likewise. > * 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. > * conform/data/sys/ipc.h-data: Only xfail {struct ipc_perm} mode_t > mode for Hurd. > * sysdeps/unix/sysv/linux/m68k/Versions (libc) [GLIBC_2.31]: Add > msgctl, semctl, and shmctl. > * sysdeps/unix/sysv/linux/arm/be/Versions: New file. > * sysdeps/unix/sysv/linux/microblaze/be/Versions: Likewise. > * sysdeps/unix/sysv/linux/sh/be/Versions: Likewise. > > [1] http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_ipc.h.html > --- > ChangeLog | 49 +++++++++++ > conform/data/sys/ipc.h-data | 3 +- > 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/Versions | 5 ++ > sysdeps/unix/sysv/linux/arm/be/libc.abilist | 3 + > sysdeps/unix/sysv/linux/arm/kernel-features.h | 5 ++ > 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 | 8 ++ > sysdeps/unix/sysv/linux/m68k/Versions | 3 + > .../sysv/linux/m68k/coldfire/libc.abilist | 3 + > .../unix/sysv/linux/m68k/kernel-features.h | 1 + > .../unix/sysv/linux/m68k/m680x0/libc.abilist | 3 + > .../unix/sysv/linux/microblaze/be/Versions | 5 ++ > .../sysv/linux/microblaze/be/libc.abilist | 3 + > .../sysv/linux/microblaze/kernel-features.h | 5 ++ > 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 + > sysdeps/unix/sysv/linux/s390/s390-32/Versions | 3 + > .../unix/sysv/linux/s390/s390-32/libc.abilist | 3 + > sysdeps/unix/sysv/linux/semctl.c | 84 +++++++++++++++++-- > sysdeps/unix/sysv/linux/sh/be/Versions | 5 ++ > 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 +------ > 34 files changed, 386 insertions(+), 421 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/arm/be/Versions > 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 > create mode 100644 sysdeps/unix/sysv/linux/microblaze/be/Versions > 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 > create mode 100644 sysdeps/unix/sysv/linux/sh/be/Versions > 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..1364b07e87 100644 > --- a/conform/data/sys/ipc.h-data > +++ b/conform/data/sys/ipc.h-data > @@ -6,8 +6,7 @@ xfail[i386-gnu]-element {struct ipc_perm} uid_t uid > 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 40db26e733..4dd5acf8da 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/Versions b/sysdeps/unix/sysv/linux/arm/be/Versions > new file mode 100644 > index 0000000000..a50cd57630 > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/arm/be/Versions > @@ -0,0 +1,5 @@ > +libc { > + GLIBC_2.31 { > + msgctl; semctl; shmctl; > + } > +} > diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist > index bc3df8dcea..2a24b4996f 100644 > --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist > +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist > @@ -130,6 +130,9 @@ GLIBC_2.30 getdents64 F > GLIBC_2.30 gettid F > GLIBC_2.30 tgkill F > GLIBC_2.30 twalk_r F > +GLIBC_2.31 msgctl F > +GLIBC_2.31 semctl F > +GLIBC_2.31 shmctl F > GLIBC_2.4 _Exit F > GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 > GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 > diff --git a/sysdeps/unix/sysv/linux/arm/kernel-features.h b/sysdeps/unix/sysv/linux/arm/kernel-features.h > index 4220adff37..c0dcd6ded0 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 > @@ -49,3 +50,7 @@ > > #undef __ASSUME_CLONE_DEFAULT > #define __ASSUME_CLONE_BACKWARDS 1 > + > +#if __BYTE_ORDER == __BIG_ENDIAN > +# define __ASSUME_SYSVIPC_BROKEN_MODE_T > +#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 1518bb5228..91152158f1 100644 > --- a/sysdeps/unix/sysv/linux/kernel-features.h > +++ b/sysdeps/unix/sysv/linux/kernel-features.h > @@ -81,6 +81,14 @@ > either support ipc syscall and/or all the ipc correspondent syscalls. */ > #define __ASSUME_DIRECT_SYSVIPC_SYSCALLS 1 > > +/* All supported architectures reserve a 32-bit for MODE field in sysvipc > + ipc_perm. However, some kernel ABI interfaces still expect a 16-bit > + field. This is only an issue if arch-defined IPC_PERM padding is on a > + wrong position regarding endianness. In this case, the IPC control > + routines (msgctl, semctl, and semtctl) requires to shift the value to > + correct place. > + The ABIs that requires it define __ASSUME_SYSVIPC_BROKEN_MODE_T. */ > + > /* 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 > implementation based on p{read,write}v and returning an error for > diff --git a/sysdeps/unix/sysv/linux/m68k/Versions b/sysdeps/unix/sysv/linux/m68k/Versions > index 8e72cd18cb..4b18795513 100644 > --- a/sysdeps/unix/sysv/linux/m68k/Versions > +++ b/sysdeps/unix/sysv/linux/m68k/Versions > @@ -37,6 +37,9 @@ libc { > GLIBC_2.11 { > fallocate64; > } > + GLIBC_2.31 { > + msgctl; semctl; shmctl; > + } > GLIBC_2.12 { > __m68k_read_tp; > } > diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist > index 05633b3cb8..afd9e2cecb 100644 > --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist > +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist > @@ -131,6 +131,9 @@ GLIBC_2.30 getdents64 F > GLIBC_2.30 gettid F > GLIBC_2.30 tgkill F > GLIBC_2.30 twalk_r F > +GLIBC_2.31 msgctl F > +GLIBC_2.31 semctl F > +GLIBC_2.31 shmctl F > GLIBC_2.4 _Exit F > GLIBC_2.4 _IO_2_1_stderr_ D 0x98 > GLIBC_2.4 _IO_2_1_stdin_ D 0x98 > diff --git a/sysdeps/unix/sysv/linux/m68k/kernel-features.h b/sysdeps/unix/sysv/linux/m68k/kernel-features.h > index 1976724362..a130ce1b7c 100644 > --- a/sysdeps/unix/sysv/linux/m68k/kernel-features.h > +++ b/sysdeps/unix/sysv/linux/m68k/kernel-features.h > @@ -52,3 +52,4 @@ > > /* m68k only supports ipc syscall. */ > #undef __ASSUME_DIRECT_SYSVIPC_SYSCALLS > +#define __ASSUME_SYSVIPC_BROKEN_MODE_T > diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist > index 47eb7b4608..ba69765d9b 100644 > --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist > +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist > @@ -2150,6 +2150,9 @@ GLIBC_2.30 getdents64 F > GLIBC_2.30 gettid F > GLIBC_2.30 tgkill F > GLIBC_2.30 twalk_r F > +GLIBC_2.31 msgctl F > +GLIBC_2.31 semctl F > +GLIBC_2.31 shmctl F > GLIBC_2.4 __confstr_chk F > GLIBC_2.4 __fgets_chk F > GLIBC_2.4 __fgets_unlocked_chk F > diff --git a/sysdeps/unix/sysv/linux/microblaze/be/Versions b/sysdeps/unix/sysv/linux/microblaze/be/Versions > new file mode 100644 > index 0000000000..a50cd57630 > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/microblaze/be/Versions > @@ -0,0 +1,5 @@ > +libc { > + GLIBC_2.31 { > + msgctl; semctl; shmctl; > + } > +} > diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist > index f7ced487f7..ac55b0acd7 100644 > --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist > +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist > @@ -2137,3 +2137,6 @@ GLIBC_2.30 getdents64 F > GLIBC_2.30 gettid F > GLIBC_2.30 tgkill F > GLIBC_2.30 twalk_r F > +GLIBC_2.31 msgctl F > +GLIBC_2.31 semctl F > +GLIBC_2.31 shmctl F > diff --git a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h > index a787409295..1be0c5eb18 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 > @@ -67,3 +68,7 @@ > > #undef __ASSUME_CLONE_DEFAULT > #define __ASSUME_CLONE_BACKWARDS3 > + > +#if __BYTE_ORDER == __BIG_ENDIAN > +# define __ASSUME_SYSVIPC_BROKEN_MODE_T > +#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 2d49567686..7c2ac8b82c 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 > +# ifndef __ASSUME_SYSVIPC_BROKEN_MODE_T > +# define DEFAULT_VERSION GLIBC_2_2 > +# else > +# define DEFAULT_VERSION GLIBC_2_31 > +# 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)"); > + > +#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T > + 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); > + > +#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T > + 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_BROKEN_MODE_T \ > + && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_31) > +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 8fdf38c454..c560eb78ab 100644 > --- a/sysdeps/unix/sysv/linux/s390/kernel-features.h > +++ b/sysdeps/unix/sysv/linux/s390/kernel-features.h > @@ -47,6 +47,9 @@ > > /* s390 only supports ipc syscall. */ > #undef __ASSUME_DIRECT_SYSVIPC_SYSCALLS > +#ifndef __s390x__ > +# define __ASSUME_SYSVIPC_BROKEN_MODE_T > +#endif > > #undef __ASSUME_CLONE_DEFAULT > #define __ASSUME_CLONE_BACKWARDS2 > diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/Versions b/sysdeps/unix/sysv/linux/s390/s390-32/Versions > index 1c120e8cbe..99193982a7 100644 > --- a/sysdeps/unix/sysv/linux/s390/s390-32/Versions > +++ b/sysdeps/unix/sysv/linux/s390/s390-32/Versions > @@ -49,6 +49,9 @@ libc { > GLIBC_2.11 { > fallocate64; > } > + GLIBC_2.31 { > + msgctl; semctl; shmctl; > + } > } > > libutil { > diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist > index 576295deff..42368b7bc4 100644 > --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist > +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist > @@ -2175,6 +2175,9 @@ GLIBC_2.30 getdents64 F > GLIBC_2.30 gettid F > GLIBC_2.30 tgkill F > GLIBC_2.30 twalk_r F > +GLIBC_2.31 msgctl F > +GLIBC_2.31 semctl F > +GLIBC_2.31 shmctl F > GLIBC_2.4 _IO_fprintf F > GLIBC_2.4 _IO_printf F > GLIBC_2.4 _IO_sprintf F > diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c > index d428400681..1b2104e0d9 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 > +# ifndef __ASSUME_SYSVIPC_BROKEN_MODE_T > +# define DEFAULT_VERSION GLIBC_2_2 > +# else > +# define DEFAULT_VERSION GLIBC_2_31 > +# 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)); > +#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T > + 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); > + > +#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T > + 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_BROKEN_MODE_T \ > + && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_31) > +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/Versions b/sysdeps/unix/sysv/linux/sh/be/Versions > new file mode 100644 > index 0000000000..a50cd57630 > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/sh/be/Versions > @@ -0,0 +1,5 @@ > +libc { > + GLIBC_2.31 { > + msgctl; semctl; shmctl; > + } > +} > diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist > index 41977f6e9c..68f7474212 100644 > --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist > +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist > @@ -2045,6 +2045,9 @@ GLIBC_2.30 getdents64 F > GLIBC_2.30 gettid F > GLIBC_2.30 tgkill F > GLIBC_2.30 twalk_r F > +GLIBC_2.31 msgctl F > +GLIBC_2.31 semctl F > +GLIBC_2.31 shmctl F > GLIBC_2.4 __confstr_chk F > GLIBC_2.4 __fgets_chk F > GLIBC_2.4 __fgets_unlocked_chk F > diff --git a/sysdeps/unix/sysv/linux/sh/kernel-features.h b/sysdeps/unix/sysv/linux/sh/kernel-features.h > index 0f287fbf85..f82bf49771 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 > @@ -43,6 +45,9 @@ > > /* sh only supports ipc syscall. */ > #undef __ASSUME_DIRECT_SYSVIPC_SYSCALLS > +#if __BYTE_ORDER == __BIG_ENDIAN > +# define __ASSUME_SYSVIPC_BROKEN_MODE_T > +#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 b322f205f8..e4baf71176 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 > +# ifndef __ASSUME_SYSVIPC_BROKEN_MODE_T > +# define DEFAULT_VERSION GLIBC_2_2 > +# else > +# define DEFAULT_VERSION GLIBC_2_31 > +# 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)"); > + > +#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T > + 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); > + > +#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T > + 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_BROKEN_MODE_T \ > + && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_31) > +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; >
Note that this breaks libsanitizer. Andreas. -- Andreas Schwab, SUSE Labs, schwab@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different."
* Andreas Schwab:
> Note that this breaks libsanitizer.
In what way and on which targets?
Such terse complaints are not really helpful, Andreas.
Florian
On Nov 12 2019, Florian Weimer wrote: > * Andreas Schwab: > >> Note that this breaks libsanitizer. > > In what way and on which targets? See <https://gcc.gnu.org/ml/gcc-patches/2019-11/msg00874.html>. Andreas. -- Andreas Schwab, SUSE Labs, schwab@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different."
* Andreas Schwab: > On Nov 12 2019, Florian Weimer wrote: > >> * Andreas Schwab: >> >>> Note that this breaks libsanitizer. >> >> In what way and on which targets? > > See <https://gcc.gnu.org/ml/gcc-patches/2019-11/msg00874.html>. Uh-oh. The sanitizers cannot intercept versioned symbols for various reasons. So there's no good fix here. Problems like these are the reason why I think we should not make struct layout changes merely for POSIX conformance. Thanks, Florian
On 12/11/2019 07:48, Andreas Schwab wrote: > On Nov 12 2019, Florian Weimer wrote: > >> * Andreas Schwab: >> >>> Note that this breaks libsanitizer. >> >> In what way and on which targets? > > See <https://gcc.gnu.org/ml/gcc-patches/2019-11/msg00874.html>. > > Andreas. > This is similar to BZ#16919 [1], where the culprit is essentially that there is no easy way to make libsanitizer to intercept symbol with multiple versions [2]. For BZ#16919 [3], I ended up reverting the change (with libsanitizer being one of the reasons). However I don't really see a good way forward to keep avoid fixing this kind of conformance issues or, worse, revert this change in case or possible library breakage. I would rather work towards fixing BZ#14932 instead [4], although I am not sure how libsanitizer would really work fixing it (it was hinted on [2] that they might use a different strategy and maybe with llvm-libc they move towards it). Thoughts? [1] https://sourceware.org/bugzilla/show_bug.cgi?id=16919 [2] https://github.com/google/sanitizers/issues/628 [3] https://sourceware.org/ml/libc-alpha/2016-06/msg00339.html [4] https://sourceware.org/bugzilla/show_bug.cgi?id=14932
diff --git a/conform/data/sys/ipc.h-data b/conform/data/sys/ipc.h-data index 09e8f68f8e..1364b07e87 100644 --- a/conform/data/sys/ipc.h-data +++ b/conform/data/sys/ipc.h-data @@ -6,8 +6,7 @@ xfail[i386-gnu]-element {struct ipc_perm} uid_t uid 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 40db26e733..4dd5acf8da 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/Versions b/sysdeps/unix/sysv/linux/arm/be/Versions new file mode 100644 index 0000000000..a50cd57630 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/be/Versions @@ -0,0 +1,5 @@ +libc { + GLIBC_2.31 { + msgctl; semctl; shmctl; + } +} diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist index bc3df8dcea..2a24b4996f 100644 --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist @@ -130,6 +130,9 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 msgctl F +GLIBC_2.31 semctl F +GLIBC_2.31 shmctl F GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 diff --git a/sysdeps/unix/sysv/linux/arm/kernel-features.h b/sysdeps/unix/sysv/linux/arm/kernel-features.h index 4220adff37..c0dcd6ded0 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 @@ -49,3 +50,7 @@ #undef __ASSUME_CLONE_DEFAULT #define __ASSUME_CLONE_BACKWARDS 1 + +#if __BYTE_ORDER == __BIG_ENDIAN +# define __ASSUME_SYSVIPC_BROKEN_MODE_T +#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 1518bb5228..91152158f1 100644 --- a/sysdeps/unix/sysv/linux/kernel-features.h +++ b/sysdeps/unix/sysv/linux/kernel-features.h @@ -81,6 +81,14 @@ either support ipc syscall and/or all the ipc correspondent syscalls. */ #define __ASSUME_DIRECT_SYSVIPC_SYSCALLS 1 +/* All supported architectures reserve a 32-bit for MODE field in sysvipc + ipc_perm. However, some kernel ABI interfaces still expect a 16-bit + field. This is only an issue if arch-defined IPC_PERM padding is on a + wrong position regarding endianness. In this case, the IPC control + routines (msgctl, semctl, and semtctl) requires to shift the value to + correct place. + The ABIs that requires it define __ASSUME_SYSVIPC_BROKEN_MODE_T. */ + /* 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 implementation based on p{read,write}v and returning an error for diff --git a/sysdeps/unix/sysv/linux/m68k/Versions b/sysdeps/unix/sysv/linux/m68k/Versions index 8e72cd18cb..4b18795513 100644 --- a/sysdeps/unix/sysv/linux/m68k/Versions +++ b/sysdeps/unix/sysv/linux/m68k/Versions @@ -37,6 +37,9 @@ libc { GLIBC_2.11 { fallocate64; } + GLIBC_2.31 { + msgctl; semctl; shmctl; + } GLIBC_2.12 { __m68k_read_tp; } diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 05633b3cb8..afd9e2cecb 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -131,6 +131,9 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 msgctl F +GLIBC_2.31 semctl F +GLIBC_2.31 shmctl F GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0x98 GLIBC_2.4 _IO_2_1_stdin_ D 0x98 diff --git a/sysdeps/unix/sysv/linux/m68k/kernel-features.h b/sysdeps/unix/sysv/linux/m68k/kernel-features.h index 1976724362..a130ce1b7c 100644 --- a/sysdeps/unix/sysv/linux/m68k/kernel-features.h +++ b/sysdeps/unix/sysv/linux/m68k/kernel-features.h @@ -52,3 +52,4 @@ /* m68k only supports ipc syscall. */ #undef __ASSUME_DIRECT_SYSVIPC_SYSCALLS +#define __ASSUME_SYSVIPC_BROKEN_MODE_T diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index 47eb7b4608..ba69765d9b 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -2150,6 +2150,9 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 msgctl F +GLIBC_2.31 semctl F +GLIBC_2.31 shmctl F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/microblaze/be/Versions b/sysdeps/unix/sysv/linux/microblaze/be/Versions new file mode 100644 index 0000000000..a50cd57630 --- /dev/null +++ b/sysdeps/unix/sysv/linux/microblaze/be/Versions @@ -0,0 +1,5 @@ +libc { + GLIBC_2.31 { + msgctl; semctl; shmctl; + } +} diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist index f7ced487f7..ac55b0acd7 100644 --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist @@ -2137,3 +2137,6 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 msgctl F +GLIBC_2.31 semctl F +GLIBC_2.31 shmctl F diff --git a/sysdeps/unix/sysv/linux/microblaze/kernel-features.h b/sysdeps/unix/sysv/linux/microblaze/kernel-features.h index a787409295..1be0c5eb18 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 @@ -67,3 +68,7 @@ #undef __ASSUME_CLONE_DEFAULT #define __ASSUME_CLONE_BACKWARDS3 + +#if __BYTE_ORDER == __BIG_ENDIAN +# define __ASSUME_SYSVIPC_BROKEN_MODE_T +#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 2d49567686..7c2ac8b82c 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 +# ifndef __ASSUME_SYSVIPC_BROKEN_MODE_T +# define DEFAULT_VERSION GLIBC_2_2 +# else +# define DEFAULT_VERSION GLIBC_2_31 +# 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)"); + +#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T + 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); + +#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T + 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_BROKEN_MODE_T \ + && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_31) +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 8fdf38c454..c560eb78ab 100644 --- a/sysdeps/unix/sysv/linux/s390/kernel-features.h +++ b/sysdeps/unix/sysv/linux/s390/kernel-features.h @@ -47,6 +47,9 @@ /* s390 only supports ipc syscall. */ #undef __ASSUME_DIRECT_SYSVIPC_SYSCALLS +#ifndef __s390x__ +# define __ASSUME_SYSVIPC_BROKEN_MODE_T +#endif #undef __ASSUME_CLONE_DEFAULT #define __ASSUME_CLONE_BACKWARDS2 diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/Versions b/sysdeps/unix/sysv/linux/s390/s390-32/Versions index 1c120e8cbe..99193982a7 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/Versions +++ b/sysdeps/unix/sysv/linux/s390/s390-32/Versions @@ -49,6 +49,9 @@ libc { GLIBC_2.11 { fallocate64; } + GLIBC_2.31 { + msgctl; semctl; shmctl; + } } libutil { diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index 576295deff..42368b7bc4 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -2175,6 +2175,9 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 msgctl F +GLIBC_2.31 semctl F +GLIBC_2.31 shmctl F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c index d428400681..1b2104e0d9 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 +# ifndef __ASSUME_SYSVIPC_BROKEN_MODE_T +# define DEFAULT_VERSION GLIBC_2_2 +# else +# define DEFAULT_VERSION GLIBC_2_31 +# 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)); +#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T + 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); + +#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T + 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_BROKEN_MODE_T \ + && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_31) +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/Versions b/sysdeps/unix/sysv/linux/sh/be/Versions new file mode 100644 index 0000000000..a50cd57630 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sh/be/Versions @@ -0,0 +1,5 @@ +libc { + GLIBC_2.31 { + msgctl; semctl; shmctl; + } +} diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist index 41977f6e9c..68f7474212 100644 --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist @@ -2045,6 +2045,9 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 msgctl F +GLIBC_2.31 semctl F +GLIBC_2.31 shmctl F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/sh/kernel-features.h b/sysdeps/unix/sysv/linux/sh/kernel-features.h index 0f287fbf85..f82bf49771 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 @@ -43,6 +45,9 @@ /* sh only supports ipc syscall. */ #undef __ASSUME_DIRECT_SYSVIPC_SYSCALLS +#if __BYTE_ORDER == __BIG_ENDIAN +# define __ASSUME_SYSVIPC_BROKEN_MODE_T +#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 b322f205f8..e4baf71176 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 +# ifndef __ASSUME_SYSVIPC_BROKEN_MODE_T +# define DEFAULT_VERSION GLIBC_2_2 +# else +# define DEFAULT_VERSION GLIBC_2_31 +# 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)"); + +#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T + 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); + +#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T + 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_BROKEN_MODE_T \ + && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_31) +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;