diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2009-01-14 08:14:02 -0500 |
---|---|---|
committer | Heiko Carstens <heiko.carstens@de.ibm.com> | 2009-01-14 08:15:18 -0500 |
commit | 6673e0c3fbeaed2cd08e2fd4a4aa97382d6fedb0 (patch) | |
tree | eb33a94f5e4b0e035001f7c96ef44cade0fbb489 /fs | |
parent | ed6bb6194350dc6ae97a65dbf2d621a3dbe6bbe9 (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.c | 10 | ||||
-rw-r--r-- | fs/open.c | 27 | ||||
-rw-r--r-- | fs/read_write.c | 24 | ||||
-rw-r--r-- | fs/sync.c | 26 |
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 | */ |
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 | 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 | |
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 | static int dcookie_init(void) | 209 | static int dcookie_init(void) |
204 | { | 210 | { |
@@ -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 |
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 | return do_sys_truncate(path, length); | 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 | 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 | ||
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 | #endif | 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 | struct file *file; | 384 | struct file *file; |
371 | struct inode *inode; | 385 | struct inode *inode; |
@@ -422,6 +436,13 @@ out_fput: | |||
422 | out: | 436 | out: |
423 | return ret; | 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 | * 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 | ||
406 | asmlinkage long sys_pread64(unsigned int fd, char __user *buf, | 406 | SYSCALL_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 | ||
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, | 435 | SYSCALL_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 | ||
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 | * 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 |
@@ -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 | */ |
204 | asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, | 204 | SYSCALL_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: | |||
262 | out: | 262 | out: |
263 | return ret; | 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 | /* 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 */ |
268 | asmlinkage long sys_sync_file_range2(int fd, unsigned int flags, | 277 | SYSCALL_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 | ||
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 | * `endbyte' is inclusive | 293 | * `endbyte' is inclusive |