mirror of
https://github.com/adulau/aha.git
synced 2024-12-26 18:56:14 +00:00
[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>
This commit is contained in:
parent
ed6bb61943
commit
6673e0c3fb
7 changed files with 106 additions and 17 deletions
|
@ -145,7 +145,7 @@ out:
|
|||
/* And here is where the userspace process can look up the cookie value
|
||||
* to retrieve the path.
|
||||
*/
|
||||
asmlinkage long sys_lookup_dcookie(u64 cookie64, char __user * buf, size_t len)
|
||||
SYSCALL_DEFINE(lookup_dcookie)(u64 cookie64, char __user * buf, size_t len)
|
||||
{
|
||||
unsigned long cookie = (unsigned long)cookie64;
|
||||
int err = -EINVAL;
|
||||
|
@ -198,7 +198,13 @@ out:
|
|||
mutex_unlock(&dcookie_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
|
||||
asmlinkage long SyS_lookup_dcookie(u64 cookie64, long buf, long len)
|
||||
{
|
||||
return SYSC_lookup_dcookie(cookie64, (char __user *) buf, (size_t) len);
|
||||
}
|
||||
SYSCALL_ALIAS(sys_lookup_dcookie, SyS_lookup_dcookie);
|
||||
#endif
|
||||
|
||||
static int dcookie_init(void)
|
||||
{
|
||||
|
|
27
fs/open.c
27
fs/open.c
|
@ -351,21 +351,35 @@ asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length)
|
|||
|
||||
/* LFS versions of truncate are only needed on 32 bit machines */
|
||||
#if BITS_PER_LONG == 32
|
||||
asmlinkage long sys_truncate64(const char __user * path, loff_t length)
|
||||
SYSCALL_DEFINE(truncate64)(const char __user * path, loff_t length)
|
||||
{
|
||||
return do_sys_truncate(path, length);
|
||||
}
|
||||
#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
|
||||
asmlinkage long SyS_truncate64(long path, loff_t length)
|
||||
{
|
||||
return SYSC_truncate64((const char __user *) path, length);
|
||||
}
|
||||
SYSCALL_ALIAS(sys_truncate64, SyS_truncate64);
|
||||
#endif
|
||||
|
||||
asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length)
|
||||
SYSCALL_DEFINE(ftruncate64)(unsigned int fd, loff_t length)
|
||||
{
|
||||
long ret = do_sys_ftruncate(fd, length, 0);
|
||||
/* avoid REGPARM breakage on x86: */
|
||||
asmlinkage_protect(2, ret, fd, length);
|
||||
return ret;
|
||||
}
|
||||
#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
|
||||
asmlinkage long SyS_ftruncate64(long fd, loff_t length)
|
||||
{
|
||||
return SYSC_ftruncate64((unsigned int) fd, length);
|
||||
}
|
||||
SYSCALL_ALIAS(sys_ftruncate64, SyS_ftruncate64);
|
||||
#endif
|
||||
#endif /* BITS_PER_LONG == 32 */
|
||||
|
||||
asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len)
|
||||
SYSCALL_DEFINE(fallocate)(int fd, int mode, loff_t offset, loff_t len)
|
||||
{
|
||||
struct file *file;
|
||||
struct inode *inode;
|
||||
|
@ -422,6 +436,13 @@ out_fput:
|
|||
out:
|
||||
return ret;
|
||||
}
|
||||
#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
|
||||
asmlinkage long SyS_fallocate(long fd, long mode, loff_t offset, loff_t len)
|
||||
{
|
||||
return SYSC_fallocate((int)fd, (int)mode, offset, len);
|
||||
}
|
||||
SYSCALL_ALIAS(sys_fallocate, SyS_fallocate);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* access() needs to use the real uid/gid, not the effective uid/gid.
|
||||
|
|
|
@ -403,8 +403,8 @@ asmlinkage long sys_write(unsigned int fd, const char __user * buf, size_t count
|
|||
return ret;
|
||||
}
|
||||
|
||||
asmlinkage long sys_pread64(unsigned int fd, char __user *buf,
|
||||
size_t count, loff_t pos)
|
||||
SYSCALL_DEFINE(pread64)(unsigned int fd, char __user *buf,
|
||||
size_t count, loff_t pos)
|
||||
{
|
||||
struct file *file;
|
||||
ssize_t ret = -EBADF;
|
||||
|
@ -423,9 +423,17 @@ asmlinkage long sys_pread64(unsigned int fd, char __user *buf,
|
|||
|
||||
return ret;
|
||||
}
|
||||
#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
|
||||
asmlinkage long SyS_pread64(long fd, long buf, long count, loff_t pos)
|
||||
{
|
||||
return SYSC_pread64((unsigned int) fd, (char __user *) buf,
|
||||
(size_t) count, pos);
|
||||
}
|
||||
SYSCALL_ALIAS(sys_pread64, SyS_pread64);
|
||||
#endif
|
||||
|
||||
asmlinkage long sys_pwrite64(unsigned int fd, const char __user *buf,
|
||||
size_t count, loff_t pos)
|
||||
SYSCALL_DEFINE(pwrite64)(unsigned int fd, const char __user *buf,
|
||||
size_t count, loff_t pos)
|
||||
{
|
||||
struct file *file;
|
||||
ssize_t ret = -EBADF;
|
||||
|
@ -444,6 +452,14 @@ asmlinkage long sys_pwrite64(unsigned int fd, const char __user *buf,
|
|||
|
||||
return ret;
|
||||
}
|
||||
#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
|
||||
asmlinkage long SyS_pwrite64(long fd, long buf, long count, loff_t pos)
|
||||
{
|
||||
return SYSC_pwrite64((unsigned int) fd, (const char __user *) buf,
|
||||
(size_t) count, pos);
|
||||
}
|
||||
SYSCALL_ALIAS(sys_pwrite64, SyS_pwrite64);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Reduce an iovec's length in-place. Return the resulting number of segments
|
||||
|
|
26
fs/sync.c
26
fs/sync.c
|
@ -201,8 +201,8 @@ asmlinkage long sys_fdatasync(unsigned int fd)
|
|||
* already-instantiated disk blocks, there are no guarantees here that the data
|
||||
* will be available after a crash.
|
||||
*/
|
||||
asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes,
|
||||
unsigned int flags)
|
||||
SYSCALL_DEFINE(sync_file_range)(int fd, loff_t offset, loff_t nbytes,
|
||||
unsigned int flags)
|
||||
{
|
||||
int ret;
|
||||
struct file *file;
|
||||
|
@ -262,14 +262,32 @@ out_put:
|
|||
out:
|
||||
return ret;
|
||||
}
|
||||
#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
|
||||
asmlinkage long SyS_sync_file_range(long fd, loff_t offset, loff_t nbytes,
|
||||
long flags)
|
||||
{
|
||||
return SYSC_sync_file_range((int) fd, offset, nbytes,
|
||||
(unsigned int) flags);
|
||||
}
|
||||
SYSCALL_ALIAS(sys_sync_file_range, SyS_sync_file_range);
|
||||
#endif
|
||||
|
||||
/* It would be nice if people remember that not all the world's an i386
|
||||
when they introduce new system calls */
|
||||
asmlinkage long sys_sync_file_range2(int fd, unsigned int flags,
|
||||
loff_t offset, loff_t nbytes)
|
||||
SYSCALL_DEFINE(sync_file_range2)(int fd, unsigned int flags,
|
||||
loff_t offset, loff_t nbytes)
|
||||
{
|
||||
return sys_sync_file_range(fd, offset, nbytes, flags);
|
||||
}
|
||||
#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
|
||||
asmlinkage long SyS_sync_file_range2(long fd, long flags,
|
||||
loff_t offset, loff_t nbytes)
|
||||
{
|
||||
return SYSC_sync_file_range2((int) fd, (unsigned int) flags,
|
||||
offset, nbytes);
|
||||
}
|
||||
SYSCALL_ALIAS(sys_sync_file_range2, SyS_sync_file_range2);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* `endbyte' is inclusive
|
||||
|
|
|
@ -887,7 +887,7 @@ out_up:
|
|||
return err;
|
||||
}
|
||||
|
||||
asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg)
|
||||
SYSCALL_DEFINE(semctl)(int semid, int semnum, int cmd, union semun arg)
|
||||
{
|
||||
int err = -EINVAL;
|
||||
int version;
|
||||
|
@ -923,6 +923,13 @@ asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg)
|
|||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
|
||||
asmlinkage long SyS_semctl(int semid, int semnum, int cmd, union semun arg)
|
||||
{
|
||||
return SYSC_semctl((int) semid, (int) semnum, (int) cmd, arg);
|
||||
}
|
||||
SYSCALL_ALIAS(sys_semctl, SyS_semctl);
|
||||
#endif
|
||||
|
||||
/* If the task doesn't already have a undo_list, then allocate one
|
||||
* here. We guarantee there is only one thread using this undo list,
|
||||
|
|
18
mm/fadvise.c
18
mm/fadvise.c
|
@ -24,7 +24,7 @@
|
|||
* POSIX_FADV_WILLNEED could set PG_Referenced, and POSIX_FADV_NOREUSE could
|
||||
* deactivate the pages and clear PG_Referenced.
|
||||
*/
|
||||
asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
|
||||
SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice)
|
||||
{
|
||||
struct file *file = fget(fd);
|
||||
struct address_space *mapping;
|
||||
|
@ -126,12 +126,26 @@ out:
|
|||
fput(file);
|
||||
return ret;
|
||||
}
|
||||
#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
|
||||
asmlinkage long SyS_fadvise64_64(long fd, loff_t offset, loff_t len, long advice)
|
||||
{
|
||||
return SYSC_fadvise64_64((int) fd, offset, len, (int) advice);
|
||||
}
|
||||
SYSCALL_ALIAS(sys_fadvise64_64, SyS_fadvise64_64);
|
||||
#endif
|
||||
|
||||
#ifdef __ARCH_WANT_SYS_FADVISE64
|
||||
|
||||
asmlinkage long sys_fadvise64(int fd, loff_t offset, size_t len, int advice)
|
||||
SYSCALL_DEFINE(fadvise64)(int fd, loff_t offset, size_t len, int advice)
|
||||
{
|
||||
return sys_fadvise64_64(fd, offset, len, advice);
|
||||
}
|
||||
#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
|
||||
asmlinkage long SyS_fadvise64(long fd, loff_t offset, long len, long advice)
|
||||
{
|
||||
return SYSC_fadvise64((int) fd, offset, (size_t)len, (int)advice);
|
||||
}
|
||||
SYSCALL_ALIAS(sys_fadvise64, SyS_fadvise64);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1374,7 +1374,7 @@ do_readahead(struct address_space *mapping, struct file *filp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
asmlinkage long sys_readahead(int fd, loff_t offset, size_t count)
|
||||
SYSCALL_DEFINE(readahead)(int fd, loff_t offset, size_t count)
|
||||
{
|
||||
ssize_t ret;
|
||||
struct file *file;
|
||||
|
@ -1393,6 +1393,13 @@ asmlinkage long sys_readahead(int fd, loff_t offset, size_t count)
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
|
||||
asmlinkage long SyS_readahead(long fd, loff_t offset, long count)
|
||||
{
|
||||
return SYSC_readahead((int) fd, offset, (size_t) count);
|
||||
}
|
||||
SYSCALL_ALIAS(sys_readahead, SyS_readahead);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue