Re: make check_no_exec() work reliable
Peter Beutner [EMAIL PROTECTED] writes: I'm not so sure about this, I think I read somewhere that each loaded DLL is checked for this not just the main exe and the protection is disabled if at least on module is not nx compatible. But as no wine dll is marked as NX_COMPAT(i assume) this would basically mean to always disable the protection. It probably doesn't hurt to leave it like this for now. Yes, the next step is to implement a smarter strategy for turning protection on or off. I don't know about checking the flag for all dlls or only the main exe, I guess I'll have to ask you to try this on Windows too... -- Alexandre Julliard [EMAIL PROTECTED]
Re: make check_no_exec() work reliable
Alexandre Julliard wrote: Peter Beutner [EMAIL PROTECTED] writes: Why should this exception be visible to the application? Plus if you make it visible, you can just forget this whole workaround idea, because it won't work reliable anyways. Well, yes, the workaround is really a hack that should be replaced by a proper fix; I was hoping it would encourage someone to look into it and fix it properly, I can't do it because my box doesn't have noexec support. Certainly some more testing on windows is needed, but this check_no_exec() workaround was regardless introduced a long time ago. This patch just fixes this workaround. Otherwise it could as well be removed at all. Well, yes, it could certainly be removed; I added it mostly to make sure that we generated the exception properly, and to demonstrate how the exception can be handled. The proper fix is clearly more complex than that, but moving that hack into the exception code isn't a step in the right direction IMO. hm, at least for that message box that was talked about, I don't see another choice than to put it into the exception code. But that probably should then only be the message box (and maybe a possibility to change the noexecute configuration for this app) and no code for trying to workaround the protection. I also took a closer look on the windows behaviour. There is no (at least application visible) difference in how the memory areas(heap, stack,valloc,image) are mapped between NX disabled/enabled mode. (Apart from the mysterious fact that a bunch of more dlls are loaded when it is disabled.) The only difference is whether code runs from non-executable memory or not. I'll attach the output of a small testcase I've written which shows the memory layout for both cases. There is however one exception. If the noexecute policy is set to OptOut[1] and windows loads a PE file where the AddressEntryPoint is in a non-executable section, NX protection is automatically switched off for this process. According to some paper[2] there are even more specific compatibility checks, e.g. for the safedisc driver. Sadly MS just speaks of System compatibility fixes without further detailed explanation :/ But as linux can't just switch on/off the protection for specific processes, wine has to emulate it by marking all readable memory as executable as well. And as all this happens behind the application's back, I would still go with my first proposal to just pair every PROT_READ with a PROT_EXEC in dlls/ntdll/virtual.c:VIRTUAL_GetUnixProt(). Does that sound acceptable? 1) means: apply protection for all apps, but allow to disable it for specific apps 2) http://www.uninformed.org/?v=2a=4 run tests: execute onstack: failed execute on .rodata: failed execute on.data: failed execute on heap: failed execute on valloc: failed --- dump memory info: 0x0001 - 0x00011fff -rw- private 0x0002 - 0x00020fff -rw- private 0x0022d000 - 0x0022dfff grw- private 0x0022e000 - 0x0022 -rw- private (stack) 0x0023 - 0x00232fff -r-- mapped 0x0024 - 0x00243fff -rw- private (heap) 0x0034 - 0x00345fff -rw- private 0x0035 - 0x00352fff -rw- mapped 0x0036 - 0x00375fff -r-- mapped 0x0038 - 0x003bcfff -r-- mapped 0x003c - 0x003c5fff -r-- mapped 0x003d - 0x003d5fff -rw- private 0x003e - 0x003e2fff -r-- mapped 0x003f - 0x003f0fff -rwe private 0x0040 - 0x00400fff -r-- image file: test_mem.exe (40 - 408000) 0x00401000 - 0x00403fff -r-e image section:.text flags: r-x CODE 0x00404000 - 0x00404fff -rw- image section:.data flags: rw- DATA 0x00405000 - 0x00405fff -r-- image section: .rdata flags: r-- DATA 0x00406000 - 0x00407fff -rw- image section: .bss flags: rw- BSS 0x0041 - 0x00450fff -r-- mapped 0x0046 - 0x00460fff -rw- private (valloc) 0x77be - 0x77be0fff -r-- image file: msvcrt.dll (77be - 77c38000) 0x77be1000 - 0x77c2cfff -r-e image section:.text flags: r-x CODE 0x77c2d000 - 0x77c2efff -rw- image section:.data flags: rw- DATA 0x77c2f000 - 0x77c2 -rw- image section:.data flags: rw- DATA 0x77c3 - 0x77c30fff -rw- image section:.data flags: rw- DATA 0x77c31000 - 0x77c33fff -rw- image section:.data flags: rw- DATA 0x77c34000 - 0x77c37fff -r-- image section:.rsrc flags: r-- DATA 0x7c80 - 0x7c800fff -r-- image file: kernel32.dll (7c80 - 7c906000) 0x7c801000 - 0x7c882fff -r-e image section:.text flags: r-x CODE 0x7c883000 - 0x7c885fff -rw- image section:.data flags: rw- DATA 0x7c886000 - 0x7c887fff -rw- image section:.data flags: rw- DATA 0x7c888000 - 0x7c905fff -r-- image section:.rsrc flags: r-- DATA 0x7c91 - 0x7c910fff -r-- image file: ntdll.dll (7c91 - 7c9c7000) 0x7c911000 - 0x7c98bfff -r-e image section:.text flags: r-x CODE 0x7c98c000 - 0x7c98efff -rw- image section:.data flags: rw- DATA 0x7c98f000
Re: make check_no_exec() work reliable
Peter Beutner wrote: Before starting to make this whole noexecute override behaviour configurable, it first must work reliable. In its current form there is no guarantee that the check_no_exec() function is actually called, because any other installed exception handler might decide to handle the exception itself. And as seen by the number of failing applications, this seems to happen quite a lot. This patch therefore makes check_no_exec() to be called before any other exception handler. --- Any comments what is wrong with this one?
Re: make check_no_exec() work reliable
Peter Beutner [EMAIL PROTECTED] writes: Peter Beutner wrote: Before starting to make this whole noexecute override behaviour configurable, it first must work reliable. In its current form there is no guarantee that the check_no_exec() function is actually called, because any other installed exception handler might decide to handle the exception itself. And as seen by the number of failing applications, this seems to happen quite a lot. This patch therefore makes check_no_exec() to be called before any other exception handler. --- Any comments what is wrong with this one? If the exception is not made visible to the app then there is no point in having one at all, we might just as well turn off the protection right away. What really needs to be done is to investigate the Windows behavior and determine which parts of the app memory should be protected and which shouldn't, depending on the exe flags etc. and then replicate that behavior. -- Alexandre Julliard [EMAIL PROTECTED]
Re: make check_no_exec() work reliable
Alexandre Julliard wrote: Peter Beutner [EMAIL PROTECTED] writes: Peter Beutner wrote: Before starting to make this whole noexecute override behaviour configurable, it first must work reliable. In its current form there is no guarantee that the check_no_exec() function is actually called, because any other installed exception handler might decide to handle the exception itself. And as seen by the number of failing applications, this seems to happen quite a lot. This patch therefore makes check_no_exec() to be called before any other exception handler. --- Any comments what is wrong with this one? If the exception is not made visible to the app then there is no point in having one at all, we might just as well turn off the protection right away. Why should this exception be visible to the application? Plus if you make it visible, you can just forget this whole workaround idea, because it won't work reliable anyways. And remembering the last discussion I thought just turning off the protection wasn't your preferred solution either. What really needs to be done is to investigate the Windows behavior and determine which parts of the app memory should be protected and which shouldn't, depending on the exe flags etc. and then replicate that behavior. Certainly some more testing on windows is needed, but this check_no_exec() workaround was regardless introduced a long time ago. This patch just fixes this workaround. Otherwise it could as well be removed at all.
Re: make check_no_exec() work reliable
Peter Beutner [EMAIL PROTECTED] writes: Why should this exception be visible to the application? Plus if you make it visible, you can just forget this whole workaround idea, because it won't work reliable anyways. Well, yes, the workaround is really a hack that should be replaced by a proper fix; I was hoping it would encourage someone to look into it and fix it properly, I can't do it because my box doesn't have noexec support. Certainly some more testing on windows is needed, but this check_no_exec() workaround was regardless introduced a long time ago. This patch just fixes this workaround. Otherwise it could as well be removed at all. Well, yes, it could certainly be removed; I added it mostly to make sure that we generated the exception properly, and to demonstrate how the exception can be handled. The proper fix is clearly more complex than that, but moving that hack into the exception code isn't a step in the right direction IMO. -- Alexandre Julliard [EMAIL PROTECTED]