Commit 6673e0c3fbeaed2cd08e2fd4a4aa97382d6fedb0
1 parent
ed6bb61943
Exists in
master
and in
4 other branches
[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>
Showing 7 changed files with 106 additions and 17 deletions Side-by-side Diff
fs/dcookies.c
| ... | ... | @@ -145,7 +145,7 @@ |
| 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,7 +198,13 @@ |
| 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 | { |
fs/open.c
| ... | ... | @@ -351,21 +351,35 @@ |
| 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; |
| ... | ... | @@ -422,6 +436,13 @@ |
| 422 | 436 | out: |
| 423 | 437 | return ret; |
| 424 | 438 | } |
| 439 | +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS | |
| 440 | +asmlinkage long SyS_fallocate(long fd, long mode, loff_t offset, loff_t len) | |
| 441 | +{ | |
| 442 | + return SYSC_fallocate((int)fd, (int)mode, offset, len); | |
| 443 | +} | |
| 444 | +SYSCALL_ALIAS(sys_fallocate, SyS_fallocate); | |
| 445 | +#endif | |
| 425 | 446 | |
| 426 | 447 | /* |
| 427 | 448 | * access() needs to use the real uid/gid, not the effective uid/gid. |
fs/read_write.c
| ... | ... | @@ -403,8 +403,8 @@ |
| 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; |
| 411 | 411 | |
| ... | ... | @@ -423,9 +423,17 @@ |
| 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; |
| ... | ... | @@ -444,6 +452,14 @@ |
| 444 | 452 | |
| 445 | 453 | return ret; |
| 446 | 454 | } |
| 455 | +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS | |
| 456 | +asmlinkage long SyS_pwrite64(long fd, long buf, long count, loff_t pos) | |
| 457 | +{ | |
| 458 | + return SYSC_pwrite64((unsigned int) fd, (const char __user *) buf, | |
| 459 | + (size_t) count, pos); | |
| 460 | +} | |
| 461 | +SYSCALL_ALIAS(sys_pwrite64, SyS_pwrite64); | |
| 462 | +#endif | |
| 447 | 463 | |
| 448 | 464 | /* |
| 449 | 465 | * Reduce an iovec's length in-place. Return the resulting number of segments |
fs/sync.c
| ... | ... | @@ -201,8 +201,8 @@ |
| 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; |
| 209 | 209 | |
| 210 | 210 | |
| ... | ... | @@ -262,14 +262,32 @@ |
| 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 |
ipc/sem.c
| ... | ... | @@ -887,7 +887,7 @@ |
| 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,6 +923,13 @@ |
| 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, |
mm/fadvise.c
| ... | ... | @@ -24,7 +24,7 @@ |
| 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; |
| 31 | 31 | |
| 32 | 32 | |
| ... | ... | @@ -126,13 +126,27 @@ |
| 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 |
mm/filemap.c
| ... | ... | @@ -1374,7 +1374,7 @@ |
| 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,6 +1393,13 @@ |
| 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 | /** |