linux/arch
Jan Beulich 13d2b4d11d x86/xen: don't assume %ds is usable in xen_iret for 32-bit PVOPS.
This fixes CVE-2013-0228 / XSA-42

Drew Jones while working on CVE-2013-0190 found that that unprivileged guest user
in 32bit PV guest can use to crash the > guest with the panic like this:

-------------
general protection fault: 0000 [#1] SMP
last sysfs file: /sys/devices/vbd-51712/block/xvda/dev
Modules linked in: sunrpc ipt_REJECT nf_conntrack_ipv4 nf_defrag_ipv4
iptable_filter ip_tables ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6
xt_state nf_conntrack ip6table_filter ip6_tables ipv6 xen_netfront ext4
mbcache jbd2 xen_blkfront dm_mirror dm_region_hash dm_log dm_mod [last
unloaded: scsi_wait_scan]

Pid: 1250, comm: r Not tainted 2.6.32-356.el6.i686 #1
EIP: 0061:[<c0407462>] EFLAGS: 00010086 CPU: 0
EIP is at xen_iret+0x12/0x2b
EAX: eb8d0000 EBX: 00000001 ECX: 08049860 EDX: 00000010
ESI: 00000000 EDI: 003d0f00 EBP: b77f8388 ESP: eb8d1fe0
 DS: 0000 ES: 007b FS: 0000 GS: 00e0 SS: 0069
Process r (pid: 1250, ti=eb8d0000 task=c2953550 task.ti=eb8d0000)
Stack:
 00000000 0027f416 00000073 00000206 b77f8364 0000007b 00000000 00000000
Call Trace:
Code: c3 8b 44 24 18 81 4c 24 38 00 02 00 00 8d 64 24 30 e9 03 00 00 00
8d 76 00 f7 44 24 08 00 00 02 80 75 33 50 b8 00 e0 ff ff 21 e0 <8b> 40
10 8b 04 85 a0 f6 ab c0 8b 80 0c b0 b3 c0 f6 44 24 0d 02
EIP: [<c0407462>] xen_iret+0x12/0x2b SS:ESP 0069:eb8d1fe0
general protection fault: 0000 [#2]
---[ end trace ab0d29a492dcd330 ]---
Kernel panic - not syncing: Fatal exception
Pid: 1250, comm: r Tainted: G      D    ---------------
2.6.32-356.el6.i686 #1
Call Trace:
 [<c08476df>] ? panic+0x6e/0x122
 [<c084b63c>] ? oops_end+0xbc/0xd0
 [<c084b260>] ? do_general_protection+0x0/0x210
 [<c084a9b7>] ? error_code+0x73/
-------------

Petr says: "
 I've analysed the bug and I think that xen_iret() cannot cope with
 mangled DS, in this case zeroed out (null selector/descriptor) by either
 xen_failsafe_callback() or RESTORE_REGS because the corresponding LDT
 entry was invalidated by the reproducer. "

Jan took a look at the preliminary patch and came up a fix that solves
this problem:

"This code gets called after all registers other than those handled by
IRET got already restored, hence a null selector in %ds or a non-null
one that got loaded from a code or read-only data descriptor would
cause a kernel mode fault (with the potential of crashing the kernel
as a whole, if panic_on_oops is set)."

The way to fix this is to realize that the we can only relay on the
registers that IRET restores. The two that are guaranteed are the
%cs and %ss as they are always fixed GDT selectors. Also they are
inaccessible from user mode - so they cannot be altered. This is
the approach taken in this patch.

Another alternative option suggested by Jan would be to relay on
the subtle realization that using the %ebp or %esp relative references uses
the %ss segment.  In which case we could switch from using %eax to %ebp and
would not need the %ss over-rides. That would also require one extra
instruction to compensate for the one place where the register is used
as scaled index. However Andrew pointed out that is too subtle and if
further work was to be done in this code-path it could escape folks attention
and lead to accidents.

Reviewed-by: Petr Matousek <pmatouse@redhat.com>
Reported-by: Petr Matousek <pmatouse@redhat.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
2013-02-13 15:40:30 -05:00
..
alpha Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2012-11-18 09:13:48 -10:00
arm Linux 3.7 2013-01-15 15:58:25 -05:00
arm64 open*(2) compat fixes (s390, arm64) 2012-12-02 10:46:38 -08:00
avr32 Merge branch 'modules-next' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux 2012-10-14 13:39:34 -07:00
blackfin Merge branch 'modules-next' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux 2012-10-14 13:39:34 -07:00
c6x c6x: use generic kvm_para.h 2012-11-28 14:33:03 -05:00
cris Merge branch 'modules-next' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux 2012-10-14 13:39:34 -07:00
frv frv: fix the broken preempt 2012-11-02 12:08:25 -04:00
h8300 h8300: add missing L1_CACHE_SHIFT 2012-11-09 06:41:47 +01:00
hexagon Hexagon: Copyright marking changes 2012-10-18 17:07:21 -05:00
ia64 revert "mm: fix-up zone present pages" 2012-11-16 14:33:04 -08:00
m32r Merge branch 'modules-next' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux 2012-10-14 13:39:34 -07:00
m68k m68k: fix sigset_t accessor functions 2012-11-18 10:32:16 +01:00
microblaze microblaze: rt_sigreturn is too trigger-happy about sigaltstack errors 2012-11-28 21:46:12 -05:00
mips MIPS: Fix endless loop when processing signals for kernel tasks 2012-12-05 19:59:00 +01:00
mn10300 UAPI: Make arch/mn10300/include/uapi/asm/setup.h non-empty 2012-10-17 12:32:35 +01:00
openrisc openrisk: fix altstack switching on sigreturn 2012-11-28 21:46:11 -05:00
parisc [parisc] open(2) compat bug 2012-12-03 11:13:09 -08:00
powerpc powerpc/eeh: Do not invalidate PE properly 2012-11-26 09:14:16 +11:00
s390 open*(2) compat fixes (s390, arm64) 2012-12-02 10:46:38 -08:00
score score: do_sigaltstack() expects a userland pointer... 2012-11-28 21:46:12 -05:00
sh sh64: fix altstack switching on sigreturn 2012-11-28 21:46:11 -05:00
sparc sparc: Fix piggyback with newer binutils. 2012-12-03 11:24:25 -08:00
tile arch/tile: avoid build warnings from duplicate ELF_R_xxx #defines 2012-10-23 10:22:48 -04:00
um um: get_safe_registers() should be done in flush_thread(), not start_thread() 2012-11-28 21:46:03 -05:00
unicore32 arch/unicore32: remove CONFIG_EXPERIMENTAL 2012-11-09 17:30:10 +08:00
x86 x86/xen: don't assume %ds is usable in xen_iret for 32-bit PVOPS. 2013-02-13 15:40:30 -05:00
xtensa xtensa: switch to generic sys_execve() 2012-10-25 15:00:44 -07:00
.gitignore
Kconfig Merge branch 'modules-next' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux 2012-10-14 13:39:34 -07:00