Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

compat: generic compat get/settimeofday

Nothing arch specific in get/settimeofday. The details of the timeval
conversion varied a little from arch to arch, but all with the same
results.

Also add an extern declaration for sys_tz to linux/time.h because externs
in .c files are fowned upon. I'll kill the externs in various other files
in a sparate patch.

[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: David S. Miller <davem@davemloft.net> [ sparc bits ]
Cc: "Luck, Tony" <tony.luck@intel.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Acked-by: Kyle McMartin <kyle@mcmartin.ca>
Cc: Matthew Wilcox <matthew@wil.cx>
Cc: Grant Grundler <grundler@parisc-linux.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Christoph Hellwig and committed by
Linus Torvalds
b418da16 f7a5000f

+85 -460
+2 -2
arch/ia64/ia32/ia32_entry.S
··· 251 251 data8 compat_sys_setrlimit /* 75 */ 252 252 data8 compat_sys_old_getrlimit 253 253 data8 compat_sys_getrusage 254 - data8 sys32_gettimeofday 255 - data8 sys32_settimeofday 254 + data8 compat_sys_gettimeofday 255 + data8 compat_sys_settimeofday 256 256 data8 sys32_getgroups16 /* 80 */ 257 257 data8 sys32_setgroups16 258 258 data8 sys32_old_select
-56
arch/ia64/ia32/sys_ia32.c
··· 1113 1113 return retval; 1114 1114 } 1115 1115 1116 - static inline long 1117 - get_tv32 (struct timeval *o, struct compat_timeval __user *i) 1118 - { 1119 - return (!access_ok(VERIFY_READ, i, sizeof(*i)) || 1120 - (__get_user(o->tv_sec, &i->tv_sec) | __get_user(o->tv_usec, &i->tv_usec))); 1121 - } 1122 - 1123 - static inline long 1124 - put_tv32 (struct compat_timeval __user *o, struct timeval *i) 1125 - { 1126 - return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || 1127 - (__put_user(i->tv_sec, &o->tv_sec) | __put_user(i->tv_usec, &o->tv_usec))); 1128 - } 1129 - 1130 1116 asmlinkage unsigned long 1131 1117 sys32_alarm (unsigned int seconds) 1132 1118 { 1133 1119 return alarm_setitimer(seconds); 1134 - } 1135 - 1136 - /* Translations due to time_t size differences. Which affects all 1137 - sorts of things, like timeval and itimerval. */ 1138 - 1139 - extern struct timezone sys_tz; 1140 - 1141 - asmlinkage long 1142 - sys32_gettimeofday (struct compat_timeval __user *tv, struct timezone __user *tz) 1143 - { 1144 - if (tv) { 1145 - struct timeval ktv; 1146 - do_gettimeofday(&ktv); 1147 - if (put_tv32(tv, &ktv)) 1148 - return -EFAULT; 1149 - } 1150 - if (tz) { 1151 - if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) 1152 - return -EFAULT; 1153 - } 1154 - return 0; 1155 - } 1156 - 1157 - asmlinkage long 1158 - sys32_settimeofday (struct compat_timeval __user *tv, struct timezone __user *tz) 1159 - { 1160 - struct timeval ktv; 1161 - struct timespec kts; 1162 - struct timezone ktz; 1163 - 1164 - if (tv) { 1165 - if (get_tv32(&ktv, tv)) 1166 - return -EFAULT; 1167 - kts.tv_sec = ktv.tv_sec; 1168 - kts.tv_nsec = ktv.tv_usec * 1000; 1169 - } 1170 - if (tz) { 1171 - if (copy_from_user(&ktz, tz, sizeof(ktz))) 1172 - return -EFAULT; 1173 - } 1174 - 1175 - return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); 1176 1120 } 1177 1121 1178 1122 struct sel_arg_struct {
-66
arch/mips/kernel/linux32.c
··· 133 133 return sys_ftruncate(fd, merge_64(a2, a3)); 134 134 } 135 135 136 - static inline long 137 - get_tv32(struct timeval *o, struct compat_timeval __user *i) 138 - { 139 - return (!access_ok(VERIFY_READ, i, sizeof(*i)) || 140 - (__get_user(o->tv_sec, &i->tv_sec) | 141 - __get_user(o->tv_usec, &i->tv_usec))); 142 - } 143 - 144 - static inline long 145 - put_tv32(struct compat_timeval __user *o, struct timeval *i) 146 - { 147 - return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || 148 - (__put_user(i->tv_sec, &o->tv_sec) | 149 - __put_user(i->tv_usec, &o->tv_usec))); 150 - } 151 - 152 - extern struct timezone sys_tz; 153 - 154 - asmlinkage int 155 - sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) 156 - { 157 - if (tv) { 158 - struct timeval ktv; 159 - do_gettimeofday(&ktv); 160 - if (put_tv32(tv, &ktv)) 161 - return -EFAULT; 162 - } 163 - if (tz) { 164 - if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) 165 - return -EFAULT; 166 - } 167 - return 0; 168 - } 169 - 170 - static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i) 171 - { 172 - long usec; 173 - 174 - if (!access_ok(VERIFY_READ, i, sizeof(*i))) 175 - return -EFAULT; 176 - if (__get_user(o->tv_sec, &i->tv_sec)) 177 - return -EFAULT; 178 - if (__get_user(usec, &i->tv_usec)) 179 - return -EFAULT; 180 - o->tv_nsec = usec * 1000; 181 - return 0; 182 - } 183 - 184 - asmlinkage int 185 - sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) 186 - { 187 - struct timespec kts; 188 - struct timezone ktz; 189 - 190 - if (tv) { 191 - if (get_ts32(&kts, tv)) 192 - return -EFAULT; 193 - } 194 - if (tz) { 195 - if (copy_from_user(&ktz, tz, sizeof(ktz))) 196 - return -EFAULT; 197 - } 198 - 199 - return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); 200 - } 201 - 202 136 asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high, 203 137 unsigned int offset_low, loff_t __user * result, 204 138 unsigned int origin)
+2 -2
arch/mips/kernel/scall64-n32.S
··· 214 214 PTR sys_fchown 215 215 PTR sys_lchown 216 216 PTR sys_umask 217 - PTR sys32_gettimeofday 217 + PTR compat_sys_gettimeofday 218 218 PTR compat_sys_getrlimit /* 6095 */ 219 219 PTR compat_sys_getrusage 220 220 PTR compat_sys_sysinfo ··· 279 279 PTR sys_chroot 280 280 PTR sys_sync 281 281 PTR sys_acct 282 - PTR sys32_settimeofday 282 + PTR compat_sys_settimeofday 283 283 PTR compat_sys_mount /* 6160 */ 284 284 PTR sys_umount 285 285 PTR sys_swapon
+2 -2
arch/mips/kernel/scall64-o32.S
··· 283 283 PTR compat_sys_setrlimit /* 4075 */ 284 284 PTR compat_sys_getrlimit 285 285 PTR compat_sys_getrusage 286 - PTR sys32_gettimeofday 287 - PTR sys32_settimeofday 286 + PTR compat_sys_gettimeofday 287 + PTR compat_sys_settimeofday 288 288 PTR sys_getgroups /* 4080 */ 289 289 PTR sys_setgroups 290 290 PTR sys_ni_syscall /* old_select */
-58
arch/parisc/kernel/sys_parisc32.c
··· 179 179 return ret; 180 180 } 181 181 182 - static int 183 - put_compat_timeval(struct compat_timeval __user *u, struct timeval *t) 184 - { 185 - struct compat_timeval t32; 186 - t32.tv_sec = t->tv_sec; 187 - t32.tv_usec = t->tv_usec; 188 - return copy_to_user(u, &t32, sizeof t32); 189 - } 190 - 191 - static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i) 192 - { 193 - long usec; 194 - 195 - if (__get_user(o->tv_sec, &i->tv_sec)) 196 - return -EFAULT; 197 - if (__get_user(usec, &i->tv_usec)) 198 - return -EFAULT; 199 - o->tv_nsec = usec * 1000; 200 - return 0; 201 - } 202 - 203 - asmlinkage int 204 - sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) 205 - { 206 - extern void do_gettimeofday(struct timeval *tv); 207 - 208 - if (tv) { 209 - struct timeval ktv; 210 - do_gettimeofday(&ktv); 211 - if (put_compat_timeval(tv, &ktv)) 212 - return -EFAULT; 213 - } 214 - if (tz) { 215 - extern struct timezone sys_tz; 216 - if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) 217 - return -EFAULT; 218 - } 219 - return 0; 220 - } 221 - 222 - asmlinkage 223 - int sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) 224 - { 225 - struct timespec kts; 226 - struct timezone ktz; 227 - 228 - if (tv) { 229 - if (get_ts32(&kts, tv)) 230 - return -EFAULT; 231 - } 232 - if (tz) { 233 - if (copy_from_user(&ktz, tz, sizeof(ktz))) 234 - return -EFAULT; 235 - } 236 - 237 - return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); 238 - } 239 - 240 182 /*** copied from mips64 ***/ 241 183 /* 242 184 * Ooo, nasty. We need here to frob 32-bit unsigned longs to
+2 -2
arch/parisc/kernel/syscall_table.S
··· 149 149 ENTRY_COMP(getrlimit) 150 150 ENTRY_COMP(getrusage) 151 151 /* struct timeval and timezone are maybe?? consistent wide and narrow */ 152 - ENTRY_DIFF(gettimeofday) 153 - ENTRY_DIFF(settimeofday) 152 + ENTRY_COMP(gettimeofday) 153 + ENTRY_COMP(settimeofday) 154 154 ENTRY_SAME(getgroups) /* 80 */ 155 155 ENTRY_SAME(setgroups) 156 156 /* struct socketaddr... */
-63
arch/powerpc/kernel/sys_ppc32.c
··· 71 71 return sys_sysfs((int)option, arg1, arg2); 72 72 } 73 73 74 - static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i) 75 - { 76 - long usec; 77 - 78 - if (!access_ok(VERIFY_READ, i, sizeof(*i))) 79 - return -EFAULT; 80 - if (__get_user(o->tv_sec, &i->tv_sec)) 81 - return -EFAULT; 82 - if (__get_user(usec, &i->tv_usec)) 83 - return -EFAULT; 84 - o->tv_nsec = usec * 1000; 85 - return 0; 86 - } 87 - 88 - static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i) 89 - { 90 - return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || 91 - (__put_user(i->tv_sec, &o->tv_sec) | 92 - __put_user(i->tv_usec, &o->tv_usec))); 93 - } 94 - 95 - 96 - 97 - 98 - /* Translations due to time_t size differences. Which affects all 99 - sorts of things, like timeval and itimerval. */ 100 - extern struct timezone sys_tz; 101 - 102 - asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) 103 - { 104 - if (tv) { 105 - struct timeval ktv; 106 - do_gettimeofday(&ktv); 107 - if (put_tv32(tv, &ktv)) 108 - return -EFAULT; 109 - } 110 - if (tz) { 111 - if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) 112 - return -EFAULT; 113 - } 114 - 115 - return 0; 116 - } 117 - 118 - 119 - 120 - asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) 121 - { 122 - struct timespec kts; 123 - struct timezone ktz; 124 - 125 - if (tv) { 126 - if (get_ts32(&kts, tv)) 127 - return -EFAULT; 128 - } 129 - if (tz) { 130 - if (copy_from_user(&ktz, tz, sizeof(ktz))) 131 - return -EFAULT; 132 - } 133 - 134 - return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); 135 - } 136 - 137 74 #ifdef CONFIG_SYSVIPC 138 75 long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr, 139 76 u32 fifth)
-67
arch/s390/kernel/compat_linux.c
··· 279 279 return high2lowgid(current->egid); 280 280 } 281 281 282 - /* 32-bit timeval and related flotsam. */ 283 - 284 - static inline long get_tv32(struct timeval *o, struct compat_timeval __user *i) 285 - { 286 - return (!access_ok(VERIFY_READ, o, sizeof(*o)) || 287 - (__get_user(o->tv_sec, &i->tv_sec) || 288 - __get_user(o->tv_usec, &i->tv_usec))); 289 - } 290 - 291 - static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i) 292 - { 293 - return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || 294 - (__put_user(i->tv_sec, &o->tv_sec) || 295 - __put_user(i->tv_usec, &o->tv_usec))); 296 - } 297 - 298 282 /* 299 283 * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation. 300 284 * ··· 505 521 } 506 522 507 523 #endif /* CONFIG_MODULES */ 508 - 509 - /* Translations due to time_t size differences. Which affects all 510 - sorts of things, like timeval and itimerval. */ 511 - 512 - extern struct timezone sys_tz; 513 - 514 - asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) 515 - { 516 - if (tv) { 517 - struct timeval ktv; 518 - do_gettimeofday(&ktv); 519 - if (put_tv32(tv, &ktv)) 520 - return -EFAULT; 521 - } 522 - if (tz) { 523 - if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) 524 - return -EFAULT; 525 - } 526 - return 0; 527 - } 528 - 529 - static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i) 530 - { 531 - long usec; 532 - 533 - if (!access_ok(VERIFY_READ, i, sizeof(*i))) 534 - return -EFAULT; 535 - if (__get_user(o->tv_sec, &i->tv_sec)) 536 - return -EFAULT; 537 - if (__get_user(usec, &i->tv_usec)) 538 - return -EFAULT; 539 - o->tv_nsec = usec * 1000; 540 - return 0; 541 - } 542 - 543 - asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) 544 - { 545 - struct timespec kts; 546 - struct timezone ktz; 547 - 548 - if (tv) { 549 - if (get_ts32(&kts, tv)) 550 - return -EFAULT; 551 - } 552 - if (tz) { 553 - if (copy_from_user(&ktz, tz, sizeof(ktz))) 554 - return -EFAULT; 555 - } 556 - 557 - return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); 558 - } 559 524 560 525 asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf, 561 526 size_t count, u32 poshi, u32 poslo)
-4
arch/s390/kernel/compat_linux.h
··· 202 202 long sys32_init_module(void __user *umod, unsigned long len, 203 203 const char __user *uargs); 204 204 long sys32_delete_module(const char __user *name_user, unsigned int flags); 205 - long sys32_gettimeofday(struct compat_timeval __user *tv, 206 - struct timezone __user *tz); 207 - long sys32_settimeofday(struct compat_timeval __user *tv, 208 - struct timezone __user *tz); 209 205 long sys32_pread64(unsigned int fd, char __user *ubuf, size_t count, 210 206 u32 poshi, u32 poslo); 211 207 long sys32_pwrite64(unsigned int fd, const char __user *ubuf,
+6 -6
arch/s390/kernel/compat_wrapper.S
··· 332 332 llgtr %r3,%r3 # struct rusage_emu31 * 333 333 jg compat_sys_getrusage # branch to system call 334 334 335 - .globl sys32_gettimeofday_wrapper 336 - sys32_gettimeofday_wrapper: 335 + .globl compat_sys_gettimeofday_wrapper 336 + compat_sys_gettimeofday_wrapper: 337 337 llgtr %r2,%r2 # struct timeval_emu31 * 338 338 llgtr %r3,%r3 # struct timezone * 339 - jg sys32_gettimeofday # branch to system call 339 + jg compat_sys_gettimeofday # branch to system call 340 340 341 - .globl sys32_settimeofday_wrapper 342 - sys32_settimeofday_wrapper: 341 + .globl compat_sys_settimeofday_wrapper 342 + compat_sys_settimeofday_wrapper: 343 343 llgtr %r2,%r2 # struct timeval_emu31 * 344 344 llgtr %r3,%r3 # struct timezone * 345 - jg sys32_settimeofday # branch to system call 345 + jg compat_sys_settimeofday # branch to system call 346 346 347 347 .globl sys32_getgroups16_wrapper 348 348 sys32_getgroups16_wrapper:
+2 -2
arch/s390/kernel/syscalls.S
··· 86 86 SYSCALL(sys_setrlimit,sys_setrlimit,compat_sys_setrlimit_wrapper) /* 75 */ 87 87 SYSCALL(sys_old_getrlimit,sys_getrlimit,compat_sys_old_getrlimit_wrapper) 88 88 SYSCALL(sys_getrusage,sys_getrusage,compat_sys_getrusage_wrapper) 89 - SYSCALL(sys_gettimeofday,sys_gettimeofday,sys32_gettimeofday_wrapper) 90 - SYSCALL(sys_settimeofday,sys_settimeofday,sys32_settimeofday_wrapper) 89 + SYSCALL(sys_gettimeofday,sys_gettimeofday,compat_sys_gettimeofday_wrapper) 90 + SYSCALL(sys_settimeofday,sys_settimeofday,compat_sys_settimeofday_wrapper) 91 91 SYSCALL(sys_getgroups16,sys_ni_syscall,sys32_getgroups16_wrapper) /* 80 old getgroups16 syscall */ 92 92 SYSCALL(sys_setgroups16,sys_ni_syscall,sys32_setgroups16_wrapper) /* old setgroups16 syscall */ 93 93 NI_SYSCALL /* old select syscall */
-62
arch/sparc64/kernel/sys_sparc32.c
··· 58 58 #include <asm/mmu_context.h> 59 59 #include <asm/compat_signal.h> 60 60 61 - /* 32-bit timeval and related flotsam. */ 62 - 63 - static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i) 64 - { 65 - return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || 66 - (__put_user(i->tv_sec, &o->tv_sec) | 67 - __put_user(i->tv_usec, &o->tv_usec))); 68 - } 69 - 70 61 #ifdef CONFIG_SYSVIPC 71 62 asmlinkage long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr, u32 fifth) 72 63 { ··· 477 486 } 478 487 479 488 #endif /* CONFIG_MODULES */ 480 - 481 - /* Translations due to time_t size differences. Which affects all 482 - sorts of things, like timeval and itimerval. */ 483 - 484 - extern struct timezone sys_tz; 485 - 486 - asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv, 487 - struct timezone __user *tz) 488 - { 489 - if (tv) { 490 - struct timeval ktv; 491 - do_gettimeofday(&ktv); 492 - if (put_tv32(tv, &ktv)) 493 - return -EFAULT; 494 - } 495 - if (tz) { 496 - if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) 497 - return -EFAULT; 498 - } 499 - return 0; 500 - } 501 - 502 - static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i) 503 - { 504 - long usec; 505 - 506 - if (!access_ok(VERIFY_READ, i, sizeof(*i))) 507 - return -EFAULT; 508 - if (__get_user(o->tv_sec, &i->tv_sec)) 509 - return -EFAULT; 510 - if (__get_user(usec, &i->tv_usec)) 511 - return -EFAULT; 512 - o->tv_nsec = usec * 1000; 513 - return 0; 514 - } 515 - 516 - asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, 517 - struct timezone __user *tz) 518 - { 519 - struct timespec kts; 520 - struct timezone ktz; 521 - 522 - if (tv) { 523 - if (get_ts32(&kts, tv)) 524 - return -EFAULT; 525 - } 526 - if (tz) { 527 - if (copy_from_user(&ktz, tz, sizeof(ktz))) 528 - return -EFAULT; 529 - } 530 - 531 - return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); 532 - } 533 489 534 490 asmlinkage compat_ssize_t sys32_pread64(unsigned int fd, 535 491 char __user *ubuf,
+2 -2
arch/sparc64/kernel/systbls.S
··· 41 41 /*100*/ .word sys32_getpriority, sys32_rt_sigreturn, sys32_rt_sigaction, sys32_rt_sigprocmask, sys32_rt_sigpending 42 42 .word compat_sys_rt_sigtimedwait, sys32_rt_sigqueueinfo, compat_sys_rt_sigsuspend, sys_setresuid, sys_getresuid 43 43 /*110*/ .word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall 44 - .word sys32_getgroups, sys32_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd 45 - /*120*/ .word compat_sys_readv, compat_sys_writev, sys32_settimeofday, sys_fchown16, sys_fchmod 44 + .word sys32_getgroups, compat_sys_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd 45 + /*120*/ .word compat_sys_readv, compat_sys_writev, compat_sys_settimeofday, sys_fchown16, sys_fchmod 46 46 .word sys_nis_syscall, sys_setreuid16, sys_setregid16, sys_rename, sys_truncate 47 47 /*130*/ .word sys_ftruncate, sys_flock, compat_sys_lstat64, sys_nis_syscall, sys_nis_syscall 48 48 .word sys_nis_syscall, sys32_mkdir, sys_rmdir, compat_sys_utimes, compat_sys_stat64
+2 -2
arch/x86/ia32/ia32entry.S
··· 571 571 .quad compat_sys_setrlimit /* 75 */ 572 572 .quad compat_sys_old_getrlimit /* old_getrlimit */ 573 573 .quad compat_sys_getrusage 574 - .quad sys32_gettimeofday 575 - .quad sys32_settimeofday 574 + .quad compat_sys_gettimeofday 575 + .quad compat_sys_settimeofday 576 576 .quad sys_getgroups16 /* 80 */ 577 577 .quad sys_setgroups16 578 578 .quad sys32_old_select
-64
arch/x86/ia32/sys_ia32.c
··· 367 367 return 0; 368 368 } 369 369 370 - static inline long get_tv32(struct timeval *o, struct compat_timeval __user *i) 371 - { 372 - int err = -EFAULT; 373 - 374 - if (access_ok(VERIFY_READ, i, sizeof(*i))) { 375 - err = __get_user(o->tv_sec, &i->tv_sec); 376 - err |= __get_user(o->tv_usec, &i->tv_usec); 377 - } 378 - return err; 379 - } 380 - 381 - static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i) 382 - { 383 - int err = -EFAULT; 384 - 385 - if (access_ok(VERIFY_WRITE, o, sizeof(*o))) { 386 - err = __put_user(i->tv_sec, &o->tv_sec); 387 - err |= __put_user(i->tv_usec, &o->tv_usec); 388 - } 389 - return err; 390 - } 391 - 392 370 asmlinkage long sys32_alarm(unsigned int seconds) 393 371 { 394 372 return alarm_setitimer(seconds); 395 - } 396 - 397 - /* 398 - * Translations due to time_t size differences. Which affects all 399 - * sorts of things, like timeval and itimerval. 400 - */ 401 - asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv, 402 - struct timezone __user *tz) 403 - { 404 - if (tv) { 405 - struct timeval ktv; 406 - 407 - do_gettimeofday(&ktv); 408 - if (put_tv32(tv, &ktv)) 409 - return -EFAULT; 410 - } 411 - if (tz) { 412 - if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) 413 - return -EFAULT; 414 - } 415 - return 0; 416 - } 417 - 418 - asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, 419 - struct timezone __user *tz) 420 - { 421 - struct timeval ktv; 422 - struct timespec kts; 423 - struct timezone ktz; 424 - 425 - if (tv) { 426 - if (get_tv32(&ktv, tv)) 427 - return -EFAULT; 428 - kts.tv_sec = ktv.tv_sec; 429 - kts.tv_nsec = ktv.tv_usec * NSEC_PER_USEC; 430 - } 431 - if (tz) { 432 - if (copy_from_user(&ktz, tz, sizeof(ktz))) 433 - return -EFAULT; 434 - } 435 - 436 - return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); 437 373 } 438 374 439 375 struct sel_arg_struct {
+5
include/linux/compat.h
··· 234 234 extern int put_compat_itimerspec(struct compat_itimerspec __user *dst, 235 235 const struct itimerspec *src); 236 236 237 + asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv, 238 + struct timezone __user *tz); 239 + asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, 240 + struct timezone __user *tz); 241 + 237 242 asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp); 238 243 239 244 extern int compat_printk(const char *fmt, ...);
+2
include/linux/time.h
··· 29 29 30 30 #ifdef __KERNEL__ 31 31 32 + extern struct timezone sys_tz; 33 + 32 34 /* Parameters used to convert the timespec values: */ 33 35 #define MSEC_PER_SEC 1000L 34 36 #define USEC_PER_MSEC 1000L
+58
kernel/compat.c
··· 26 26 27 27 #include <asm/uaccess.h> 28 28 29 + /* 30 + * Note that the native side is already converted to a timespec, because 31 + * that's what we want anyway. 32 + */ 33 + static int compat_get_timeval(struct timespec *o, 34 + struct compat_timeval __user *i) 35 + { 36 + long usec; 37 + 38 + if (get_user(o->tv_sec, &i->tv_sec) || 39 + get_user(usec, &i->tv_usec)) 40 + return -EFAULT; 41 + o->tv_nsec = usec * 1000; 42 + return 0; 43 + } 44 + 45 + static int compat_put_timeval(struct compat_timeval __user *o, 46 + struct timeval *i) 47 + { 48 + return (put_user(i->tv_sec, &o->tv_sec) || 49 + put_user(i->tv_usec, &o->tv_usec)) ? -EFAULT : 0; 50 + } 51 + 52 + asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv, 53 + struct timezone __user *tz) 54 + { 55 + if (tv) { 56 + struct timeval ktv; 57 + do_gettimeofday(&ktv); 58 + if (compat_put_timeval(tv, &ktv)) 59 + return -EFAULT; 60 + } 61 + if (tz) { 62 + if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) 63 + return -EFAULT; 64 + } 65 + 66 + return 0; 67 + } 68 + 69 + asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, 70 + struct timezone __user *tz) 71 + { 72 + struct timespec kts; 73 + struct timezone ktz; 74 + 75 + if (tv) { 76 + if (compat_get_timeval(&kts, tv)) 77 + return -EFAULT; 78 + } 79 + if (tz) { 80 + if (copy_from_user(&ktz, tz, sizeof(ktz))) 81 + return -EFAULT; 82 + } 83 + 84 + return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); 85 + } 86 + 29 87 int get_compat_timespec(struct timespec *ts, const struct compat_timespec __user *cts) 30 88 { 31 89 return (!access_ok(VERIFY_READ, cts, sizeof(*cts)) ||