[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] Tracking guest code execution with EPT violations
Thanks for your reply. > Hi, > > > 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. 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. I played a bit with the p2m->default_access and got a new problem now. I hardcode the default access in static int p2m_initialise(struct domain *d, struct p2m_domain *p2m) to p2m->default_access = p2m_access_rw; This works well as I get several thousand EPT_VIOLATIONS (with unique GFN) when booting the guest (and several thousand more when starting new processes). When I set the default_access to p2m->default_access = p2m_access_rwx; I get no EPT_VIOLATIONS with execution attempts (no surprise here). 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. The idea behind this was that the guest needs to access new pages to start up Firefox, which would be set to the default_access (rw in this case). So when Firefox is running I would get EPT_VIOLATIONS with EPT_EXEC_VIOLATION in the exit_qualifications. This doesn`t work as expected, as I get none of these EPT_VIOLATIONS. 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. 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. > > 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. Yeah, I now use those. The p2m->get/set_entry worked, but the p2m_set/get_mem_access() are definitely the better choice. > > > 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. I was able to solve the problem with the wrong access rights. Turns out I was using the wrong domain, as you suggested... :-\ > > 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. > I use the gfn I get with gfn = gpa >> PAGE_SHIFT; in the EXIT_REASON_EPT_VIOLATION case of the vmexit_handler. The problem was that my initial assumption (EPT_VIOLATION being risen when the guest tries to access a page for the first time) was wrong, though I can`t figure out how the memory allocation is really working. Now when setting the access rights to access_rw after ept_handle_violation(exit_qualification, gpa); was called I successfully put the machine into a livelock (as expected since the ept_handle_violation sets the access rights to rwx, then I set them to rw again and the same instruction gets executed again leading to a new EPT_VIOLATION. Then the cycle repeats infinitely). I hope you can identify the error in my assumptions or point me to some code that might help regarding my problem with the default_access. Cheers Kevin ____________ Virus checked by G Data MailSecurity Version: AVA 24.6214 dated 23.01.2015 Virus news: www.antiviruslab.com _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |