Bug 750284 - sVirt allows PROT_EXEC mappings
Summary: sVirt allows PROT_EXEC mappings
Keywords:
Status: CLOSED WORKSFORME
Alias: None
Product: Red Hat Enterprise Linux 6
Classification: Red Hat
Component: libvirt
Version: 6.3
Hardware: x86_64
OS: Linux
high
high
Target Milestone: rc
: ---
Assignee: Jiri Denemark
QA Contact: Virtualization Bugs
URL:
Whiteboard:
Depends On: 760473
Blocks:
TreeView+ depends on / blocked
 
Reported: 2011-10-31 15:09 UTC by Avi Kivity
Modified: 2013-01-09 11:24 UTC (History)
10 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
: 760473 (view as bug list)
Environment:
Last Closed: 2012-02-01 20:32:29 UTC
Target Upstream Version:


Attachments (Terms of Use)

Description Avi Kivity 2011-10-31 15:09:40 UTC
Description of problem:

sVirt now allows mprotect(..., PROT_EXEC) and mmap(..., PROT_EXEC, ..., -1, ...) (that is, executable anonymous memory).  This allows a vulnerable qemu to be compromised by stuffing the stack with a call to mprotect(), making some guest-controlled memory executable, and then returning to that memory.


Version-Release number of selected component (if applicable):
libvirt-0.9.4-20.el6

How reproducible:
always (if you're incredibly clever)

Steps to Reproduce:
1. Find a vulnerability within qemu
2. Fill some guest memory with stage 2 exploit code
3. Exploit the vulnerability
4. Circumvent PIE/PIC and cause the qemu to return to mprotect(), marking your stage 2 exploit code executable
5. Return to stage 2 exploit code
6. Find another vulnerability in the kernel
7. Get your stage 2 exploit code to exploit this vulnerability
8. Responsible disclosure
9. Submit a paper to Black Hat
  
Actual results:

p0wned

Expected results:

segfault

Additional info:

Please also verify that no file mappings can be made executable, either at mmap() time or via mprotect(); especially for guest controlled files like images, or qcow2 snapshot files.

Comment 6 Jiri Denemark 2011-12-02 14:48:07 UTC
Avi, I don't claim to completely understand this issue, but it seems like there's anything that libvirt could do except for running qemu process with the right SELinux context, which libvirt already does. So IMHO this needs to be handled in SELinux policy. Am I right or did I miss anything?

Comment 7 Avi Kivity 2011-12-05 10:32:42 UTC
Maybe it can be handled fully in the policy; I'm not familiar with it.  But note at least one snag - if you run qemu without kvm, then qemu needs to be able to PROT_EXEC some memory for its translated code.  So libvirt does need to make some differentiation between the two cases.

Comment 8 Jiri Denemark 2011-12-05 14:01:45 UTC
Hmm, this is getting complicated. Daniel, any idea how to solve this without the need to have two SELinux types, one that allows PROT_EXEC and one that denies it? Which would be quite a mess. Something like a per-process boolean (which I doubt it exists) would be great :-)

Comment 9 Daniel Walsh 2011-12-05 20:54:19 UTC
No the way to fix this is to have two different types.

svirt_t and svirt_prot_exec_t or something like that.  They can have the exact same policy except one gets prot_exec and the other does not.  The only problem is how to we tell libvirt which to launch.

Comment 10 Daniel Walsh 2011-12-05 20:55:30 UTC
When I originally designed the policy we had planned on there being multiple types BTW, I had thought at one time we might want to design a type that had no network access or limited network ports.  For example.  But a lot of that responsibility can be better handled by iptables.

Comment 11 Jiri Denemark 2011-12-06 09:41:12 UTC
OK, so it seems it won't be such a big mess then :-) Libvirt will need to decide which of the contexts to use according to domain type qemu/kvm.

Anyway, I'm cloning this BZ to selinux-policy so that an appropriate svirt_* type is created.

Comment 12 Jiri Denemark 2012-01-17 08:58:34 UTC
Avi, did you actually try to reproduce the reported issue? According to Daniel's comment https://bugzilla.redhat.com/show_bug.cgi?id=760473#c6 this seems to be already blocked by current policy for svirt_t.

Comment 13 Jiri Denemark 2012-01-31 22:12:00 UTC
And Fedora bug 785635 confirms that this is indeed blocked (at least in Fedora) since qemu doesn't work because of that. So it seems we should be fine in RHEL as long as we have that policy as we have no qemu. We may need the extra virt type for Fedora/upstream though.

Comment 14 Avi Kivity 2012-02-01 10:58:37 UTC
(In reply to comment #12)
> Avi, did you actually try to reproduce the reported issue? According to
> Daniel's comment https://bugzilla.redhat.com/show_bug.cgi?id=760473#c6 this
> seems to be already blocked by current policy for svirt_t.

I did not, and agree we appear to be protected now.

Comment 15 Jiri Denemark 2012-02-01 20:32:29 UTC
Great, I think we can just close this bug then. More work still needs to be done, but that only affects upstream and it is already tracked by bug 785635.

Comment 16 Dave Allan 2012-02-01 20:54:14 UTC
WORKSFORME I think, but agreed.


Note You need to log in before you can comment on or make changes to this bug.