Bug 194215

Summary: CVE-2006-2448 missing access_ok checks in powerpc signal*.c
Product: Red Hat Enterprise Linux 4 Reporter: Marcel Holtmann <holtmann>
Component: kernelAssignee: David Woodhouse <dwmw2>
Status: CLOSED ERRATA QA Contact: Brian Brock <bbrock>
Severity: high Docs Contact:
Priority: medium    
Version: 4.0CC: dwmw2, jbaron, miyer, security-response-team
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard: impact=important,source=kernelsec,reported=20060606,embargo=yes,public=20060609
Fixed In Version: RHSA-2006-0575 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2006-08-10 19:26:47 EDT Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---
Bug Depends On:    
Bug Blocks: 181411    
Attachments:
Description Flags
RHEL4 patch
none
Test case from David Woodhouse
none
Updated minimal and correct patch none

Description Marcel Holtmann 2006-06-06 08:04:16 EDT
Dave Jones reported that he was able to provoke a machine check on ppc32 with
his scrashme program, apparently as a result of missing access_ok checks on the
arguments to the sys_debug_setcontext system call. In signal_32.c and
signal_64.c there were other similar issues.

Some of them are pretty serious. One of them will let an unprivileged user
program read any kernel memory on ppc64 systems with Altivec. Both 32-bit and
64-bit kernels are affected and some of the problems go back to the 2.4 days. It
appears that some of the people that did the original ppc64 port liked to do

        ret = put_user(&p->a);
        ret |= __put_user(&p->b);
        if (ret)
                return -EFAULT;

which is of course *not* a good idea, although

        if (put_user(&p->a) || __put_user(&p->b))
                return -EFAULT;

is OK on ppc64 because of the large gap between TASK_SIZE and KERNELBASE.
Comment 2 Marcel Holtmann 2006-06-06 11:42:24 EDT
Paul Mackerras revised his initial post and mentioned that those of the
bogosities found that are in the 32-bit compatibility code for 64-bit kernels
aren't actually security holes, since it isn't possible for a 32-bit process to
generate a kernel address. That leaves:

- a hole in the 64-bit kernel that lets unprivileged processes read (but not
write) arbitrary kernel memory on systems that have Altivec.

- a hole that lets processes on a 32-bit kernel restore their register set from
an arbitrary kernel address (on signal return or with the sys_swapcontext or
sys_debug_setcontext system calls). That only reads kernel memory and would be
hard to exploit as a method of reading kernel memory since the program counter
would be set to some hard-to-predict value. It could be used to crash the system
though.
Comment 3 Marcel Holtmann 2006-06-07 06:27:43 EDT
The arch/powerpc/kernel/signal_32.c changes from the patch map to
ppc64/kernel/signal32.c in the RHEL4 kernel.

In sys32_rt_sigaction() we see the same problems addressed in the upstream patch.

The do_setcontext32() function is missing a verify_area() call.

In sys32_swapcontext() the RHEL4 kernel has the needed verify_area() call
already. So it seems this one got removed upstream during the PowerPC
re-organization.

The verify_area() call in arch/ppc64/kernel/signal.c for the Altivec specific
issue is missing.
Comment 4 David Woodhouse 2006-06-08 09:40:23 EDT
Of which, the only one which actually matters is the last, because the rest will
all be limited to 32-bit addresses anyway. 

There's also a suspect read from regs->rip in fix_alignment(), in some
circumstances.
Comment 5 David Woodhouse 2006-06-08 10:03:22 EDT
Created attachment 130744 [details]
RHEL4 patch
Comment 6 Marcel Holtmann 2006-06-14 06:26:39 EDT
The final upstream patch can be found here:

http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=7c85d1f9d358b24c5b05c3a2783a78423775a080
Comment 9 Josh Bressers 2006-06-14 08:39:30 EDT
------- Additional Comments From holtmann@redhat.com  2006-06-12 03:11 EST -------
For reference the upstream fix can be found here:

http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=7c85d1f9d358b24c5b05c3a2783a78423775a080
Comment 10 David Woodhouse 2006-06-14 18:43:29 EDT
Created attachment 130940 [details]
Updated minimal and correct patch

The part in fix_alignment() in the previous patch was not necessary.

Also, revert to using access_ok() as in the original upstream patch, having
corrected the length.

This is the version which was tested.
Comment 17 Jason Baron 2006-06-26 21:15:02 EDT
committed in stream U4 build 39.2. A test kernel with this patch is available
from http://people.redhat.com/~jbaron/rhel4/
Comment 22 Red Hat Bugzilla 2006-08-10 19:26:53 EDT
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on the solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.

http://rhn.redhat.com/errata/RHSA-2006-0575.html