Commit 6673e0c3fbeaed2cd08e2fd4a4aa97382d6fedb0

Authored by Heiko Carstens
1 parent ed6bb61943

[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

... ... @@ -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 {
... ... @@ -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.
... ... @@ -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
... ... @@ -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
... ... @@ -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,
... ... @@ -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
... ... @@ -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 /**