Commit 89f686a0 authored by John David Anglin's avatar John David Anglin Committed by Helge Deller
Browse files

parisc: Revise __get_user() to probe user read access



Because of the way read access support is implemented, read access
interruptions are only triggered at privilege levels 2 and 3. The
kernel executes at privilege level 0, so __get_user() never triggers
a read access interruption (code 26). Thus, it is currently possible
for user code to access a read protected address via a system call.

Fix this by probing read access rights at privilege level 3 (PRIV_USER)
and setting __gu_err to -EFAULT (-14) if access isn't allowed.

Note the cmpiclr instruction does a 32-bit compare because COND macro
doesn't work inside asm.

Signed-off-by: default avatarJohn David Anglin <dave.anglin@bell.net>
Signed-off-by: default avatarHelge Deller <deller@gmx.de>
Cc: stable@vger.kernel.org # v5.12+
parent f6334f4a
Loading
Loading
Loading
Loading
+18 −3
Original line number Diff line number Diff line
@@ -42,9 +42,24 @@
	__gu_err;					\
})

#define __probe_user_internal(sr, error, ptr)			\
({								\
	__asm__("\tproberi (%%sr%1,%2),%3,%0\n"			\
		"\tcmpiclr,= 1,%0,%0\n"				\
		"\tldi %4,%0\n"					\
		: "=r"(error)					\
		: "i"(sr), "r"(ptr), "i"(PRIV_USER),		\
		  "i"(-EFAULT));				\
})

#define __get_user(val, ptr)					\
({								\
	__get_user_internal(SR_USER, val, ptr);	\
	register long __gu_err;					\
								\
	__gu_err = __get_user_internal(SR_USER, val, ptr);	\
	if (likely(!__gu_err))					\
		__probe_user_internal(SR_USER, __gu_err, ptr);	\
	__gu_err;						\
})

#define __get_user_asm(sr, val, ldx, ptr)		\