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

Commit dc6ec87d authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull parisc fixes from Helge Deller:
 - revert an access_ok() patch which broke 32bit userspace on 64bit
   kernels
 - avoid a gcc miscompilation in two internal pa_memcpy() functions by
   not inlining those
 - do not export the definition of SOCK_NONBLOCK via uapi header (fixes
   build of audit package)
 - depending on the fault type we now correctly report either SIGBUS or
   SIGSEGV
 - a small fix to not compare a size_t variable for < 0

* 'parisc-3.13' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
  parisc: size_t is unsigned, so comparison size < 0 doesn't make sense.
  parisc: improve SIGBUS/SIGSEGV error reporting
  parisc: break out SOCK_NONBLOCK define to own asm header file
  parisc: do not inline pa_memcpy() internal functions
  Revert "parisc: implement full version of access_ok()"
parents 8a60ba0a 964f4133
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
#ifndef _ASM_SOCKET_H
#define _ASM_SOCKET_H

#include <uapi/asm/socket.h>

/* O_NONBLOCK clashes with the bits used for socket types.  Therefore we
 * have to define SOCK_NONBLOCK to a different value here.
 */
#define SOCK_NONBLOCK	0x40000000

#endif /* _ASM_SOCKET_H */
+4 −42
Original line number Diff line number Diff line
@@ -4,14 +4,11 @@
/*
 * User space memory access functions
 */
#include <asm/processor.h>
#include <asm/page.h>
#include <asm/cache.h>
#include <asm/errno.h>
#include <asm-generic/uaccess-unaligned.h>

#include <linux/sched.h>

#define VERIFY_READ 0
#define VERIFY_WRITE 1

@@ -36,43 +33,12 @@ extern int __get_user_bad(void);
extern int __put_kernel_bad(void);
extern int __put_user_bad(void);


/*
 * Test whether a block of memory is a valid user space address.
 * Returns 0 if the range is valid, nonzero otherwise.
 */
static inline int __range_not_ok(unsigned long addr, unsigned long size,
				 unsigned long limit)
static inline long access_ok(int type, const void __user * addr,
		unsigned long size)
{
	unsigned long __newaddr = addr + size;
	return (__newaddr < addr || __newaddr > limit || size > limit);
	return 1;
}

/**
 * access_ok: - Checks if a user space pointer is valid
 * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE.  Note that
 *        %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe
 *        to write to a block, it is always safe to read from it.
 * @addr: User space pointer to start of block to check
 * @size: Size of block to check
 *
 * Context: User context only.  This function may sleep.
 *
 * Checks if a pointer to a block of memory in user space is valid.
 *
 * Returns true (nonzero) if the memory block may be valid, false (zero)
 * if it is definitely invalid.
 *
 * Note that, depending on architecture, this function probably just
 * checks that the pointer is in the user space range - after calling
 * this function, memory access functions may still return -EFAULT.
 */
#define access_ok(type, addr, size)					\
(	__chk_user_ptr(addr),						\
	!__range_not_ok((unsigned long) (__force void *) (addr),	\
			size, user_addr_max())				\
)

#define put_user __put_user
#define get_user __get_user

@@ -253,11 +219,7 @@ extern long lstrnlen_user(const char __user *,long);
/*
 * Complex access routines -- macros
 */
#ifdef CONFIG_COMPAT
#define user_addr_max() (TASK_SIZE)
#else
#define user_addr_max() (DEFAULT_TASK_SIZE)
#endif
#define user_addr_max() (~0UL)

#define strnlen_user lstrnlen_user
#define strlen_user(str) lstrnlen_user(str, 0x7fffffffL)
+3 −8
Original line number Diff line number Diff line
#ifndef _ASM_SOCKET_H
#define _ASM_SOCKET_H
#ifndef _UAPI_ASM_SOCKET_H
#define _UAPI_ASM_SOCKET_H

#include <asm/sockios.h>

@@ -77,9 +77,4 @@

#define SO_MAX_PACING_RATE	0x4048

/* O_NONBLOCK clashes with the bits used for socket types.  Therefore we
 * have to define SOCK_NONBLOCK to a different value here.
 */
#define SOCK_NONBLOCK   0x40000000

#endif /* _ASM_SOCKET_H */
#endif /* _UAPI_ASM_SOCKET_H */
+3 −3
Original line number Diff line number Diff line
@@ -161,7 +161,7 @@ static inline void prefetch_dst(const void *addr)
/* Copy from a not-aligned src to an aligned dst, using shifts. Handles 4 words
 * per loop.  This code is derived from glibc. 
 */
static inline unsigned long copy_dstaligned(unsigned long dst,
static noinline unsigned long copy_dstaligned(unsigned long dst,
					unsigned long src, unsigned long len)
{
	/* gcc complains that a2 and a3 may be uninitialized, but actually
@@ -276,7 +276,7 @@ static inline unsigned long copy_dstaligned(unsigned long dst,
/* Returns PA_MEMCPY_OK, PA_MEMCPY_LOAD_ERROR or PA_MEMCPY_STORE_ERROR.
 * In case of an access fault the faulty address can be read from the per_cpu
 * exception data struct. */
static unsigned long pa_memcpy_internal(void *dstp, const void *srcp,
static noinline unsigned long pa_memcpy_internal(void *dstp, const void *srcp,
					unsigned long len)
{
	register unsigned long src, dst, t1, t2, t3;
@@ -529,7 +529,7 @@ long probe_kernel_read(void *dst, const void *src, size_t size)
{
	unsigned long addr = (unsigned long)src;

	if (size < 0 || addr < PAGE_SIZE)
	if (addr < PAGE_SIZE)
		return -EFAULT;

	/* check for I/O space F_EXTEND(0xfff00000) access as well? */
+20 −2
Original line number Diff line number Diff line
@@ -282,16 +282,34 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
#endif
		switch (code) {
		case 15:	/* Data TLB miss fault/Data page fault */
			/* send SIGSEGV when outside of vma */
			if (!vma ||
			    address < vma->vm_start || address > vma->vm_end) {
				si.si_signo = SIGSEGV;
				si.si_code = SEGV_MAPERR;
				break;
			}

			/* send SIGSEGV for wrong permissions */
			if ((vma->vm_flags & acc_type) != acc_type) {
				si.si_signo = SIGSEGV;
				si.si_code = SEGV_ACCERR;
				break;
			}

			/* probably address is outside of mapped file */
			/* fall through */
		case 17:	/* NA data TLB miss / page fault */
		case 18:	/* Unaligned access - PCXS only */
			si.si_signo = SIGBUS;
			si.si_code = BUS_ADRERR;
			si.si_code = (code == 18) ? BUS_ADRALN : BUS_ADRERR;
			break;
		case 16:	/* Non-access instruction TLB miss fault */
		case 26:	/* PCXL: Data memory access rights trap */
		default:
			si.si_signo = SIGSEGV;
			si.si_code = SEGV_MAPERR;
			si.si_code = (code == 26) ? SEGV_ACCERR : SEGV_MAPERR;
			break;
		}
		si.si_errno = 0;
		si.si_addr = (void __user *) address;