This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH v2 4/4] sysvipc: Set ipc_perm mode as mode_t (BZ#18231)


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;
> 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]