parisc: Ensure userspace privilege for ptraced processes in regset functions [Linux 4.9.187]

This Linux kernel change "parisc: Ensure userspace privilege for ptraced processes in regset functions" is included in the Linux 4.9.187 release. This change is authored by Helge Deller <deller [at] gmx.de> on Thu Jul 4 03:44:17 2019 +0200. The commit for this change in Linux stable tree is e7193d4 (patch) which is from upstream commit 34c32fc. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream 34c32fc.

parisc: Ensure userspace privilege for ptraced processes in regset functions

commit 34c32fc603311a72cb558e5e337555434f64c27b upstream.

On parisc the privilege level of a process is stored in the lowest two bits of
the instruction pointers (IAOQ0 and IAOQ1). On Linux we use privilege level 0
for the kernel and privilege level 3 for user-space. So userspace should not be
allowed to modify IAOQ0 or IAOQ1 of a ptraced process to change it's privilege
level to e.g. 0 to try to gain kernel privileges.

This patch prevents such modifications in the regset support functions by
always setting the two lowest bits to one (which relates to privilege level 3
for user-space) if IAOQ0 or IAOQ1 are modified via ptrace regset calls.

Link: https://bugs.gentoo.org/481768
Cc: <[email protected]> # v4.7+
Tested-by: Rolf Eike Beer <[email protected]>
Signed-off-by: Helge Deller <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

There are 3 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 arch/parisc/kernel/ptrace.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index 0780c37..8a0c72a 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -499,7 +499,8 @@ static void set_reg(struct pt_regs *regs, int num, unsigned long val)
            return;
    case RI(iaoq[0]):
    case RI(iaoq[1]):
-           regs->iaoq[num - RI(iaoq[0])] = val;
+           /* set 2 lowest bits to ensure userspace privilege: */
+           regs->iaoq[num - RI(iaoq[0])] = val | 3;
            return;
    case RI(sar):   regs->sar = val;
            return;

Leave a Reply

Your email address will not be published. Required fields are marked *