Re: [Xen-devel] Tracking guest code execution with EPT violations
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
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
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