summary refs log tree commit diff
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-11-17 11:54:55 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2017-11-17 11:54:55 -0800
commit93f30c73ecd0281cf3685ef0e4e384980a176176 (patch)
treebd272334a0dbd258c08b5b2237e8bf5e17ce7255 /arch
parent06ede5f6086757f746b7be860ae76137f4e95032 (diff)
parent96271654f55c74ff7325fbdfc535466c9deb0ce6 (diff)
downloadlinux-93f30c73ecd0281cf3685ef0e4e384980a176176.tar.gz
Merge branch 'misc.compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull compat and uaccess updates from Al Viro:

 - {get,put}_compat_sigset() series

 - assorted compat ioctl stuff

 - more set_fs() elimination

 - a few more timespec64 conversions

 - several removals of pointless access_ok() in places where it was
   followed only by non-__ variants of primitives

* 'misc.compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (24 commits)
  coredump: call do_unlinkat directly instead of sys_unlink
  fs: expose do_unlinkat for built-in callers
  ext4: take handling of EXT4_IOC_GROUP_ADD into a helper, get rid of set_fs()
  ipmi: get rid of pointless access_ok()
  pi433: sanitize ioctl
  cxlflash: get rid of pointless access_ok()
  mtdchar: get rid of pointless access_ok()
  r128: switch compat ioctls to drm_ioctl_kernel()
  selection: get rid of field-by-field copyin
  VT_RESIZEX: get rid of field-by-field copyin
  i2c compat ioctls: move to ->compat_ioctl()
  sched_rr_get_interval(): move compat to native, get rid of set_fs()
  mips: switch to {get,put}_compat_sigset()
  sparc: switch to {get,put}_compat_sigset()
  s390: switch to {get,put}_compat_sigset()
  ppc: switch to {get,put}_compat_sigset()
  parisc: switch to {get,put}_compat_sigset()
  get_compat_sigset()
  get rid of {get,put}_compat_itimerspec()
  io_getevents: Use timespec64 to represent timeouts
  ...
Diffstat (limited to 'arch')
-rw-r--r--arch/mips/include/asm/compat-signal.h37
-rw-r--r--arch/parisc/kernel/signal.c9
-rw-r--r--arch/parisc/kernel/signal32.c13
-rw-r--r--arch/parisc/kernel/signal32.h2
-rw-r--r--arch/powerpc/kernel/signal_32.c31
-rw-r--r--arch/s390/kernel/compat_signal.c33
-rw-r--r--arch/sparc/kernel/signal32.c9
-rw-r--r--arch/sparc/kernel/sys_sparc32.c8
8 files changed, 21 insertions, 121 deletions
diff --git a/arch/mips/include/asm/compat-signal.h b/arch/mips/include/asm/compat-signal.h
index e87cd243b0f4..c3b7a2550d1d 100644
--- a/arch/mips/include/asm/compat-signal.h
+++ b/arch/mips/include/asm/compat-signal.h
@@ -14,45 +14,16 @@
 static inline int __copy_conv_sigset_to_user(compat_sigset_t __user *d,
 	const sigset_t *s)
 {
-	int err;
+	BUILD_BUG_ON(sizeof(*d) != sizeof(*s));
+	BUILD_BUG_ON(_NSIG_WORDS != 2);
 
-	BUG_ON(sizeof(*d) != sizeof(*s));
-	BUG_ON(_NSIG_WORDS != 2);
-
-	err  = __put_user(s->sig[0],	   &d->sig[0]);
-	err |= __put_user(s->sig[0] >> 32, &d->sig[1]);
-	err |= __put_user(s->sig[1],	   &d->sig[2]);
-	err |= __put_user(s->sig[1] >> 32, &d->sig[3]);
-
-	return err;
+	return put_compat_sigset(d, s, sizeof(*d));
 }
 
 static inline int __copy_conv_sigset_from_user(sigset_t *d,
 	const compat_sigset_t __user *s)
 {
-	int err;
-	union sigset_u {
-		sigset_t	s;
-		compat_sigset_t c;
-	} *u = (union sigset_u *) d;
-
-	BUG_ON(sizeof(*d) != sizeof(*s));
-	BUG_ON(_NSIG_WORDS != 2);
-
-#ifdef CONFIG_CPU_BIG_ENDIAN
-	err  = __get_user(u->c.sig[1], &s->sig[0]);
-	err |= __get_user(u->c.sig[0], &s->sig[1]);
-	err |= __get_user(u->c.sig[3], &s->sig[2]);
-	err |= __get_user(u->c.sig[2], &s->sig[3]);
-#endif
-#ifdef CONFIG_CPU_LITTLE_ENDIAN
-	err  = __get_user(u->c.sig[0], &s->sig[0]);
-	err |= __get_user(u->c.sig[1], &s->sig[1]);
-	err |= __get_user(u->c.sig[2], &s->sig[2]);
-	err |= __get_user(u->c.sig[3], &s->sig[3]);
-#endif
-
-	return err;
+	return get_compat_sigset(d, s);
 }
 
 #endif /* __ASM_COMPAT_SIGNAL_H */
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index f2a4038e275b..342073f44d3f 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -93,7 +93,6 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
 	unsigned long usp = (regs->gr[30] & ~(0x01UL));
 	unsigned long sigframe_size = PARISC_RT_SIGFRAME_SIZE;
 #ifdef CONFIG_64BIT
-	compat_sigset_t compat_set;
 	struct compat_rt_sigframe __user * compat_frame;
 	
 	if (is_compat_task())
@@ -114,9 +113,8 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
 	
 	if (is_compat_task()) {
 		DBG(2,"sys_rt_sigreturn: ELF32 process.\n");
-		if (__copy_from_user(&compat_set, &compat_frame->uc.uc_sigmask, sizeof(compat_set)))
+		if (get_compat_sigset(&set, &compat_frame->uc.uc_sigmask))
 			goto give_sigsegv;
-		sigset_32to64(&set,&compat_set);
 	} else
 #endif
 	{
@@ -238,7 +236,6 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
 	int err = 0;
 #ifdef CONFIG_64BIT
 	struct compat_rt_sigframe __user * compat_frame;
-	compat_sigset_t compat_set;
 #endif
 	
 	usp = (regs->gr[30] & ~(0x01UL));
@@ -261,8 +258,8 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
 		DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &compat_frame->uc.uc_mcontext);
 		err |= setup_sigcontext32(&compat_frame->uc.uc_mcontext, 
 					&compat_frame->regs, regs, in_syscall);
-		sigset_64to32(&compat_set,set);
-		err |= __copy_to_user(&compat_frame->uc.uc_sigmask, &compat_set, sizeof(compat_set));
+		err |= put_compat_sigset(&compat_frame->uc.uc_sigmask, set,
+					 sizeof(compat_sigset_t));
 	} else
 #endif
 	{	
diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c
index 9e0cb6a577d6..41afa9cd1f55 100644
--- a/arch/parisc/kernel/signal32.c
+++ b/arch/parisc/kernel/signal32.c
@@ -46,19 +46,6 @@
 #define DBG(LEVEL, ...)
 #endif
 
-inline void
-sigset_32to64(sigset_t *s64, compat_sigset_t *s32)
-{
-	s64->sig[0] = s32->sig[0] | ((unsigned long)s32->sig[1] << 32);
-}
-
-inline void
-sigset_64to32(compat_sigset_t *s32, sigset_t *s64)
-{
-	s32->sig[0] = s64->sig[0] & 0xffffffffUL;
-	s32->sig[1] = (s64->sig[0] >> 32) & 0xffffffffUL;
-}
-
 long
 restore_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
 		struct pt_regs *regs)
diff --git a/arch/parisc/kernel/signal32.h b/arch/parisc/kernel/signal32.h
index af51d4ccee42..719e7417732c 100644
--- a/arch/parisc/kernel/signal32.h
+++ b/arch/parisc/kernel/signal32.h
@@ -79,8 +79,6 @@ struct compat_rt_sigframe {
 #define FUNCTIONCALLFRAME32     48
 #define PARISC_RT_SIGFRAME_SIZE32 (((sizeof(struct compat_rt_sigframe) + FUNCTIONCALLFRAME32) + SIGFRAME32) & -SIGFRAME32)
 
-void sigset_32to64(sigset_t *s64, compat_sigset_t *s32);
-void sigset_64to32(compat_sigset_t *s32, sigset_t *s64);
 long restore_sigcontext32(struct compat_sigcontext __user *sc, 
 		struct compat_regfile __user *rf,
 		struct pt_regs *regs);
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 16d16583cf11..9ffd73296f64 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -94,40 +94,13 @@
  */
 static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set)
 {
-	compat_sigset_t	cset;
-
-	switch (_NSIG_WORDS) {
-	case 4: cset.sig[6] = set->sig[3] & 0xffffffffull;
-		cset.sig[7] = set->sig[3] >> 32;
-	case 3: cset.sig[4] = set->sig[2] & 0xffffffffull;
-		cset.sig[5] = set->sig[2] >> 32;
-	case 2: cset.sig[2] = set->sig[1] & 0xffffffffull;
-		cset.sig[3] = set->sig[1] >> 32;
-	case 1: cset.sig[0] = set->sig[0] & 0xffffffffull;
-		cset.sig[1] = set->sig[0] >> 32;
-	}
-	return copy_to_user(uset, &cset, sizeof(*uset));
+	return put_compat_sigset(uset, set, sizeof(*uset));
 }
 
 static inline int get_sigset_t(sigset_t *set,
 			       const compat_sigset_t __user *uset)
 {
-	compat_sigset_t s32;
-
-	if (copy_from_user(&s32, uset, sizeof(*uset)))
-		return -EFAULT;
-
-	/*
-	 * Swap the 2 words of the 64-bit sigset_t (they are stored
-	 * in the "wrong" endian in 32-bit user storage).
-	 */
-	switch (_NSIG_WORDS) {
-	case 4: set->sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
-	case 3: set->sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
-	case 2: set->sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
-	case 1: set->sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
-	}
-	return 0;
+	return get_compat_sigset(set, uset);
 }
 
 #define to_user_ptr(p)		ptr_to_compat(p)
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index a4a1208e3df3..ef246940b44c 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -50,19 +50,6 @@ typedef struct
 	struct ucontext32 uc;
 } rt_sigframe32;
 
-static inline void sigset_to_sigset32(unsigned long *set64,
-				      compat_sigset_word *set32)
-{
-	set32[0] = (compat_sigset_word) set64[0];
-	set32[1] = (compat_sigset_word)(set64[0] >> 32);
-}
-
-static inline void sigset32_to_sigset(compat_sigset_word *set32,
-				      unsigned long *set64)
-{
-	set64[0] = (unsigned long) set32[0] | ((unsigned long) set32[1] << 32);
-}
-
 int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
 {
 	int err;
@@ -294,12 +281,10 @@ COMPAT_SYSCALL_DEFINE0(sigreturn)
 {
 	struct pt_regs *regs = task_pt_regs(current);
 	sigframe32 __user *frame = (sigframe32 __user *)regs->gprs[15];
-	compat_sigset_t cset;
 	sigset_t set;
 
-	if (__copy_from_user(&cset.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32))
+	if (get_compat_sigset(&set, (compat_sigset_t __user *)frame->sc.oldmask))
 		goto badframe;
-	sigset32_to_sigset(cset.sig, set.sig);
 	set_current_blocked(&set);
 	save_fpu_regs();
 	if (restore_sigregs32(regs, &frame->sregs))
@@ -317,12 +302,10 @@ COMPAT_SYSCALL_DEFINE0(rt_sigreturn)
 {
 	struct pt_regs *regs = task_pt_regs(current);
 	rt_sigframe32 __user *frame = (rt_sigframe32 __user *)regs->gprs[15];
-	compat_sigset_t cset;
 	sigset_t set;
 
-	if (__copy_from_user(&cset, &frame->uc.uc_sigmask, sizeof(cset)))
+	if (get_compat_sigset(&set, &frame->uc.uc_sigmask))
 		goto badframe;
-	sigset32_to_sigset(cset.sig, set.sig);
 	set_current_blocked(&set);
 	if (compat_restore_altstack(&frame->uc.uc_stack))
 		goto badframe;
@@ -372,7 +355,6 @@ static int setup_frame32(struct ksignal *ksig, sigset_t *set,
 {
 	int sig = ksig->sig;
 	sigframe32 __user *frame;
-	struct sigcontext32 sc;
 	unsigned long restorer;
 	size_t frame_size;
 
@@ -394,9 +376,10 @@ static int setup_frame32(struct ksignal *ksig, sigset_t *set,
 		return -EFAULT;
 
 	/* Create struct sigcontext32 on the signal stack */
-	sigset_to_sigset32(set->sig, sc.oldmask);
-	sc.sregs = (__u32)(unsigned long __force) &frame->sregs;
-	if (__copy_to_user(&frame->sc, &sc, sizeof(frame->sc)))
+	if (put_compat_sigset((compat_sigset_t __user *)frame->sc.oldmask,
+			      set, sizeof(compat_sigset_t)))
+		return -EFAULT;
+	if (__put_user(ptr_to_compat(&frame->sc), &frame->sc.sregs))
 		return -EFAULT;
 
 	/* Store registers needed to create the signal frame */
@@ -455,7 +438,6 @@ static int setup_frame32(struct ksignal *ksig, sigset_t *set,
 static int setup_rt_frame32(struct ksignal *ksig, sigset_t *set,
 			    struct pt_regs *regs)
 {
-	compat_sigset_t cset;
 	rt_sigframe32 __user *frame;
 	unsigned long restorer;
 	size_t frame_size;
@@ -502,12 +484,11 @@ static int setup_rt_frame32(struct ksignal *ksig, sigset_t *set,
 	store_sigregs();
 
 	/* Create ucontext on the signal stack. */
-	sigset_to_sigset32(set->sig, cset.sig);
 	if (__put_user(uc_flags, &frame->uc.uc_flags) ||
 	    __put_user(0, &frame->uc.uc_link) ||
 	    __compat_save_altstack(&frame->uc.uc_stack, regs->gprs[15]) ||
 	    save_sigregs32(regs, &frame->uc.uc_mcontext) ||
-	    __copy_to_user(&frame->uc.uc_sigmask, &cset, sizeof(cset)) ||
+	    put_compat_sigset(&frame->uc.uc_sigmask, set, sizeof(compat_sigset_t)) ||
 	    save_sigregs_ext32(regs, &frame->uc.uc_mcontext_ext))
 		return -EFAULT;
 
diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c
index 5c572de64c74..54a6159b9cd8 100644
--- a/arch/sparc/kernel/signal32.c
+++ b/arch/sparc/kernel/signal32.c
@@ -249,7 +249,6 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
 	compat_uptr_t fpu_save;
 	compat_uptr_t rwin_save;
 	sigset_t set;
-	compat_sigset_t seta;
 	int err, i;
 	
 	/* Always make any pending restarted system calls return -EINTR */
@@ -312,7 +311,7 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
 	err |= __get_user(fpu_save, &sf->fpu_save);
 	if (!err && fpu_save)
 		err |= restore_fpu_state(regs, compat_ptr(fpu_save));
-	err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t));
+	err |= get_compat_sigset(&set, &sf->mask);
 	err |= compat_restore_altstack(&sf->stack);
 	if (err)
 		goto segv;
@@ -323,7 +322,6 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
 			goto segv;
 	}
 
-	set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32);
 	set_current_blocked(&set);
 	return;
 segv:
@@ -555,7 +553,6 @@ static int setup_rt_frame32(struct ksignal *ksig, struct pt_regs *regs,
 	void __user *tail;
 	int sigframe_size;
 	u32 psr;
-	compat_sigset_t seta;
 
 	/* 1. Make sure everything is clean */
 	synchronize_user_stack();
@@ -625,9 +622,7 @@ static int setup_rt_frame32(struct ksignal *ksig, struct pt_regs *regs,
 	/* Setup sigaltstack */
 	err |= __compat_save_altstack(&sf->stack, regs->u_regs[UREG_FP]);
 
-	seta.sig[1] = (oldset->sig[0] >> 32);
-	seta.sig[0] = oldset->sig[0];
-	err |= __copy_to_user(&sf->mask, &seta, sizeof(compat_sigset_t));
+	err |= put_compat_sigset(&sf->mask, oldset, sizeof(compat_sigset_t));
 
 	if (!wsaved) {
 		err |= copy_in_user((u32 __user *)sf,
diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c
index b4e1478413a1..6d964bdefbaa 100644
--- a/arch/sparc/kernel/sys_sparc32.c
+++ b/arch/sparc/kernel/sys_sparc32.c
@@ -160,7 +160,6 @@ COMPAT_SYSCALL_DEFINE5(rt_sigaction, int, sig,
 {
         struct k_sigaction new_ka, old_ka;
         int ret;
-	compat_sigset_t set32;
 
         /* XXX: Don't preclude handling different sized sigset_t's.  */
         if (sigsetsize != sizeof(compat_sigset_t))
@@ -172,8 +171,7 @@ COMPAT_SYSCALL_DEFINE5(rt_sigaction, int, sig,
 		new_ka.ka_restorer = restorer;
 		ret = get_user(u_handler, &act->sa_handler);
 		new_ka.sa.sa_handler =  compat_ptr(u_handler);
-		ret |= copy_from_user(&set32, &act->sa_mask, sizeof(compat_sigset_t));
-		sigset_from_compat(&new_ka.sa.sa_mask, &set32);
+		ret |= get_compat_sigset(&new_ka.sa.sa_mask, &act->sa_mask);
 		ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags);
 		ret |= get_user(u_restorer, &act->sa_restorer);
 		new_ka.sa.sa_restorer = compat_ptr(u_restorer);
@@ -184,9 +182,9 @@ COMPAT_SYSCALL_DEFINE5(rt_sigaction, int, sig,
 	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
 
 	if (!ret && oact) {
-		sigset_to_compat(&set32, &old_ka.sa.sa_mask);
 		ret = put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler);
-		ret |= copy_to_user(&oact->sa_mask, &set32, sizeof(compat_sigset_t));
+		ret |= put_compat_sigset(&oact->sa_mask, &old_ka.sa.sa_mask,
+					 sizeof(oact->sa_mask));
 		ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags);
 		ret |= put_user(ptr_to_compat(old_ka.sa.sa_restorer), &oact->sa_restorer);
 		if (ret)