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);
which is of course *not* a good idea, although
if (put_user(&p->a) || __put_user(&p->b))
is OK on ppc64 because of the large gap between TASK_SIZE and KERNELBASE.
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
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
The verify_area() call in arch/ppc64/kernel/signal.c for the Altivec specific
issue is missing.
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
Created attachment 130744 [details]
The final upstream patch can be found here:
------- Additional Comments From firstname.lastname@example.org 2006-06-12 03:11 EST -------
For reference the upstream fix can be found here:
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.
committed in stream U4 build 39.2. A test kernel with this patch is available
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.