[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