From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
To: libc-alpha@sourceware.org
Subject: Re: [PATCH v2 4/4] sysvipc: Set ipc_perm mode as mode_t (BZ#18231)
Date: Tue, 27 Aug 2019 14:09:00 -0000 [thread overview]
Message-ID: <bd650b42-9db5-90fb-d4b8-42bdc124f7f6@linaro.org> (raw)
In-Reply-To: <20190730123030.3376-4-adhemerval.zanella@linaro.org>
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;
>
next prev parent reply other threads:[~2019-08-27 14:09 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-07-30 12:31 [PATCH v2 1/4] arm: Split BE/LE abilist Adhemerval Zanella
2019-07-30 12:31 ` [PATCH v2 4/4] sysvipc: Set ipc_perm mode as mode_t (BZ#18231) Adhemerval Zanella
2019-07-30 19:53 ` Joseph Myers
2019-07-30 20:09 ` Adhemerval Zanella
2019-08-27 14:09 ` Adhemerval Zanella [this message]
2019-08-27 16:41 ` Joseph Myers
2019-08-27 18:31 ` Adhemerval Zanella
2019-08-27 14:30 ` Rich Felker
2019-08-27 19:44 ` Adhemerval Zanella
2019-07-30 12:31 ` [PATCH v2 3/4] sh: Split BE/LE abilist Adhemerval Zanella
2019-08-27 14:09 ` Adhemerval Zanella
2019-07-30 12:31 ` [PATCH v2 2/4] microblaze: " Adhemerval Zanella
2019-08-27 14:09 ` Adhemerval Zanella
2019-08-27 14:08 ` [PATCH v2 1/4] arm: " Adhemerval Zanella
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=bd650b42-9db5-90fb-d4b8-42bdc124f7f6@linaro.org \
--to=adhemerval.zanella@linaro.org \
--cc=libc-alpha@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).