Commit 93f30c73 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
  ...
parents 06ede5f6 96271654
Loading
Loading
Loading
Loading
+4 −33
Original line number Diff line number Diff line
@@ -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 */
+3 −6
Original line number Diff line number Diff line
@@ -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
	{	
+0 −13
Original line number Diff line number Diff line
@@ -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)
+0 −2
Original line number Diff line number Diff line
@@ -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);
+2 −29
Original line number Diff line number Diff line
@@ -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)
Loading