Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/s390/linux

Pull second set of s390 patches from Martin Schwidefsky:
 "The main part of this merge are Heikos uaccess patches.  Together with
  commit 0988496 ("mm: do not grow the stack vma just because of an
  overrun on preceding vma") the user string access is hopefully fixed
  for good.

  In addition some bug fixes and two cleanup patches."

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
  s390/module: fix compile warning
  qdio: remove unused parameters
  s390/uaccess: fix kernel ds access for page table walk
  s390/uaccess: fix strncpy_from_user string length check
  input: disable i8042 PC Keyboard controller for s390
  s390/dis: Fix invalid array size
  s390/uaccess: remove pointless access_ok() checks
  s390/uaccess: fix strncpy_from_user/strnlen_user zero maxlen case
  s390/uaccess: shorten strncpy_from_user/strnlen_user
  s390/dasd: fix unresponsive device after all channel paths were lost
  s390/mm: ignore change bit for vmemmap
  s390/page table dumper: add support for change-recording override bit
  • Loading branch information
torvalds committed Mar 3, 2013
2 parents 6977c6f + 72a6b43 commit 530ede1
Show file tree
Hide file tree
Showing 17 changed files with 172 additions and 144 deletions.
6 changes: 0 additions & 6 deletions arch/s390/include/asm/futex.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;

if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32)))
return -EFAULT;

pagefault_disable();
ret = uaccess.futex_atomic_op(op, uaddr, oparg, &oldval);
pagefault_enable();
Expand All @@ -40,9 +37,6 @@ static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
u32 oldval, u32 newval)
{
if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32)))
return -EFAULT;

return uaccess.futex_atomic_cmpxchg(uval, uaddr, oldval, newval);
}

Expand Down
2 changes: 2 additions & 0 deletions arch/s390/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,8 @@ extern unsigned long MODULES_END;
#define _REGION3_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_INV)

#define _REGION3_ENTRY_LARGE 0x400 /* RTTE-format control, large page */
#define _REGION3_ENTRY_RO 0x200 /* page protection bit */
#define _REGION3_ENTRY_CO 0x100 /* change-recording override */

/* Bits in the segment table entry */
#define _SEGMENT_ENTRY_ORIGIN ~0x7ffUL/* segment table origin */
Expand Down
23 changes: 5 additions & 18 deletions arch/s390/include/asm/uaccess.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,9 +252,7 @@ static inline unsigned long __must_check
copy_to_user(void __user *to, const void *from, unsigned long n)
{
might_fault();
if (access_ok(VERIFY_WRITE, to, n))
n = __copy_to_user(to, from, n);
return n;
return __copy_to_user(to, from, n);
}

/**
Expand Down Expand Up @@ -315,11 +313,7 @@ copy_from_user(void *to, const void __user *from, unsigned long n)
copy_from_user_overflow();
return n;
}
if (access_ok(VERIFY_READ, from, n))
n = __copy_from_user(to, from, n);
else
memset(to, 0, n);
return n;
return __copy_from_user(to, from, n);
}

static inline unsigned long __must_check
Expand All @@ -332,9 +326,7 @@ static inline unsigned long __must_check
copy_in_user(void __user *to, const void __user *from, unsigned long n)
{
might_fault();
if (__access_ok(from,n) && __access_ok(to,n))
n = __copy_in_user(to, from, n);
return n;
return __copy_in_user(to, from, n);
}

/*
Expand All @@ -343,11 +335,8 @@ copy_in_user(void __user *to, const void __user *from, unsigned long n)
static inline long __must_check
strncpy_from_user(char *dst, const char __user *src, long count)
{
long res = -EFAULT;
might_fault();
if (access_ok(VERIFY_READ, src, 1))
res = uaccess.strncpy_from_user(count, src, dst);
return res;
return uaccess.strncpy_from_user(count, src, dst);
}

static inline unsigned long
Expand Down Expand Up @@ -387,9 +376,7 @@ static inline unsigned long __must_check
clear_user(void __user *to, unsigned long n)
{
might_fault();
if (access_ok(VERIFY_WRITE, to, n))
n = uaccess.clear_user(n, to);
return n;
return uaccess.clear_user(n, to);
}

extern int copy_to_user_real(void __user *dest, void *src, size_t count);
Expand Down
14 changes: 0 additions & 14 deletions arch/s390/kernel/compat_signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,6 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
{
int err;

if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
return -EFAULT;

/* If you change siginfo_t structure, please be sure
this code is fixed accordingly.
It should never copy any pad contained in the structure
Expand Down Expand Up @@ -110,9 +107,6 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
int err;
u32 tmp;

if (!access_ok (VERIFY_READ, from, sizeof(compat_siginfo_t)))
return -EFAULT;

err = __get_user(to->si_signo, &from->si_signo);
err |= __get_user(to->si_errno, &from->si_errno);
err |= __get_user(to->si_code, &from->si_code);
Expand Down Expand Up @@ -244,8 +238,6 @@ asmlinkage long sys32_sigreturn(void)
sigframe32 __user *frame = (sigframe32 __user *)regs->gprs[15];
sigset_t set;

if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32))
goto badframe;
set_current_blocked(&set);
Expand All @@ -265,8 +257,6 @@ asmlinkage long sys32_rt_sigreturn(void)
rt_sigframe32 __user *frame = (rt_sigframe32 __user *)regs->gprs[15];
sigset_t set;

if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
goto badframe;
set_current_blocked(&set);
Expand Down Expand Up @@ -325,8 +315,6 @@ static int setup_frame32(int sig, struct k_sigaction *ka,
sigset_t *set, struct pt_regs * regs)
{
sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(sigframe32));
if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe32)))
goto give_sigsegv;

if (frame == (void __user *) -1UL)
goto give_sigsegv;
Expand Down Expand Up @@ -391,8 +379,6 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
{
int err = 0;
rt_sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(rt_sigframe32));
if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe32)))
goto give_sigsegv;

if (frame == (void __user *) -1UL)
goto give_sigsegv;
Expand Down
4 changes: 2 additions & 2 deletions arch/s390/kernel/dis.c
Original file line number Diff line number Diff line change
Expand Up @@ -1711,10 +1711,10 @@ int insn_to_mnemonic(unsigned char *instruction, char buf[8])
if (!insn)
return -ENOENT;
if (insn->name[0] == '\0')
snprintf(buf, sizeof(buf), "%s",
snprintf(buf, 8, "%s",
long_insn_name[(int) insn->name[1]]);
else
snprintf(buf, sizeof(buf), "%.5s", insn->name);
snprintf(buf, 8, "%.5s", insn->name);
return 0;
}
EXPORT_SYMBOL_GPL(insn_to_mnemonic);
Expand Down
2 changes: 1 addition & 1 deletion arch/s390/kernel/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
struct mod_arch_syminfo *info;
Elf_Addr loc, val;
int r_type, r_sym;
int rc;
int rc = -ENOEXEC;

/* This is where to make the change */
loc = base + rela->r_offset;
Expand Down
8 changes: 0 additions & 8 deletions arch/s390/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,6 @@ SYSCALL_DEFINE0(sigreturn)
sigframe __user *frame = (sigframe __user *)regs->gprs[15];
sigset_t set;

if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE))
goto badframe;
set_current_blocked(&set);
Expand All @@ -135,8 +133,6 @@ SYSCALL_DEFINE0(rt_sigreturn)
rt_sigframe __user *frame = (rt_sigframe __user *)regs->gprs[15];
sigset_t set;

if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
if (__copy_from_user(&set.sig, &frame->uc.uc_sigmask, sizeof(set)))
goto badframe;
set_current_blocked(&set);
Expand Down Expand Up @@ -195,8 +191,6 @@ static int setup_frame(int sig, struct k_sigaction *ka,
sigframe __user *frame;

frame = get_sigframe(ka, regs, sizeof(sigframe));
if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe)))
goto give_sigsegv;

if (frame == (void __user *) -1UL)
goto give_sigsegv;
Expand Down Expand Up @@ -264,8 +258,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
rt_sigframe __user *frame;

frame = get_sigframe(ka, regs, sizeof(rt_sigframe));
if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe)))
goto give_sigsegv;

if (frame == (void __user *) -1UL)
goto give_sigsegv;
Expand Down
26 changes: 14 additions & 12 deletions arch/s390/lib/uaccess_mvcos.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,38 +162,40 @@ static size_t clear_user_mvcos(size_t size, void __user *to)

static size_t strnlen_user_mvcos(size_t count, const char __user *src)
{
size_t done, len, offset, len_str;
char buf[256];
int rc;
size_t done, len, len_str;

done = 0;
do {
len = min(count - done, (size_t) 256);
rc = uaccess.copy_from_user(len, src + done, buf);
if (unlikely(rc == len))
offset = (size_t)src & ~PAGE_MASK;
len = min(256UL, PAGE_SIZE - offset);
len = min(count - done, len);
if (copy_from_user_mvcos(len, src, buf))
return 0;
len -= rc;
len_str = strnlen(buf, len);
done += len_str;
src += len_str;
} while ((len_str == len) && (done < count));
return done + 1;
}

static size_t strncpy_from_user_mvcos(size_t count, const char __user *src,
char *dst)
{
int rc;
size_t done, len, len_str;
size_t done, len, offset, len_str;

if (unlikely(!count))
return 0;
done = 0;
do {
len = min(count - done, (size_t) 4096);
rc = uaccess.copy_from_user(len, src + done, dst);
if (unlikely(rc == len))
offset = (size_t)src & ~PAGE_MASK;
len = min(count - done, PAGE_SIZE - offset);
if (copy_from_user_mvcos(len, src, dst))
return -EFAULT;
len -= rc;
len_str = strnlen(dst, len);
done += len_str;
src += len_str;
dst += len_str;
} while ((len_str == len) && (done < count));
return done;
}
Expand Down
Loading

0 comments on commit 530ede1

Please sign in to comment.