aboutsummaryrefslogtreecommitdiffstats
path: root/fs
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 /fs
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>
Diffstat (limited to 'fs')
-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
4 files changed, 74 insertions, 13 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