Message ID | 20201015151756.514621-1-hjl.tools@gmail.com |
---|---|
State | Dropped |
Headers |
Return-Path: <libc-alpha-bounces@sourceware.org> X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 070673950C33; Thu, 15 Oct 2020 15:18:03 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 070673950C33 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1602775083; bh=gjJRvPJBiryIksVwfweWE1HpMc1QAHOsyfqu6skkVYE=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=PPgwP6BkUjFnsR+nmXvIwF8Q/ySq/u6kW4E49y1jX1bL8i51/PIo2tkFyxbs0RLlO 5rxS2pL99AZsU3uGZlPU/qxkSPfOYI9fW0e3nyIQjqtDAUQhPGt0lOQqr7AAnJ+YeO sAvUlC9hLKoOMMFlL619ezaGl9ljITOhXpZu4rLU= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pl1-x644.google.com (mail-pl1-x644.google.com [IPv6:2607:f8b0:4864:20::644]) by sourceware.org (Postfix) with ESMTPS id A823E3857809 for <libc-alpha@sourceware.org>; Thu, 15 Oct 2020 15:17:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org A823E3857809 Received: by mail-pl1-x644.google.com with SMTP id b19so1807048pld.0 for <libc-alpha@sourceware.org>; Thu, 15 Oct 2020 08:17:59 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=gjJRvPJBiryIksVwfweWE1HpMc1QAHOsyfqu6skkVYE=; b=nzA/AQrLFmSUDqqoJ3jBttIArjSseFdo/mr1EENEo5BYhsBiVr+x0Pfrcu6ue44eJ5 j6qAT7r1S2zapNDpXq+p1BggCBo40WK9IFhww4wTZm8U0Ui37hpZxdhNugShVuPMu60A hVHeke+8WdaX+y7AI6wCLStSMxBjcDvKS8IWvWMd69IUx8ydLehx8doBiCr6yoEcJ1f6 5mTc9AGm6HBBZLYA+g18GsYdraKXBH2ujR72sLZ6RvNu9zHatxE1JAUf/hi61LqaNfrh Fs8TXRB9D3AtdE5x1NxLLnlvMFx3zmTaMkQjKNnyKMjhAsuJfqy3ZOpKkbOxX6AD7KwV Ihpg== X-Gm-Message-State: AOAM530HbBD9ZNL8Q4RXsrYFs9h/PGC/swXfRnEG78NzvYIBGwV9UTVg EiWK/eSxgqF/yHS3E3QyojmiupSRB3c= X-Google-Smtp-Source: ABdhPJw7mvLcgG4CuJWIp0UjuYzX6FfKH75vAB43CyeAGSGserFrrr7lN8ddoJrGlPN0M9QQ3tdsnQ== X-Received: by 2002:a17:902:8a8a:b029:d5:aba7:5abb with SMTP id p10-20020a1709028a8ab02900d5aba75abbmr4211740plo.50.1602775078456; Thu, 15 Oct 2020 08:17:58 -0700 (PDT) Received: from gnu-cfl-2.localdomain (c-69-181-90-243.hsd1.ca.comcast.net. [69.181.90.243]) by smtp.gmail.com with ESMTPSA id t2sm3686676pji.12.2020.10.15.08.17.57 for <libc-alpha@sourceware.org> (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 Oct 2020 08:17:57 -0700 (PDT) Received: from gnu-cfl-2.localdomain (localhost [IPv6:::1]) by gnu-cfl-2.localdomain (Postfix) with ESMTP id 65FC61A0106 for <libc-alpha@sourceware.org>; Thu, 15 Oct 2020 08:17:56 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH] IPC_INFO: Cast shmmax and shmall fields to uintptr_t [BZ #26736] Date: Thu, 15 Oct 2020 08:17:56 -0700 Message-Id: <20201015151756.514621-1-hjl.tools@gmail.com> X-Mailer: git-send-email 2.26.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-3041.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list <libc-alpha.sourceware.org> List-Unsubscribe: <https://sourceware.org/mailman/options/libc-alpha>, <mailto:libc-alpha-request@sourceware.org?subject=unsubscribe> List-Archive: <https://sourceware.org/pipermail/libc-alpha/> List-Post: <mailto:libc-alpha@sourceware.org> List-Help: <mailto:libc-alpha-request@sourceware.org?subject=help> List-Subscribe: <https://sourceware.org/mailman/listinfo/libc-alpha>, <mailto:libc-alpha-request@sourceware.org?subject=subscribe> From: "H.J. Lu via Libc-alpha" <libc-alpha@sourceware.org> Reply-To: "H.J. Lu" <hjl.tools@gmail.com> Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" <libc-alpha-bounces@sourceware.org> |
Series |
IPC_INFO: Cast shmmax and shmall fields to uintptr_t [BZ #26736]
|
|
Commit Message
H.J. Lu
Oct. 15, 2020, 3:17 p.m. UTC
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(-)
Comments
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.
On 15/10/2020 12:17, H.J. Lu via Libc-alpha 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; > This is semantic change of shmctl for x32, which I really do not oppose but I think we should rely on kernel to clamp the value correctly for x32 (the shmctl is already rather complex to handle y2038 safeness). What about changing the testcase to use the expected types for shminfo fields (__syscall_ulong_t instead of unsigned long int) and check for the expected provided kernel value: --- diff --git a/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c b/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c index 7128ae2e14..cb32bd522e 100644 --- a/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c +++ b/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c @@ -54,9 +54,9 @@ do_prepare (int argc, char *argv[]) struct test_shminfo { - unsigned long int shmall; - unsigned long int shmmax; - unsigned long int shmmni; + __syscall_ulong_t shmall; + __syscall_ulong_t shmmax; + __syscall_ulong_t shmmni; }; /* It tries to obtain some system-wide SysV shared memory information from @@ -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 (__syscall_ulong_t) == sizeof (unsigned long int) + && v > INT_MAX) v = INT_MAX; #endif tipcinfo.shmmax = v;
* H. J. Lu via Libc-alpha: > 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 > + case IPC_INFO: > + if (sizeof (((struct shminfo *) 0)->shmmax) > sizeof (uintptr_t)) I think the C way of writing this is: sizeof ((struct shminfo) { 0 }.shmmax) I believe a null pointer deference is still undefined in an unevaluated sizeof context. > 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) Likewise.
On Thu, Oct 15, 2020 at 10:24 AM Adhemerval Zanella via Libc-alpha <libc-alpha@sourceware.org> wrote: > > > > On 15/10/2020 12:17, H.J. Lu via Libc-alpha 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; > > > > This is semantic change of shmctl for x32, which I really do not oppose > but I think we should rely on kernel to clamp the value correctly for x32 > (the shmctl is already rather complex to handle y2038 safeness). > > What about changing the testcase to use the expected types for shminfo > fields (__syscall_ulong_t instead of unsigned long int) and check for > the expected provided kernel value: > > --- > > diff --git a/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c b/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c > index 7128ae2e14..cb32bd522e 100644 > --- a/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c > +++ b/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c > @@ -54,9 +54,9 @@ do_prepare (int argc, char *argv[]) > > struct test_shminfo > { > - unsigned long int shmall; > - unsigned long int shmmax; > - unsigned long int shmmni; > + __syscall_ulong_t shmall; > + __syscall_ulong_t shmmax; > + __syscall_ulong_t shmmni; > }; > > /* It tries to obtain some system-wide SysV shared memory information from > @@ -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 (__syscall_ulong_t) == sizeof (unsigned long int) > + && v > INT_MAX) > v = INT_MAX; > #endif > tipcinfo.shmmax = v; This works. Can you check it in? Thanks.
On 15/10/2020 14:40, H.J. Lu wrote: > On Thu, Oct 15, 2020 at 10:24 AM Adhemerval Zanella via Libc-alpha > <libc-alpha@sourceware.org> wrote: >> >> >> >> On 15/10/2020 12:17, H.J. Lu via Libc-alpha 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; >>> >> >> This is semantic change of shmctl for x32, which I really do not oppose >> but I think we should rely on kernel to clamp the value correctly for x32 >> (the shmctl is already rather complex to handle y2038 safeness). >> >> What about changing the testcase to use the expected types for shminfo >> fields (__syscall_ulong_t instead of unsigned long int) and check for >> the expected provided kernel value: >> >> --- >> >> diff --git a/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c b/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c >> index 7128ae2e14..cb32bd522e 100644 >> --- a/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c >> +++ b/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c >> @@ -54,9 +54,9 @@ do_prepare (int argc, char *argv[]) >> >> struct test_shminfo >> { >> - unsigned long int shmall; >> - unsigned long int shmmax; >> - unsigned long int shmmni; >> + __syscall_ulong_t shmall; >> + __syscall_ulong_t shmmax; >> + __syscall_ulong_t shmmni; >> }; >> >> /* It tries to obtain some system-wide SysV shared memory information from >> @@ -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 (__syscall_ulong_t) == sizeof (unsigned long int) >> + && v > INT_MAX) >> v = INT_MAX; >> #endif >> tipcinfo.shmmax = v; > > This works. Can you check it in? I will do it.
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;