]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
sysvipc: Fix UB on time64 time support
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Fri, 25 Apr 2025 13:57:32 +0000 (13:57 +0000)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Thu, 8 May 2025 12:25:49 +0000 (09:25 -0300)
Building with ubsan on 32 bit architecture without 64 bit time_t
as default, it shows:

UBSAN: Undefined behaviour in ../sysdeps/unix/sysv/linux/msgctl.c:180:45 left shift of 3935167480 by 32 cannot be represented in type 'long long int'

Add a new macro, IPC_HILO, to handle this transparently by using
unsigned shifts.

sysdeps/unix/sysv/linux/hppa/struct_kernel_shmid64_ds.h
sysdeps/unix/sysv/linux/i386/struct_kernel_shmid64_ds.h
sysdeps/unix/sysv/linux/ipc_priv.h
sysdeps/unix/sysv/linux/mips/struct_kernel_shmid64_ds.h
sysdeps/unix/sysv/linux/msgctl.c
sysdeps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h
sysdeps/unix/sysv/linux/semctl.c
sysdeps/unix/sysv/linux/shmctl.c
sysdeps/unix/sysv/linux/sparc/struct_kernel_shmid64_ds.h
sysdeps/unix/sysv/linux/struct_kernel_shmid64_ds.h

index 4d09fc7f623a25f762f0d1dae7bff011b9991d89..c43b1e046203b47d3186daf20239b99d7aafac63 100644 (file)
@@ -2,11 +2,11 @@
 struct kernel_shmid64_ds
 {
   struct ipc_perm shm_perm;            /* operation permission struct */
-  unsigned long int shm_atime_high;
+  unsigned long int __shm_atime_high;
   unsigned long int shm_atime;         /* time of last shmat() */
-  unsigned long int shm_dtime_high;
+  unsigned long int __shm_dtime_high;
   unsigned long int shm_dtime;         /* time of last shmdt() */
-  unsigned long int shm_ctime_high;
+  unsigned long int __shm_ctime_high;
   unsigned long int shm_ctime;         /* time of last change by shmctl() */
   unsigned long int __pad;
   size_t shm_segsz;                    /* size of segment in bytes */
index 6a0a0d9c71bcc79c0604500e92d7bb03977b90b5..80b5f24005d6a735541db528f5f57026a9b1fd2f 100644 (file)
@@ -4,11 +4,11 @@ struct kernel_shmid64_ds
   struct ipc_perm shm_perm;
   size_t shm_segsz;
   unsigned long int shm_atime;
-  unsigned long int shm_atime_high;
+  unsigned long int __shm_atime_high;
   unsigned long int shm_dtime;
-  unsigned long int shm_dtime_high;
+  unsigned long int __shm_dtime_high;
   unsigned long int shm_ctime;
-  unsigned long int shm_ctime_high;
+  unsigned long int __shm_ctime_high;
   __pid_t shm_cpid;
   __pid_t shm_lpid;
   unsigned long int shm_nattch;
index 6ace4b764d16c1aada54575743946f9399e8fe1e..8c27b744d7637f4485c081ac13669120aa29aefe 100644 (file)
@@ -59,6 +59,9 @@ struct __old_ipc_perm
 #if (__WORDSIZE == 32 \
      && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32))
 # define __IPC_TIME64 1
+/* Left-shift using unsigned int, since __time64_t is signed.  */
+# define IPC_HILO(__buf, __member) \
+  ((__buf)->__member | (0ULL + (__buf)->__##__member##_high) << 32)
 #else
 # define __IPC_TIME64 0
 #endif
index a4baa5614f435379f5b5f0bbe1408ab0b9b36a27..f79f1469bec3d0499c9fd6121a2c22cc51b0125f 100644 (file)
@@ -19,9 +19,9 @@ struct kernel_shmid64_ds
   unsigned long int __unused1;
   unsigned long int __unused2;
 #else
-  unsigned short int shm_atime_high;
-  unsigned short int shm_dtime_high;
-  unsigned short int shm_ctime_high;
+  unsigned short int __shm_atime_high;
+  unsigned short int __shm_dtime_high;
+  unsigned short int __shm_ctime_high;
   unsigned short int __ununsed1;
 #endif
 };
index ee794c34234043b5507e8029dc3e2633628705fc..d83a5c270d1c7d47fb478a9f963867a3cbe9e23e 100644 (file)
@@ -172,12 +172,9 @@ static void
 msqid_to_msqid64 (struct __msqid64_ds *mq64, const struct msqid_ds *mq)
 {
   mq64->msg_perm   = mq->msg_perm;
-  mq64->msg_stime  = mq->msg_stime
-                    | ((__time64_t) mq->__msg_stime_high << 32);
-  mq64->msg_rtime  = mq->msg_rtime
-                    | ((__time64_t) mq->__msg_rtime_high << 32);
-  mq64->msg_ctime  = mq->msg_ctime
-                    | ((__time64_t) mq->__msg_ctime_high << 32);
+  mq64->msg_stime  = IPC_HILO (mq, msg_stime);
+  mq64->msg_rtime  = IPC_HILO (mq, msg_rtime);
+  mq64->msg_ctime  = IPC_HILO (mq, msg_ctime);
   mq64->msg_cbytes = mq->msg_cbytes;
   mq64->msg_qnum   = mq->msg_qnum;
   mq64->msg_qbytes = mq->msg_qbytes;
index ae3f3987ac1e82dba285ab6970ea19452d45825d..c6946312ba0c9e040eb12adf8f24d16b3c049d5b 100644 (file)
@@ -2,11 +2,11 @@
 struct kernel_shmid64_ds
 {
   struct ipc_perm shm_perm;
-  unsigned long int shm_atime_high;
+  unsigned long int __shm_atime_high;
   unsigned long int shm_atime;
-  unsigned long int shm_dtime_high;
+  unsigned long int __shm_dtime_high;
   unsigned long int shm_dtime;
-  unsigned long int shm_ctime_high;
+  unsigned long int __shm_ctime_high;
   unsigned long int shm_ctime;
   unsigned long int __ununsed1;
   size_t shm_segsz;
index feaf3fcdb10850742e0ea0388b2cbd267fbdc4a3..0450138b96f2bbfae1ccbcaab981482184289768 100644 (file)
@@ -222,10 +222,8 @@ static void
 semid_to_semid64 (struct __semid64_ds *ds64, const struct semid_ds *ds)
 {
   ds64->sem_perm  = ds->sem_perm;
-  ds64->sem_otime = ds->sem_otime
-                   | ((__time64_t) ds->__sem_otime_high << 32);
-  ds64->sem_ctime = ds->sem_ctime
-                   | ((__time64_t) ds->__sem_ctime_high << 32);
+  ds64->sem_otime = IPC_HILO (ds, sem_otime);
+  ds64->sem_ctime = IPC_HILO (ds, sem_ctime);
   ds64->sem_nsems = ds->sem_nsems;
 }
 
index 2e8faaf03b2e477d85c35e9ef7e1ee56d05a4ba4..089a6727ca8c850cd1f3f3d1c34ac6f5b51f5a35 100644 (file)
@@ -40,11 +40,11 @@ shmid64_to_kshmid64 (const struct __shmid64_ds *shmid64,
   kshmid->shm_perm       = shmid64->shm_perm;
   kshmid->shm_segsz      = shmid64->shm_segsz;
   kshmid->shm_atime      = shmid64->shm_atime;
-  kshmid->shm_atime_high = shmid64->shm_atime >> 32;
+  kshmid->__shm_atime_high = shmid64->shm_atime >> 32;
   kshmid->shm_dtime      = shmid64->shm_dtime;
-  kshmid->shm_dtime_high = shmid64->shm_dtime >> 32;
+  kshmid->__shm_dtime_high = shmid64->shm_dtime >> 32;
   kshmid->shm_ctime      = shmid64->shm_ctime;
-  kshmid->shm_ctime_high = shmid64->shm_ctime >> 32;
+  kshmid->__shm_ctime_high = shmid64->shm_ctime >> 32;
   kshmid->shm_cpid       = shmid64->shm_cpid;
   kshmid->shm_lpid       = shmid64->shm_lpid;
   kshmid->shm_nattch     = shmid64->shm_nattch;
@@ -56,12 +56,9 @@ kshmid64_to_shmid64 (const struct kernel_shmid64_ds *kshmid,
 {
   shmid64->shm_perm   = kshmid->shm_perm;
   shmid64->shm_segsz  = kshmid->shm_segsz;
-  shmid64->shm_atime  = kshmid->shm_atime
-                       | ((__time64_t) kshmid->shm_atime_high << 32);
-  shmid64->shm_dtime  = kshmid->shm_dtime
-                       | ((__time64_t) kshmid->shm_dtime_high << 32);
-  shmid64->shm_ctime  = kshmid->shm_ctime
-                       | ((__time64_t) kshmid->shm_ctime_high << 32);
+  shmid64->shm_atime  = IPC_HILO (kshmid, shm_atime);
+  shmid64->shm_dtime  = IPC_HILO (kshmid, shm_dtime);
+  shmid64->shm_ctime  = IPC_HILO (kshmid, shm_ctime);
   shmid64->shm_cpid   = kshmid->shm_cpid;
   shmid64->shm_lpid   = kshmid->shm_lpid;
   shmid64->shm_nattch = kshmid->shm_nattch;
@@ -176,12 +173,9 @@ shmid_to_shmid64 (struct __shmid64_ds *shm64, const struct shmid_ds *shm)
 {
   shm64->shm_perm   = shm->shm_perm;
   shm64->shm_segsz  = shm->shm_segsz;
-  shm64->shm_atime  = shm->shm_atime
-                     | ((__time64_t) shm->__shm_atime_high << 32);
-  shm64->shm_dtime  = shm->shm_dtime
-                     | ((__time64_t) shm->__shm_dtime_high << 32);
-  shm64->shm_ctime  = shm->shm_ctime
-                     | ((__time64_t) shm->__shm_ctime_high << 32);
+  shm64->shm_atime  = IPC_HILO (shm, shm_atime);
+  shm64->shm_dtime  = IPC_HILO (shm, shm_dtime);
+  shm64->shm_ctime  = IPC_HILO (shm, shm_ctime);
   shm64->shm_cpid   = shm->shm_cpid;
   shm64->shm_lpid   = shm->shm_lpid;
   shm64->shm_nattch = shm->shm_nattch;
index 333a410641432259a6f4e9fcb7c113460b2bbf0a..9029f8639b10e473257bd279782e8da6c38731fd 100644 (file)
@@ -2,11 +2,11 @@
 struct kernel_shmid64_ds
 {
   struct ipc_perm shm_perm;
-  unsigned long int shm_atime_high;
+  unsigned long int __shm_atime_high;
   unsigned long int shm_atime;
-  unsigned long int shm_dtime_high;
+  unsigned long int __shm_dtime_high;
   unsigned long int shm_dtime;
-  unsigned long int shm_ctime_high;
+  unsigned long int __shm_ctime_high;
   unsigned long int shm_ctime;
   size_t shm_segsz;
   __pid_t shm_cpid;
index 6fe67afccbc2c8ca06e8472740a3cb3bf99d38a4..b4dbea030a6612d6f5928da0ff573f15431412e4 100644 (file)
@@ -4,11 +4,11 @@ struct kernel_shmid64_ds
   struct ipc_perm shm_perm;
   size_t shm_segsz;
   unsigned long int shm_atime;
-  unsigned long int shm_atime_high;
+  unsigned long int __shm_atime_high;
   unsigned long int shm_dtime;
-  unsigned long int shm_dtime_high;
+  unsigned long int __shm_dtime_high;
   unsigned long int shm_ctime;
-  unsigned long int shm_ctime_high;
+  unsigned long int __shm_ctime_high;
   __pid_t shm_cpid;
   __pid_t shm_lpid;
   unsigned long int shm_nattch;