Skip to content

Commit

Permalink
Merge branch 'misc.compat' of git://git.kernel.org/pub/scm/linux/kern…
Browse files Browse the repository at this point in the history
…el/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
  ...
  • Loading branch information
torvalds committed Nov 17, 2017
2 parents 06ede5f + 9627165 commit 93f30c7
Show file tree
Hide file tree
Showing 32 changed files with 508 additions and 821 deletions.
37 changes: 4 additions & 33 deletions arch/mips/include/asm/compat-signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
9 changes: 3 additions & 6 deletions arch/parisc/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand All @@ -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
{
Expand Down Expand Up @@ -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));
Expand All @@ -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
{
Expand Down
13 changes: 0 additions & 13 deletions arch/parisc/kernel/signal32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 0 additions & 2 deletions arch/parisc/kernel/signal32.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
31 changes: 2 additions & 29 deletions arch/powerpc/kernel/signal_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
33 changes: 7 additions & 26 deletions arch/s390/kernel/compat_signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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))
Expand All @@ -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;
Expand Down Expand Up @@ -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;

Expand All @@ -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 */
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down
9 changes: 2 additions & 7 deletions arch/sparc/kernel/signal32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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;
Expand All @@ -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:
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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,
Expand Down
8 changes: 3 additions & 5 deletions arch/sparc/kernel/sys_sparc32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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);
Expand All @@ -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)
Expand Down
6 changes: 0 additions & 6 deletions drivers/char/ipmi/bt-bmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,6 @@ static ssize_t bt_bmc_read(struct file *file, char __user *buf,
ssize_t ret = 0;
ssize_t nread;

if (!access_ok(VERIFY_WRITE, buf, count))
return -EFAULT;

WARN_ON(*ppos);

if (wait_event_interruptible(bt_bmc->queue,
Expand Down Expand Up @@ -277,9 +274,6 @@ static ssize_t bt_bmc_write(struct file *file, const char __user *buf,
if (count < 5)
return -EINVAL;

if (!access_ok(VERIFY_READ, buf, count))
return -EFAULT;

WARN_ON(*ppos);

/*
Expand Down
4 changes: 4 additions & 0 deletions drivers/gpu/drm/r128/r128_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ extern int r128_engine_reset(struct drm_device *dev, void *data, struct drm_file
extern int r128_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int r128_cce_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv);

extern int r128_cce_stipple(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int r128_cce_depth(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int r128_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv);

extern void r128_freelist_reset(struct drm_device *dev);

extern int r128_wait_ring(drm_r128_private_t *dev_priv, int n);
Expand Down
Loading

0 comments on commit 93f30c7

Please sign in to comment.