[PATCH] IPC_INFO: Cast shmmax and shmall fields to uintptr_t [BZ #26736]
H.J. Lu
hjl.tools@gmail.com
Thu Oct 15 16:56:17 GMT 2020
On Thu, Oct 15, 2020 at 8:17 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On x32, the shmctl (IPC_INFO) syscall returns the x86-64 values for
> shmmax and shmall. Since x32 is limited to 32-bit address space,
> shmmax and shmall should be casted to uintptr_t and shmmax should be
> clamped to INT_MAX only if the size of shmmax is the size of int.
> ---
> sysdeps/unix/sysv/linux/shmctl.c | 20 ++++++++++++++++----
> sysdeps/unix/sysv/linux/tst-sysvshm-linux.c | 3 ++-
> 2 files changed, 18 insertions(+), 5 deletions(-)
>
> diff --git a/sysdeps/unix/sysv/linux/shmctl.c b/sysdeps/unix/sysv/linux/shmctl.c
> index 833f013e69..8d34c0e7bf 100644
> --- a/sysdeps/unix/sysv/linux/shmctl.c
> +++ b/sysdeps/unix/sysv/linux/shmctl.c
> @@ -138,11 +138,11 @@ __shmctl64 (int shmid, int cmd, struct __shmid64_ds *buf)
>
> switch (cmd)
> {
> - case IPC_STAT:
> - case SHM_STAT:
> - case SHM_STAT_ANY:
> + case IPC_STAT:
> + case SHM_STAT:
> + case SHM_STAT_ANY:
> #ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
> - arg->shm_perm.mode >>= 16;
> + arg->shm_perm.mode >>= 16;
> #else
> /* Old Linux kernel versions might not clear the mode padding. */
> if (sizeof ((struct shmid_ds){0}.shm_perm.mode)
> @@ -153,6 +153,18 @@ __shmctl64 (int shmid, int cmd, struct __shmid64_ds *buf)
> #if __IPC_TIME64
> kshmid64_to_shmid64 (arg, buf);
> #endif
> + break;
> +
> + case IPC_INFO:
> + if (sizeof (((struct shminfo *) 0)->shmmax) > sizeof (uintptr_t))
> + {
> + /* Since the address space is limited by the size of uintptr_t,
> + cast shmmax and shmall to uintptr_t. */
> + struct shminfo *shminfo_p = (struct shminfo *) arg;
> + shminfo_p->shmmax = (uintptr_t) shminfo_p->shmmax;
> + shminfo_p->shmall = (uintptr_t) shminfo_p->shmall;
> + }
> + break;
> }
>
> return ret;
> diff --git a/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c b/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c
> index 7128ae2e14..abeeb37a78 100644
> --- a/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c
> +++ b/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c
> @@ -128,7 +128,8 @@ do_test (void)
> #if LONG_MAX == INT_MAX
> /* Kernel explicit clamp the value for shmmax on compat symbol (32-bit
> binaries running on 64-bit kernels). */
> - if (v > INT_MAX)
> + if (sizeof (((struct shminfo *) 0)->shmmax) == sizeof (int)
> + && v > INT_MAX)
> v = INT_MAX;
> #endif
> tipcinfo.shmmax = v;
> --
> 2.26.2
>
Tested with scripts/build-many-glibcs.py and on i686/x32/x86-64.
--
H.J.
More information about the Libc-alpha
mailing list