Re: [Xen-devel] Tracking guest code execution with EPT violations

2015-01-29 Thread Tim Deegan
Hi,

At 14:09 + on 23 Jan (1422018568), kevin.ma...@gdata.de wrote:
 My idea was that when a guest wants to access a new page (let`s say
 a guest wants to start a new process and therefore needs to copy the
 code into the memory) then an EPT-violation should be raised because
 the corresponding EPTE for this new page isn`t there since the page
 was now accessed for the first time.  This does not happen though.

OK, I think there's some confusion about what a 'new' page means here.
From Xen's point of view (leaving aside PoD, paging, ballooning, c
for now) the guest is given a fixed pool of memory when it boots,
which looks just like the RAM in a real PC.

The guest then allocates that memory internally: typically it will put
pages in a free pool and then assign them to new processes.  But Xen
doesn't see that assignment - it happens entirely inside the guest.
Xen only cares about when the memory is accessed.  Typically the first
access to the page will be at OS boot time, when the guest OS zeros
out all its memory.

 Then I wanted to see if I could get only the EPT_VIOLATIONS of let`s say 
 Firefox (or any new process). So I let my guest-OS boot up, changed the 
 default_access to read+write with the help of
 xc_hvm_set_mem_access(xch, domid, HVMMEM_access_rw,~0ull, 0);
 as shown in xen-access.c (I didn`t want to get any EPT_VIOLATIONS
 for pages that are already present, i.e. the OS so I didn't set the
 existing pages to access_rw) and then started Firefox in the guest.

That sets the default for new mappings, but doesn't change any
existing mappings.  You need to explicitly set the permissions for the
particular pages you're interested in. 

 I suspect that the default_access gets used to initialize the domain
 and then some initialized value gets used instead of the
 p2m-default_access.

Yes.  Any existing mappings will have been established with whatever
the default was at the time.

 Another possibility is that my idea of how the
 memory is accessed is flawed or that all pages the OS uses for
 Firefox are already initialized.

Also yes: the OS will have touched them when it scrubbed memory on boot.

Cheers,

Tim.

___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


Re: [Xen-devel] Tracking guest code execution with EPT violations

2015-01-22 Thread Tim Deegan
Hi,

At 16:25 + on 16 Jan (1421421905), kevin.ma...@gdata.de wrote:
 So whenever a nonexisting memory page gets requested an EPT violation is 
 caused (and handled by ept_handle_violation). Extending the  
 EXIT_REASON_EPT_VIOLATION I should be able to set the access rights for every 
 new page to access_rw(By using the p2m-get_entry and p2m- set_entry 
 functions right after the violation was handled), leading to a new EPT 
 violation every time an instruction is fetched from this page.
 
 There are several problems with my approach so far:
 
 * I get to few unique GFN (derived from the gpa by PAGE_SHIFT in the 
 EPT violations when booting a WinXP guest.  I get about 250 EPT_VIOLATIONS 
 with unique GFNs when booting the guest OS and none when starting new 
 programs in the guest. So something seems to be wrong there. Also I read the 
 access rights of the pages back after setting them. Most of the time the 
 initial access rights are access_n before and the same after I tried setting 
 them to access_rw (this happens when the type is p2m_mmio_dm, when the type 
 is p2m_ram_rw the setting works temporarily).

I can't really tell from that what you're doing, but:
 - I suspect that the 'p2m_mmio_dm' cases are gfns that don't map to
   anything.  Accesses to unmapped addresses are assumed to be
   emulated devices and passed to qemu.
 - If you are having trouble with access types changing underfoot,
   make sure that you are setting the domain's p2m-default_access
   to something sensible.

 * I never get an EPT violation with the EPT_EXEC_VIOLATION flag set 
 in the exit qualifications even for the pages where the setting of the access 
 rights did succeed.

Hmm.

 * Later when checking the access rights (I simply save the GFNs in an 
 array and use p2m-get_entry in an own  call to domctl.c from xl) of the GFNs 
 they all have access right access_n and type p2m_mmio_dm , even for the pages 
 where the setting of the access rights did succeed or the type was different 
 before.


Again, that sounds like the addresses are not mapped at all, rather
than mapped with the wrong access control.

 This all tells me that there is something fundamentally wrong with my 
 approach so far, leading me to the following questions:
 
 
 1.   Every time a new page in memory is allocated by the guest I get an 
 EPT_VIOLATION, right?

That depends on what you mean by 'allocated by the guest'.  If you
have set the access bits correctly, you will get an EPT_VIOLATION
when the page is _accessed_ by the guest.

 a.   If this is the case then why don't I get new violations after 
 windows has finished booting?
 
 2.   What is the difference between types p2m_mmio_dm and p2m_ram_rw? 
 (got a feeling that part of the problem lies here)

Have a look at the comments in include/asm-x86/p2m.h where those names
(and others) are defined.  And as I mentioned aove, any gfn that's not
mapped at all will seem to be mmio_dm.

 3.   Are the p2m-get_entry/p2m-set_entry functions the right tools for 
 this purpose?

Probably not.  p2m_set_mem_access() and p2m_get_mem_access() should be
better. 

 4.   To get the domain I use struct vcpu *curr = current; and struct 
 p2m_domain *p2m = p2m_get_hostp2m(curr-domain); before using the 
 get/set_entry-functions. Do I get confused with wrong domains or something 
 like that?

Maybe.  Those things will get you the currently executing domain, so
if your code is part of a hypercall handler it will adjust the
_caller_'s p2m. 

 5.   Because I just set the access rights to rw every time 
 EXIT_REASON_EPT_VIOLATION is called the whole domain should freeze/crash as 
 soon as the first page tries to execute an instruction, right? It doesn't 
 because I get no execution attempts on the pages I set the access_rw, but why 
 don't I get an execution attempt?
 

I can't really tell, but it does sounds like something is confused.
Possibly you are using the wrong kind of addresses?  These p2m
operations work on GFNs, i.e. whet the guest thinks are physical
addresses, and not MFNs (actual physical addresses) or virtual
addresses.

Cheers,

Tim.

___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel


[Xen-devel] Tracking guest code execution with EPT violations

2015-01-16 Thread Kevin.Mayer
Hi all

I`m trying to track code execution with page granularity by setting the access 
rights in the EPT to not executable on Xen 4.4.1.
The idea is as follows:

According to the intel manual  A reference using a guest-physical address 
whose translation encounters an EPT paging-structure that is not present causes 
an EPT violation.
So whenever a nonexisting memory page gets requested an EPT violation is caused 
(and handled by ept_handle_violation). Extending the  EXIT_REASON_EPT_VIOLATION 
I should be able to set the access rights for every new page to access_rw(By 
using the p2m-get_entry and p2m- set_entry functions right after the 
violation was handled), leading to a new EPT violation every time an 
instruction is fetched from this page.

There are several problems with my approach so far:

* I get to few unique GFN (derived from the gpa by PAGE_SHIFT in the 
EPT violations when booting a WinXP guest.  I get about 250 EPT_VIOLATIONS with 
unique GFNs when booting the guest OS and none when starting new programs in 
the guest. So something seems to be wrong there. Also I read the access rights 
of the pages back after setting them. Most of the time the initial access 
rights are access_n before and the same after I tried setting them to access_rw 
(this happens when the type is p2m_mmio_dm, when the type is p2m_ram_rw the 
setting works temporarily).

* I never get an EPT violation with the EPT_EXEC_VIOLATION flag set in 
the exit qualifications even for the pages where the setting of the access 
rights did succeed.

* Later when checking the access rights (I simply save the GFNs in an 
array and use p2m-get_entry in an own  call to domctl.c from xl) of the GFNs 
they all have access right access_n and type p2m_mmio_dm , even for the pages 
where the setting of the access rights did succeed or the type was different 
before.

This all tells me that there is something fundamentally wrong with my approach 
so far, leading me to the following questions:


1.   Every time a new page in memory is allocated by the guest I get an 
EPT_VIOLATION, right?

a.   If this is the case then why don't I get new violations after windows 
has finished booting?

2.   What is the difference between types p2m_mmio_dm and p2m_ram_rw? (got 
a feeling that part of the problem lies here)

3.   Are the p2m-get_entry/p2m-set_entry functions the right tools for 
this purpose?

a.   If they are, then why do they sometimes fail?

4.   To get the domain I use struct vcpu *curr = current; and struct 
p2m_domain *p2m = p2m_get_hostp2m(curr-domain); before using the 
get/set_entry-functions. Do I get confused with wrong domains or something like 
that?

5.   Because I just set the access rights to rw every time 
EXIT_REASON_EPT_VIOLATION is called the whole domain should freeze/crash as 
soon as the first page tries to execute an instruction, right? It doesn't 
because I get no execution attempts on the pages I set the access_rw, but why 
don't I get an execution attempt?

I hope it got clear what I try to achieve.

Thanks

Kevin


Virus checked by G Data MailSecurity
Version: AVA 24.6111 dated 16.01.2015
Virus news: www.antiviruslab.com___
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel