]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/commitdiff
y2038: ipc: Report long times to user space
authorArnd Bergmann <arnd@arndb.de>
Tue, 28 Apr 2015 19:39:50 +0000 (21:39 +0200)
committerArnd Bergmann <arnd@arndb.de>
Fri, 20 Apr 2018 14:20:21 +0000 (16:20 +0200)
The shmid64_ds/semid64_ds/msqid64_ds data structures have been extended
to contain extra fields for storing the upper bits of the time stamps,
this patch does the other half of the job and and fills the new fields on
32-bit architectures as well as 32-bit tasks running on a 64-bit kernel
in compat mode.

There should be no change for native 64-bit tasks.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
ipc/msg.c
ipc/sem.c
ipc/shm.c

index 574f76c9a2fff167e50ddd4b5f9f0290ca24c634..3b654530259809d0241baa695136a59ad169fe4c 100644 (file)
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -537,6 +537,11 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid,
        p->msg_stime  = msq->q_stime;
        p->msg_rtime  = msq->q_rtime;
        p->msg_ctime  = msq->q_ctime;
+#ifndef CONFIG_64BIT
+       p->msg_stime_high = msq->q_stime >> 32;
+       p->msg_rtime_high = msq->q_rtime >> 32;
+       p->msg_ctime_high = msq->q_ctime >> 32;
+#endif
        p->msg_cbytes = msq->q_cbytes;
        p->msg_qnum   = msq->q_qnum;
        p->msg_qbytes = msq->q_qbytes;
@@ -646,9 +651,12 @@ static int copy_compat_msqid_to_user(void __user *buf, struct msqid64_ds *in,
                struct compat_msqid64_ds v;
                memset(&v, 0, sizeof(v));
                to_compat_ipc64_perm(&v.msg_perm, &in->msg_perm);
-               v.msg_stime = in->msg_stime;
-               v.msg_rtime = in->msg_rtime;
-               v.msg_ctime = in->msg_ctime;
+               v.msg_stime      = lower_32_bits(in->msg_stime);
+               v.msg_stime_high = upper_32_bits(in->msg_stime);
+               v.msg_rtime      = lower_32_bits(in->msg_rtime);
+               v.msg_rtime_high = upper_32_bits(in->msg_rtime);
+               v.msg_ctime      = lower_32_bits(in->msg_ctime);
+               v.msg_ctime_high = upper_32_bits(in->msg_ctime);
                v.msg_cbytes = in->msg_cbytes;
                v.msg_qnum = in->msg_qnum;
                v.msg_qbytes = in->msg_qbytes;
index c6a8a971769dafa4ff457393c72dca45e43c4579..8935cd8cf1668585a8c58a2d5a9dcdd2b3673c82 100644 (file)
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -1214,6 +1214,7 @@ static int semctl_stat(struct ipc_namespace *ns, int semid,
                         int cmd, struct semid64_ds *semid64)
 {
        struct sem_array *sma;
+       time64_t semotime;
        int id = 0;
        int err;
 
@@ -1257,8 +1258,13 @@ static int semctl_stat(struct ipc_namespace *ns, int semid,
        }
 
        kernel_to_ipc64_perm(&sma->sem_perm, &semid64->sem_perm);
-       semid64->sem_otime = get_semotime(sma);
+       semotime = get_semotime(sma);
+       semid64->sem_otime = semotime;
        semid64->sem_ctime = sma->sem_ctime;
+#ifndef CONFIG_64BIT
+       semid64->sem_otime_high = semotime >> 32;
+       semid64->sem_ctime_high = sma->sem_ctime >> 32;
+#endif
        semid64->sem_nsems = sma->sem_nsems;
 
        ipc_unlock_object(&sma->sem_perm);
@@ -1704,8 +1710,10 @@ static int copy_compat_semid_to_user(void __user *buf, struct semid64_ds *in,
                struct compat_semid64_ds v;
                memset(&v, 0, sizeof(v));
                to_compat_ipc64_perm(&v.sem_perm, &in->sem_perm);
-               v.sem_otime = in->sem_otime;
-               v.sem_ctime = in->sem_ctime;
+               v.sem_otime      = lower_32_bits(in->sem_otime);
+               v.sem_otime_high = upper_32_bits(in->sem_otime);
+               v.sem_ctime      = lower_32_bits(in->sem_ctime);
+               v.sem_ctime_high = upper_32_bits(in->sem_ctime);
                v.sem_nsems = in->sem_nsems;
                return copy_to_user(buf, &v, sizeof(v));
        } else {
index 3cf48988d68cec1e3a899f932de846818d4c729a..0075990338f40735e51045c45a00dd580b6bed59 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -1002,6 +1002,11 @@ static int shmctl_stat(struct ipc_namespace *ns, int shmid,
        tbuf->shm_atime = shp->shm_atim;
        tbuf->shm_dtime = shp->shm_dtim;
        tbuf->shm_ctime = shp->shm_ctim;
+#ifndef CONFIG_64BIT
+       tbuf->shm_atime_high = shp->shm_atim >> 32;
+       tbuf->shm_dtime_high = shp->shm_dtim >> 32;
+       tbuf->shm_ctime_high = shp->shm_ctim >> 32;
+#endif
        tbuf->shm_cpid  = pid_vnr(shp->shm_cprid);
        tbuf->shm_lpid  = pid_vnr(shp->shm_lprid);
        tbuf->shm_nattch = shp->shm_nattch;
@@ -1233,9 +1238,12 @@ static int copy_compat_shmid_to_user(void __user *buf, struct shmid64_ds *in,
                struct compat_shmid64_ds v;
                memset(&v, 0, sizeof(v));
                to_compat_ipc64_perm(&v.shm_perm, &in->shm_perm);
-               v.shm_atime = in->shm_atime;
-               v.shm_dtime = in->shm_dtime;
-               v.shm_ctime = in->shm_ctime;
+               v.shm_atime      = lower_32_bits(in->shm_atime);
+               v.shm_atime_high = upper_32_bits(in->shm_atime);
+               v.shm_dtime      = lower_32_bits(in->shm_dtime);
+               v.shm_dtime_high = upper_32_bits(in->shm_dtime);
+               v.shm_ctime      = lower_32_bits(in->shm_ctime);
+               v.shm_ctime_high = upper_32_bits(in->shm_ctime);
                v.shm_segsz = in->shm_segsz;
                v.shm_nattch = in->shm_nattch;
                v.shm_cpid = in->shm_cpid;