Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dbda6ac0 authored by Ralf Baechle's avatar Ralf Baechle
Browse files

MIPS: CVE-2009-0029: Enable syscall wrappers.



Thanks to David Daney helping with debugging and testing.

Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
Signed-off-by: default avatarDavid Daney <ddaney@caviumnetworks.com>
parent 4b0d3f5c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1391,6 +1391,7 @@ config 32BIT
config 64BIT
	bool "64-bit kernel"
	depends on CPU_SUPPORTS_64BIT_KERNEL && SYS_SUPPORTS_64BIT_KERNEL
	select HAVE_SYSCALL_WRAPPERS
	help
	  Select this option if you want to build a 64-bit kernel.

+39 −30
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include <linux/module.h>
#include <linux/binfmts.h>
#include <linux/security.h>
#include <linux/syscalls.h>
#include <linux/compat.h>
#include <linux/vfs.h>
#include <linux/ipc.h>
@@ -63,9 +64,9 @@
#define merge_64(r1, r2) ((((r2) & 0xffffffffUL) << 32) + ((r1) & 0xffffffffUL))
#endif

asmlinkage unsigned long
sys32_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
         unsigned long flags, unsigned long fd, unsigned long pgoff)
SYSCALL_DEFINE6(32_mmap2, unsigned long, addr, unsigned long, len,
	unsigned long, prot, unsigned long, flags, unsigned long, fd,
	unsigned long, pgoff)
{
	struct file * file = NULL;
	unsigned long error;
@@ -121,21 +122,21 @@ struct rlimit32 {
	int	rlim_max;
};

asmlinkage long sys32_truncate64(const char __user * path,
	unsigned long __dummy, int a2, int a3)
SYSCALL_DEFINE4(32_truncate64, const char __user *, path,
	unsigned long, __dummy, unsigned long, a2, unsigned long, a3)
{
	return sys_truncate(path, merge_64(a2, a3));
}

asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy,
	int a2, int a3)
SYSCALL_DEFINE4(32_ftruncate64, unsigned long, fd, unsigned long, __dummy,
	unsigned long, a2, unsigned long, a3)
{
	return sys_ftruncate(fd, merge_64(a2, a3));
}

asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high,
			    unsigned int offset_low, loff_t __user * result,
			    unsigned int origin)
SYSCALL_DEFINE5(32_llseek, unsigned long, fd, unsigned long, offset_high,
	unsigned long, offset_low, loff_t __user *, result,
	unsigned long, origin)
{
	return sys_llseek(fd, offset_high, offset_low, result, origin);
}
@@ -144,20 +145,20 @@ asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high,
   lseek back to original location.  They fail just like lseek does on
   non-seekable files.  */

asmlinkage ssize_t sys32_pread(unsigned int fd, char __user * buf,
			       size_t count, u32 unused, u64 a4, u64 a5)
SYSCALL_DEFINE6(32_pread, unsigned long, fd, char __user *, buf, size_t, count,
	unsigned long, unused, unsigned long, a4, unsigned long, a5)
{
	return sys_pread64(fd, buf, count, merge_64(a4, a5));
}

asmlinkage ssize_t sys32_pwrite(unsigned int fd, const char __user * buf,
			        size_t count, u32 unused, u64 a4, u64 a5)
SYSCALL_DEFINE6(32_pwrite, unsigned int, fd, const char __user *, buf,
	size_t, count, u32, unused, u64, a4, u64, a5)
{
	return sys_pwrite64(fd, buf, count, merge_64(a4, a5));
}

asmlinkage int sys32_sched_rr_get_interval(compat_pid_t pid,
	struct compat_timespec __user *interval)
SYSCALL_DEFINE2(32_sched_rr_get_interval, compat_pid_t, pid,
	struct compat_timespec __user *, interval)
{
	struct timespec t;
	int ret;
@@ -174,8 +175,8 @@ asmlinkage int sys32_sched_rr_get_interval(compat_pid_t pid,

#ifdef CONFIG_SYSVIPC

asmlinkage long
sys32_ipc(u32 call, int first, int second, int third, u32 ptr, u32 fifth)
SYSCALL_DEFINE6(32_ipc, u32, call, long, first, long, second, long, third,
	unsigned long, ptr, unsigned long, fifth)
{
	int version, err;

@@ -233,8 +234,8 @@ sys32_ipc(u32 call, int first, int second, int third, u32 ptr, u32 fifth)

#else

asmlinkage long
sys32_ipc(u32 call, int first, int second, int third, u32 ptr, u32 fifth)
SYSCALL_DEFINE6(32_ipc, u32, call, int, first, int, second, int, third,
	u32, ptr, u32 fifth)
{
	return -ENOSYS;
}
@@ -242,7 +243,7 @@ sys32_ipc(u32 call, int first, int second, int third, u32 ptr, u32 fifth)
#endif /* CONFIG_SYSVIPC */

#ifdef CONFIG_MIPS32_N32
asmlinkage long sysn32_semctl(int semid, int semnum, int cmd, u32 arg)
SYSCALL_DEFINE4(n32_semctl, int, semid, int, semnum, int, cmd, u32, arg)
{
	/* compat_sys_semctl expects a pointer to union semun */
	u32 __user *uptr = compat_alloc_user_space(sizeof(u32));
@@ -251,13 +252,14 @@ asmlinkage long sysn32_semctl(int semid, int semnum, int cmd, u32 arg)
	return compat_sys_semctl(semid, semnum, cmd, uptr);
}

asmlinkage long sysn32_msgsnd(int msqid, u32 msgp, unsigned msgsz, int msgflg)
SYSCALL_DEFINE4(n32_msgsnd, int, msqid, u32, msgp, unsigned int, msgsz,
	int, msgflg)
{
	return compat_sys_msgsnd(msqid, msgsz, msgflg, compat_ptr(msgp));
}

asmlinkage long sysn32_msgrcv(int msqid, u32 msgp, size_t msgsz, int msgtyp,
			      int msgflg)
SYSCALL_DEFINE5(n32_msgrcv, int, msqid, u32, msgp, size_t, msgsz,
	int, msgtyp, int, msgflg)
{
	return compat_sys_msgrcv(msqid, msgsz, msgtyp, msgflg, IPC_64,
				 compat_ptr(msgp));
@@ -277,7 +279,7 @@ struct sysctl_args32

#ifdef CONFIG_SYSCTL_SYSCALL

asmlinkage long sys32_sysctl(struct sysctl_args32 __user *args)
SYSCALL_DEFINE1(32_sysctl, struct sysctl_args32 __user *, args)
{
	struct sysctl_args32 tmp;
	int error;
@@ -316,9 +318,16 @@ asmlinkage long sys32_sysctl(struct sysctl_args32 __user *args)
	return error;
}

#else

SYSCALL_DEFINE1(32_sysctl, struct sysctl_args32 __user *, args)
{
	return -ENOSYS;
}

#endif /* CONFIG_SYSCTL_SYSCALL */

asmlinkage long sys32_newuname(struct new_utsname __user * name)
SYSCALL_DEFINE1(32_newuname, struct new_utsname __user *, name)
{
	int ret = 0;

@@ -334,7 +343,7 @@ asmlinkage long sys32_newuname(struct new_utsname __user * name)
	return ret;
}

asmlinkage int sys32_personality(unsigned long personality)
SYSCALL_DEFINE1(32_personality, unsigned long, personality)
{
	int ret;
	personality &= 0xffffffff;
@@ -357,7 +366,7 @@ struct ustat32 {

extern asmlinkage long sys_ustat(dev_t dev, struct ustat __user * ubuf);

asmlinkage int sys32_ustat(dev_t dev, struct ustat32 __user * ubuf32)
SYSCALL_DEFINE2(32_ustat, dev_t, dev, struct ustat32 __user *, ubuf32)
{
	int err;
	struct ustat tmp;
@@ -381,8 +390,8 @@ asmlinkage int sys32_ustat(dev_t dev, struct ustat32 __user * ubuf32)
	return err;
}

asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset,
	s32 count)
SYSCALL_DEFINE4(32_sendfile, long, out_fd, long, in_fd,
	compat_off_t __user *, offset, s32, count)
{
	mm_segment_t old_fs = get_fs();
	int ret;
+2 −2
Original line number Diff line number Diff line
@@ -399,7 +399,7 @@ einval: li v0, -ENOSYS
	sys	sys_swapon		2
	sys	sys_reboot		3
	sys	sys_old_readdir		3
	sys	old_mmap		6	/* 4090 */
	sys	sys_mips_mmap		6	/* 4090 */
	sys	sys_munmap		2
	sys	sys_truncate		2
	sys	sys_ftruncate		2
@@ -519,7 +519,7 @@ einval: li v0, -ENOSYS
	sys	sys_sendfile		4
	sys	sys_ni_syscall		0
	sys	sys_ni_syscall		0
	sys	sys_mmap2		6	/* 4210 */
	sys	sys_mips_mmap2		6	/* 4210 */
	sys	sys_truncate64		4
	sys	sys_ftruncate64		4
	sys	sys_stat64		2
+1 −1
Original line number Diff line number Diff line
@@ -207,7 +207,7 @@ sys_call_table:
	PTR	sys_newlstat
	PTR	sys_poll
	PTR	sys_lseek
	PTR	old_mmap
	PTR	sys_mips_mmap
	PTR	sys_mprotect			/* 5010 */
	PTR	sys_munmap
	PTR	sys_brk
+14 −14
Original line number Diff line number Diff line
@@ -129,12 +129,12 @@ EXPORT(sysn32_call_table)
	PTR	sys_newlstat
	PTR	sys_poll
	PTR	sys_lseek
	PTR	old_mmap
	PTR	sys_mips_mmap
	PTR	sys_mprotect			/* 6010 */
	PTR	sys_munmap
	PTR	sys_brk
	PTR	sys32_rt_sigaction
	PTR	sys32_rt_sigprocmask
	PTR	sys_32_rt_sigaction
	PTR	sys_32_rt_sigprocmask
	PTR	compat_sys_ioctl		/* 6015 */
	PTR	sys_pread64
	PTR	sys_pwrite64
@@ -159,7 +159,7 @@ EXPORT(sysn32_call_table)
	PTR	compat_sys_setitimer
	PTR	sys_alarm
	PTR	sys_getpid
	PTR	sys32_sendfile
	PTR	sys_32_sendfile
	PTR	sys_socket			/* 6040 */
	PTR	sys_connect
	PTR	sys_accept
@@ -181,14 +181,14 @@ EXPORT(sysn32_call_table)
	PTR	sys_exit
	PTR	compat_sys_wait4
	PTR	sys_kill			/* 6060 */
	PTR	sys32_newuname
	PTR	sys_32_newuname
	PTR	sys_semget
	PTR	sys_semop
	PTR	sysn32_semctl
	PTR	sys_n32_semctl
	PTR	sys_shmdt			/* 6065 */
	PTR	sys_msgget
	PTR	sysn32_msgsnd
	PTR	sysn32_msgrcv
	PTR	sys_n32_msgsnd
	PTR	sys_n32_msgrcv
	PTR	compat_sys_msgctl
	PTR	compat_sys_fcntl		/* 6070 */
	PTR	sys_flock
@@ -245,15 +245,15 @@ EXPORT(sysn32_call_table)
	PTR	sys_getsid
	PTR	sys_capget
	PTR	sys_capset
	PTR	sys32_rt_sigpending		/* 6125 */
	PTR	sys_32_rt_sigpending		/* 6125 */
	PTR	compat_sys_rt_sigtimedwait
	PTR	sys32_rt_sigqueueinfo
	PTR	sys_32_rt_sigqueueinfo
	PTR	sysn32_rt_sigsuspend
	PTR	sys32_sigaltstack
	PTR	compat_sys_utime		/* 6130 */
	PTR	sys_mknod
	PTR	sys32_personality
	PTR	sys32_ustat
	PTR	sys_32_personality
	PTR	sys_32_ustat
	PTR	compat_sys_statfs
	PTR	compat_sys_fstatfs		/* 6135 */
	PTR	sys_sysfs
@@ -265,14 +265,14 @@ EXPORT(sysn32_call_table)
	PTR	sys_sched_getscheduler
	PTR	sys_sched_get_priority_max
	PTR	sys_sched_get_priority_min
	PTR	sys32_sched_rr_get_interval	/* 6145 */
	PTR	sys_32_sched_rr_get_interval	/* 6145 */
	PTR	sys_mlock
	PTR	sys_munlock
	PTR	sys_mlockall
	PTR	sys_munlockall
	PTR	sys_vhangup			/* 6150 */
	PTR	sys_pivot_root
	PTR	sys32_sysctl
	PTR	sys_32_sysctl
	PTR	sys_prctl
	PTR	compat_sys_adjtimex
	PTR	compat_sys_setrlimit		/* 6155 */
Loading