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

[CVE-2009-0029] System call wrapper special cases

System calls with an unsigned long long argument can't be converted with
the standard wrappers since that would include a cast to long, which in
turn means that we would lose the upper 32 bit on 32 bit architectures.
Also semctl can't use the standard wrapper since it has a 'union'
parameter.

So we handle them as special case and add some extra wrappers instead.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>

+106 -17
+8 -2
fs/dcookies.c
··· 145 145 /* And here is where the userspace process can look up the cookie value 146 146 * to retrieve the path. 147 147 */ 148 - asmlinkage long sys_lookup_dcookie(u64 cookie64, char __user * buf, size_t len) 148 + SYSCALL_DEFINE(lookup_dcookie)(u64 cookie64, char __user * buf, size_t len) 149 149 { 150 150 unsigned long cookie = (unsigned long)cookie64; 151 151 int err = -EINVAL; ··· 198 198 mutex_unlock(&dcookie_mutex); 199 199 return err; 200 200 } 201 - 201 + #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS 202 + asmlinkage long SyS_lookup_dcookie(u64 cookie64, long buf, long len) 203 + { 204 + return SYSC_lookup_dcookie(cookie64, (char __user *) buf, (size_t) len); 205 + } 206 + SYSCALL_ALIAS(sys_lookup_dcookie, SyS_lookup_dcookie); 207 + #endif 202 208 203 209 static int dcookie_init(void) 204 210 {
+24 -3
fs/open.c
··· 351 351 352 352 /* LFS versions of truncate are only needed on 32 bit machines */ 353 353 #if BITS_PER_LONG == 32 354 - asmlinkage long sys_truncate64(const char __user * path, loff_t length) 354 + SYSCALL_DEFINE(truncate64)(const char __user * path, loff_t length) 355 355 { 356 356 return do_sys_truncate(path, length); 357 357 } 358 + #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS 359 + asmlinkage long SyS_truncate64(long path, loff_t length) 360 + { 361 + return SYSC_truncate64((const char __user *) path, length); 362 + } 363 + SYSCALL_ALIAS(sys_truncate64, SyS_truncate64); 364 + #endif 358 365 359 - asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length) 366 + SYSCALL_DEFINE(ftruncate64)(unsigned int fd, loff_t length) 360 367 { 361 368 long ret = do_sys_ftruncate(fd, length, 0); 362 369 /* avoid REGPARM breakage on x86: */ 363 370 asmlinkage_protect(2, ret, fd, length); 364 371 return ret; 365 372 } 373 + #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS 374 + asmlinkage long SyS_ftruncate64(long fd, loff_t length) 375 + { 376 + return SYSC_ftruncate64((unsigned int) fd, length); 377 + } 378 + SYSCALL_ALIAS(sys_ftruncate64, SyS_ftruncate64); 366 379 #endif 380 + #endif /* BITS_PER_LONG == 32 */ 367 381 368 - asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len) 382 + SYSCALL_DEFINE(fallocate)(int fd, int mode, loff_t offset, loff_t len) 369 383 { 370 384 struct file *file; 371 385 struct inode *inode; ··· 436 422 out: 437 423 return ret; 438 424 } 425 + #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS 426 + asmlinkage long SyS_fallocate(long fd, long mode, loff_t offset, loff_t len) 427 + { 428 + return SYSC_fallocate((int)fd, (int)mode, offset, len); 429 + } 430 + SYSCALL_ALIAS(sys_fallocate, SyS_fallocate); 431 + #endif 439 432 440 433 /* 441 434 * access() needs to use the real uid/gid, not the effective uid/gid.
+20 -4
fs/read_write.c
··· 403 403 return ret; 404 404 } 405 405 406 - asmlinkage long sys_pread64(unsigned int fd, char __user *buf, 407 - size_t count, loff_t pos) 406 + SYSCALL_DEFINE(pread64)(unsigned int fd, char __user *buf, 407 + size_t count, loff_t pos) 408 408 { 409 409 struct file *file; 410 410 ssize_t ret = -EBADF; ··· 423 423 424 424 return ret; 425 425 } 426 + #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS 427 + asmlinkage long SyS_pread64(long fd, long buf, long count, loff_t pos) 428 + { 429 + return SYSC_pread64((unsigned int) fd, (char __user *) buf, 430 + (size_t) count, pos); 431 + } 432 + SYSCALL_ALIAS(sys_pread64, SyS_pread64); 433 + #endif 426 434 427 - asmlinkage long sys_pwrite64(unsigned int fd, const char __user *buf, 428 - size_t count, loff_t pos) 435 + SYSCALL_DEFINE(pwrite64)(unsigned int fd, const char __user *buf, 436 + size_t count, loff_t pos) 429 437 { 430 438 struct file *file; 431 439 ssize_t ret = -EBADF; ··· 452 444 453 445 return ret; 454 446 } 447 + #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS 448 + asmlinkage long SyS_pwrite64(long fd, long buf, long count, loff_t pos) 449 + { 450 + return SYSC_pwrite64((unsigned int) fd, (const char __user *) buf, 451 + (size_t) count, pos); 452 + } 453 + SYSCALL_ALIAS(sys_pwrite64, SyS_pwrite64); 454 + #endif 455 455 456 456 /* 457 457 * Reduce an iovec's length in-place. Return the resulting number of segments
+22 -4
fs/sync.c
··· 201 201 * already-instantiated disk blocks, there are no guarantees here that the data 202 202 * will be available after a crash. 203 203 */ 204 - asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, 205 - unsigned int flags) 204 + SYSCALL_DEFINE(sync_file_range)(int fd, loff_t offset, loff_t nbytes, 205 + unsigned int flags) 206 206 { 207 207 int ret; 208 208 struct file *file; ··· 262 262 out: 263 263 return ret; 264 264 } 265 + #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS 266 + asmlinkage long SyS_sync_file_range(long fd, loff_t offset, loff_t nbytes, 267 + long flags) 268 + { 269 + return SYSC_sync_file_range((int) fd, offset, nbytes, 270 + (unsigned int) flags); 271 + } 272 + SYSCALL_ALIAS(sys_sync_file_range, SyS_sync_file_range); 273 + #endif 265 274 266 275 /* It would be nice if people remember that not all the world's an i386 267 276 when they introduce new system calls */ 268 - asmlinkage long sys_sync_file_range2(int fd, unsigned int flags, 269 - loff_t offset, loff_t nbytes) 277 + SYSCALL_DEFINE(sync_file_range2)(int fd, unsigned int flags, 278 + loff_t offset, loff_t nbytes) 270 279 { 271 280 return sys_sync_file_range(fd, offset, nbytes, flags); 272 281 } 282 + #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS 283 + asmlinkage long SyS_sync_file_range2(long fd, long flags, 284 + loff_t offset, loff_t nbytes) 285 + { 286 + return SYSC_sync_file_range2((int) fd, (unsigned int) flags, 287 + offset, nbytes); 288 + } 289 + SYSCALL_ALIAS(sys_sync_file_range2, SyS_sync_file_range2); 290 + #endif 273 291 274 292 /* 275 293 * `endbyte' is inclusive
+8 -1
ipc/sem.c
··· 887 887 return err; 888 888 } 889 889 890 - asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg) 890 + SYSCALL_DEFINE(semctl)(int semid, int semnum, int cmd, union semun arg) 891 891 { 892 892 int err = -EINVAL; 893 893 int version; ··· 923 923 return -EINVAL; 924 924 } 925 925 } 926 + #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS 927 + asmlinkage long SyS_semctl(int semid, int semnum, int cmd, union semun arg) 928 + { 929 + return SYSC_semctl((int) semid, (int) semnum, (int) cmd, arg); 930 + } 931 + SYSCALL_ALIAS(sys_semctl, SyS_semctl); 932 + #endif 926 933 927 934 /* If the task doesn't already have a undo_list, then allocate one 928 935 * here. We guarantee there is only one thread using this undo list,
+16 -2
mm/fadvise.c
··· 24 24 * POSIX_FADV_WILLNEED could set PG_Referenced, and POSIX_FADV_NOREUSE could 25 25 * deactivate the pages and clear PG_Referenced. 26 26 */ 27 - asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice) 27 + SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice) 28 28 { 29 29 struct file *file = fget(fd); 30 30 struct address_space *mapping; ··· 126 126 fput(file); 127 127 return ret; 128 128 } 129 + #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS 130 + asmlinkage long SyS_fadvise64_64(long fd, loff_t offset, loff_t len, long advice) 131 + { 132 + return SYSC_fadvise64_64((int) fd, offset, len, (int) advice); 133 + } 134 + SYSCALL_ALIAS(sys_fadvise64_64, SyS_fadvise64_64); 135 + #endif 129 136 130 137 #ifdef __ARCH_WANT_SYS_FADVISE64 131 138 132 - asmlinkage long sys_fadvise64(int fd, loff_t offset, size_t len, int advice) 139 + SYSCALL_DEFINE(fadvise64)(int fd, loff_t offset, size_t len, int advice) 133 140 { 134 141 return sys_fadvise64_64(fd, offset, len, advice); 135 142 } 143 + #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS 144 + asmlinkage long SyS_fadvise64(long fd, loff_t offset, long len, long advice) 145 + { 146 + return SYSC_fadvise64((int) fd, offset, (size_t)len, (int)advice); 147 + } 148 + SYSCALL_ALIAS(sys_fadvise64, SyS_fadvise64); 149 + #endif 136 150 137 151 #endif
+8 -1
mm/filemap.c
··· 1374 1374 return 0; 1375 1375 } 1376 1376 1377 - asmlinkage long sys_readahead(int fd, loff_t offset, size_t count) 1377 + SYSCALL_DEFINE(readahead)(int fd, loff_t offset, size_t count) 1378 1378 { 1379 1379 ssize_t ret; 1380 1380 struct file *file; ··· 1393 1393 } 1394 1394 return ret; 1395 1395 } 1396 + #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS 1397 + asmlinkage long SyS_readahead(long fd, loff_t offset, long count) 1398 + { 1399 + return SYSC_readahead((int) fd, offset, (size_t) count); 1400 + } 1401 + SYSCALL_ALIAS(sys_readahead, SyS_readahead); 1402 + #endif 1396 1403 1397 1404 #ifdef CONFIG_MMU 1398 1405 /**