aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2009-01-14 08:14:02 -0500
committerHeiko Carstens <heiko.carstens@de.ibm.com>2009-01-14 08:15:18 -0500
commit6673e0c3fbeaed2cd08e2fd4a4aa97382d6fedb0 (patch)
treeeb33a94f5e4b0e035001f7c96ef44cade0fbb489
parented6bb6194350dc6ae97a65dbf2d621a3dbe6bbe9 (diff)
[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>
-rw-r--r--fs/dcookies.c10
-rw-r--r--fs/open.c27
-rw-r--r--fs/read_write.c24
-rw-r--r--fs/sync.c26
-rw-r--r--ipc/sem.c9
-rw-r--r--mm/fadvise.c18
-rw-r--r--mm/filemap.c9
7 files changed, 106 insertions, 17 deletions
diff --git a/fs/dcookies.c b/fs/dcookies.c
index 180e9fec4ad8..a21cabdbd87b 100644
--- a/fs/dcookies.c
+++ b/fs/dcookies.c
@@ -145,7 +145,7 @@ out:
145/* And here is where the userspace process can look up the cookie value 145/* And here is where the userspace process can look up the cookie value
146 * to retrieve the path. 146 * to retrieve the path.
147 */ 147 */
148asmlinkage long sys_lookup_dcookie(u64 cookie64, char __user * buf, size_t len) 148SYSCALL_DEFINE(lookup_dcookie)(u64 cookie64, char __user * buf, size_t len)
149{ 149{
150 unsigned long cookie = (unsigned long)cookie64; 150 unsigned long cookie = (unsigned long)cookie64;
151 int err = -EINVAL; 151 int err = -EINVAL;
@@ -198,7 +198,13 @@ out:
198 mutex_unlock(&dcookie_mutex); 198 mutex_unlock(&dcookie_mutex);
199 return err; 199 return err;
200} 200}
201 201#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
202asmlinkage long SyS_lookup_dcookie(u64 cookie64, long buf, long len)
203{
204 return SYSC_lookup_dcookie(cookie64, (char __user *) buf, (size_t) len);
205}
206SYSCALL_ALIAS(sys_lookup_dcookie, SyS_lookup_dcookie);
207#endif
202 208
203static int dcookie_init(void) 209static int dcookie_init(void)
204{ 210{
diff --git a/fs/open.c b/fs/open.c
index d882fd2351d6..e349013fc790 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -351,21 +351,35 @@ asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length)
351 351
352/* LFS versions of truncate are only needed on 32 bit machines */ 352/* LFS versions of truncate are only needed on 32 bit machines */
353#if BITS_PER_LONG == 32 353#if BITS_PER_LONG == 32
354asmlinkage long sys_truncate64(const char __user * path, loff_t length) 354SYSCALL_DEFINE(truncate64)(const char __user * path, loff_t length)
355{ 355{
356 return do_sys_truncate(path, length); 356 return do_sys_truncate(path, length);
357} 357}
358#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
359asmlinkage long SyS_truncate64(long path, loff_t length)
360{
361 return SYSC_truncate64((const char __user *) path, length);
362}
363SYSCALL_ALIAS(sys_truncate64, SyS_truncate64);
364#endif
358 365
359asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length) 366SYSCALL_DEFINE(ftruncate64)(unsigned int fd, loff_t length)
360{ 367{
361 long ret = do_sys_ftruncate(fd, length, 0); 368 long ret = do_sys_ftruncate(fd, length, 0);
362 /* avoid REGPARM breakage on x86: */ 369 /* avoid REGPARM breakage on x86: */
363 asmlinkage_protect(2, ret, fd, length); 370 asmlinkage_protect(2, ret, fd, length);
364 return ret; 371 return ret;
365} 372}
373#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
374asmlinkage long SyS_ftruncate64(long fd, loff_t length)
375{
376 return SYSC_ftruncate64((unsigned int) fd, length);
377}
378SYSCALL_ALIAS(sys_ftruncate64, SyS_ftruncate64);
366#endif 379#endif
380#endif /* BITS_PER_LONG == 32 */
367 381
368asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len) 382SYSCALL_DEFINE(fallocate)(int fd, int mode, loff_t offset, loff_t len)
369{ 383{
370 struct file *file; 384 struct file *file;
371 struct inode *inode; 385 struct inode *inode;
@@ -422,6 +436,13 @@ out_fput:
422out: 436out:
423 return ret; 437 return ret;
424} 438}
439#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
440asmlinkage 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}
444SYSCALL_ALIAS(sys_fallocate, SyS_fallocate);
445#endif
425 446
426/* 447/*
427 * access() needs to use the real uid/gid, not the effective uid/gid. 448 * access() needs to use the real uid/gid, not the effective uid/gid.
diff --git a/fs/read_write.c b/fs/read_write.c
index 940367f51f2a..7a8326bc5903 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -403,8 +403,8 @@ asmlinkage long sys_write(unsigned int fd, const char __user * buf, size_t count
403 return ret; 403 return ret;
404} 404}
405 405
406asmlinkage long sys_pread64(unsigned int fd, char __user *buf, 406SYSCALL_DEFINE(pread64)(unsigned int fd, char __user *buf,
407 size_t count, loff_t pos) 407 size_t count, loff_t pos)
408{ 408{
409 struct file *file; 409 struct file *file;
410 ssize_t ret = -EBADF; 410 ssize_t ret = -EBADF;
@@ -423,9 +423,17 @@ asmlinkage long sys_pread64(unsigned int fd, char __user *buf,
423 423
424 return ret; 424 return ret;
425} 425}
426#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
427asmlinkage 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}
432SYSCALL_ALIAS(sys_pread64, SyS_pread64);
433#endif
426 434
427asmlinkage long sys_pwrite64(unsigned int fd, const char __user *buf, 435SYSCALL_DEFINE(pwrite64)(unsigned int fd, const char __user *buf,
428 size_t count, loff_t pos) 436 size_t count, loff_t pos)
429{ 437{
430 struct file *file; 438 struct file *file;
431 ssize_t ret = -EBADF; 439 ssize_t ret = -EBADF;
@@ -444,6 +452,14 @@ asmlinkage long sys_pwrite64(unsigned int fd, const char __user *buf,
444 452
445 return ret; 453 return ret;
446} 454}
455#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
456asmlinkage 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}
461SYSCALL_ALIAS(sys_pwrite64, SyS_pwrite64);
462#endif
447 463
448/* 464/*
449 * Reduce an iovec's length in-place. Return the resulting number of segments 465 * Reduce an iovec's length in-place. Return the resulting number of segments
diff --git a/fs/sync.c b/fs/sync.c
index ac02b56548bc..23ebbd72ecc9 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -201,8 +201,8 @@ asmlinkage long sys_fdatasync(unsigned int fd)
201 * already-instantiated disk blocks, there are no guarantees here that the data 201 * already-instantiated disk blocks, there are no guarantees here that the data
202 * will be available after a crash. 202 * will be available after a crash.
203 */ 203 */
204asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, 204SYSCALL_DEFINE(sync_file_range)(int fd, loff_t offset, loff_t nbytes,
205 unsigned int flags) 205 unsigned int flags)
206{ 206{
207 int ret; 207 int ret;
208 struct file *file; 208 struct file *file;
@@ -262,14 +262,32 @@ out_put:
262out: 262out:
263 return ret; 263 return ret;
264} 264}
265#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
266asmlinkage 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}
272SYSCALL_ALIAS(sys_sync_file_range, SyS_sync_file_range);
273#endif
265 274
266/* It would be nice if people remember that not all the world's an i386 275/* It would be nice if people remember that not all the world's an i386
267 when they introduce new system calls */ 276 when they introduce new system calls */
268asmlinkage long sys_sync_file_range2(int fd, unsigned int flags, 277SYSCALL_DEFINE(sync_file_range2)(int fd, unsigned int flags,
269 loff_t offset, loff_t nbytes) 278 loff_t offset, loff_t nbytes)
270{ 279{
271 return sys_sync_file_range(fd, offset, nbytes, flags); 280 return sys_sync_file_range(fd, offset, nbytes, flags);
272} 281}
282#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
283asmlinkage 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}
289SYSCALL_ALIAS(sys_sync_file_range2, SyS_sync_file_range2);
290#endif
273 291
274/* 292/*
275 * `endbyte' is inclusive 293 * `endbyte' is inclusive
diff --git a/ipc/sem.c b/ipc/sem.c
index c68cd3f8f0c9..c385c40c061c 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -887,7 +887,7 @@ out_up:
887 return err; 887 return err;
888} 888}
889 889
890asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg) 890SYSCALL_DEFINE(semctl)(int semid, int semnum, int cmd, union semun arg)
891{ 891{
892 int err = -EINVAL; 892 int err = -EINVAL;
893 int version; 893 int version;
@@ -923,6 +923,13 @@ asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg)
923 return -EINVAL; 923 return -EINVAL;
924 } 924 }
925} 925}
926#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
927asmlinkage 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}
931SYSCALL_ALIAS(sys_semctl, SyS_semctl);
932#endif
926 933
927/* If the task doesn't already have a undo_list, then allocate one 934/* If the task doesn't already have a undo_list, then allocate one
928 * here. We guarantee there is only one thread using this undo list, 935 * here. We guarantee there is only one thread using this undo list,
diff --git a/mm/fadvise.c b/mm/fadvise.c
index a1da969bd980..54a0f8040afa 100644
--- a/mm/fadvise.c
+++ b/mm/fadvise.c
@@ -24,7 +24,7 @@
24 * POSIX_FADV_WILLNEED could set PG_Referenced, and POSIX_FADV_NOREUSE could 24 * POSIX_FADV_WILLNEED could set PG_Referenced, and POSIX_FADV_NOREUSE could
25 * deactivate the pages and clear PG_Referenced. 25 * deactivate the pages and clear PG_Referenced.
26 */ 26 */
27asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice) 27SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice)
28{ 28{
29 struct file *file = fget(fd); 29 struct file *file = fget(fd);
30 struct address_space *mapping; 30 struct address_space *mapping;
@@ -126,12 +126,26 @@ out:
126 fput(file); 126 fput(file);
127 return ret; 127 return ret;
128} 128}
129#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
130asmlinkage 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}
134SYSCALL_ALIAS(sys_fadvise64_64, SyS_fadvise64_64);
135#endif
129 136
130#ifdef __ARCH_WANT_SYS_FADVISE64 137#ifdef __ARCH_WANT_SYS_FADVISE64
131 138
132asmlinkage long sys_fadvise64(int fd, loff_t offset, size_t len, int advice) 139SYSCALL_DEFINE(fadvise64)(int fd, loff_t offset, size_t len, int advice)
133{ 140{
134 return sys_fadvise64_64(fd, offset, len, advice); 141 return sys_fadvise64_64(fd, offset, len, advice);
135} 142}
143#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
144asmlinkage 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}
148SYSCALL_ALIAS(sys_fadvise64, SyS_fadvise64);
149#endif
136 150
137#endif 151#endif
diff --git a/mm/filemap.c b/mm/filemap.c
index 538b75ed6236..23acefe51808 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1374,7 +1374,7 @@ do_readahead(struct address_space *mapping, struct file *filp,
1374 return 0; 1374 return 0;
1375} 1375}
1376 1376
1377asmlinkage long sys_readahead(int fd, loff_t offset, size_t count) 1377SYSCALL_DEFINE(readahead)(int fd, loff_t offset, size_t count)
1378{ 1378{
1379 ssize_t ret; 1379 ssize_t ret;
1380 struct file *file; 1380 struct file *file;
@@ -1393,6 +1393,13 @@ asmlinkage long sys_readahead(int fd, loff_t offset, size_t count)
1393 } 1393 }
1394 return ret; 1394 return ret;
1395} 1395}
1396#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
1397asmlinkage long SyS_readahead(long fd, loff_t offset, long count)
1398{
1399 return SYSC_readahead((int) fd, offset, (size_t) count);
1400}
1401SYSCALL_ALIAS(sys_readahead, SyS_readahead);
1402#endif
1396 1403
1397#ifdef CONFIG_MMU 1404#ifdef CONFIG_MMU
1398/** 1405/**