ipc: sem: Make sem_array timestamps y2038 safe

time_t is not y2038 safe. Replace all uses of
time_t by y2038 safe time64_t.

Similarly, replace the calls to get_seconds() with
y2038 safe ktime_get_real_seconds().
Note that this preserves fast access on 64 bit systems,
but 32 bit systems need sequence counters.

The syscall interface themselves are not changed as part of
the patch. They will be part of a different series.

Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

authored by

Deepa Dinamani and committed by
Al Viro
e54d02b2 50578ea9

+11 -10
+2 -1
include/linux/sem.h
··· 4 #include <linux/atomic.h> 5 #include <linux/rcupdate.h> 6 #include <linux/cache.h> 7 #include <uapi/linux/sem.h> 8 9 struct task_struct; ··· 31 /* One sem_array data structure for each set of semaphores in the system. */ 32 struct sem_array { 33 struct kern_ipc_perm sem_perm; /* permissions .. see ipc.h */ 34 - time_t sem_ctime; /* create/last semctl() time */ 35 struct list_head pending_alter; /* pending operations */ 36 /* that alter the array */ 37 struct list_head pending_const; /* pending complex operations */
··· 4 #include <linux/atomic.h> 5 #include <linux/rcupdate.h> 6 #include <linux/cache.h> 7 + #include <linux/time64.h> 8 #include <uapi/linux/sem.h> 9 10 struct task_struct; ··· 30 /* One sem_array data structure for each set of semaphores in the system. */ 31 struct sem_array { 32 struct kern_ipc_perm sem_perm; /* permissions .. see ipc.h */ 33 + time64_t sem_ctime; /* create/last semctl() time */ 34 struct list_head pending_alter; /* pending operations */ 35 /* that alter the array */ 36 struct list_head pending_const; /* pending complex operations */
+9 -9
ipc/sem.c
··· 511 INIT_LIST_HEAD(&sma->pending_const); 512 INIT_LIST_HEAD(&sma->list_id); 513 sma->sem_nsems = nsems; 514 - sma->sem_ctime = get_seconds(); 515 516 retval = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni); 517 if (retval < 0) { ··· 1162 } 1163 } 1164 1165 - static time_t get_semotime(struct sem_array *sma) 1166 { 1167 int i; 1168 - time_t res; 1169 1170 res = sma->sems[0].sem_otime; 1171 for (i = 1; i < sma->sem_nsems; i++) { 1172 - time_t to = sma->sems[i].sem_otime; 1173 1174 if (to > res) 1175 res = to; ··· 1309 1310 curr->semval = val; 1311 curr->sempid = task_tgid_vnr(current); 1312 - sma->sem_ctime = get_seconds(); 1313 /* maybe some queued-up processes were waiting for this */ 1314 do_smart_update(sma, NULL, 0, 0, &wake_q); 1315 sem_unlock(sma, -1); ··· 1437 for (i = 0; i < nsems; i++) 1438 un->semadj[i] = 0; 1439 } 1440 - sma->sem_ctime = get_seconds(); 1441 /* maybe some queued-up processes were waiting for this */ 1442 do_smart_update(sma, NULL, 0, 0, &wake_q); 1443 err = 0; ··· 1547 err = ipc_update_perm(&semid64->sem_perm, ipcp); 1548 if (err) 1549 goto out_unlock0; 1550 - sma->sem_ctime = get_seconds(); 1551 break; 1552 default: 1553 err = -EINVAL; ··· 2292 { 2293 struct user_namespace *user_ns = seq_user_ns(s); 2294 struct sem_array *sma = it; 2295 - time_t sem_otime; 2296 2297 /* 2298 * The proc interface isn't aware of sem_lock(), it calls ··· 2305 sem_otime = get_semotime(sma); 2306 2307 seq_printf(s, 2308 - "%10d %10d %4o %10u %5u %5u %5u %5u %10lu %10lu\n", 2309 sma->sem_perm.key, 2310 sma->sem_perm.id, 2311 sma->sem_perm.mode,
··· 511 INIT_LIST_HEAD(&sma->pending_const); 512 INIT_LIST_HEAD(&sma->list_id); 513 sma->sem_nsems = nsems; 514 + sma->sem_ctime = ktime_get_real_seconds(); 515 516 retval = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni); 517 if (retval < 0) { ··· 1162 } 1163 } 1164 1165 + static time64_t get_semotime(struct sem_array *sma) 1166 { 1167 int i; 1168 + time64_t res; 1169 1170 res = sma->sems[0].sem_otime; 1171 for (i = 1; i < sma->sem_nsems; i++) { 1172 + time64_t to = sma->sems[i].sem_otime; 1173 1174 if (to > res) 1175 res = to; ··· 1309 1310 curr->semval = val; 1311 curr->sempid = task_tgid_vnr(current); 1312 + sma->sem_ctime = ktime_get_real_seconds(); 1313 /* maybe some queued-up processes were waiting for this */ 1314 do_smart_update(sma, NULL, 0, 0, &wake_q); 1315 sem_unlock(sma, -1); ··· 1437 for (i = 0; i < nsems; i++) 1438 un->semadj[i] = 0; 1439 } 1440 + sma->sem_ctime = ktime_get_real_seconds(); 1441 /* maybe some queued-up processes were waiting for this */ 1442 do_smart_update(sma, NULL, 0, 0, &wake_q); 1443 err = 0; ··· 1547 err = ipc_update_perm(&semid64->sem_perm, ipcp); 1548 if (err) 1549 goto out_unlock0; 1550 + sma->sem_ctime = ktime_get_real_seconds(); 1551 break; 1552 default: 1553 err = -EINVAL; ··· 2292 { 2293 struct user_namespace *user_ns = seq_user_ns(s); 2294 struct sem_array *sma = it; 2295 + time64_t sem_otime; 2296 2297 /* 2298 * The proc interface isn't aware of sem_lock(), it calls ··· 2305 sem_otime = get_semotime(sma); 2306 2307 seq_printf(s, 2308 + "%10d %10d %4o %10u %5u %5u %5u %5u %10llu %10llu\n", 2309 sma->sem_perm.key, 2310 sma->sem_perm.id, 2311 sma->sem_perm.mode,