Mike McCormack schrieb:
This should fix bug #6622.
The application in question doesn't crash because it needs an executable stack, but because the PE image header of the exe is totally broken, no section is marked as executable there at all. Wine does exactly what it should do here(same goes for Irfanview in #6129, seems both apps use the same exe packer(ASPack) so probably it's the packer which is broken). I bet the applications would also crash under windows if the noexecute protection is activated.
The reason why -z execstack helps is that the linux kernel marks _all_ readable pages as executable if an executable stack is requested, not only the stack(for whatever reasons), i.e. basically switching off the whole NX protection thing. So for fixing some _broken_ applications this patch unconditionally disables nx protection for every application running under wine. Seems like a bad tradeoff imo. (Though I don't know how widespread these kind of broken applications are. But there are definitly applications out there which don't need this.)
I tried to solve the same problem last weekend in a different way, see attached patch. It's not quite ready yet though.
It basically adds an option(HKCU\Software\Wine\NoExecCompat=On|Off) which, if enabled, couples PROT_READ with PROT_EXEC in every mprotect/mmap call, i.e. emulating the old standard x86 behaviour.
(The main problem is that this config option should be read out as early as possible from the registry but on the other hand a number of things need to be set up before it is possible to access the registry. So I'm not sure when the earliest/best point would be to do this. For now it is done right before the main exe is loaded.)
This way would have the advantage that the behaviour is tunable either globally or on a per-app basis.
dlls/ntdll/loader.c | 2 + dlls/ntdll/loadorder.c | 78 +++++++++++++++++++++++++--------------------- dlls/ntdll/ntdll_misc.h | 6 +++ dlls/ntdll/virtual.c | 57 +++++++++++++++++++++++++++++++++- 4 files changed, 106 insertions(+), 37 deletions(-)
diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 87767e5..64ed609 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -1728,6 +1728,8 @@ static NTSTATUS load_dll( LPCWSTR load_p main_exe = get_modref( NtCurrentTeb()->Peb->ImageBaseAddress ); loadorder = get_load_order( main_exe ? main_exe->ldr.BaseDllName.Buffer : NULL, filename );
+ if(!main_exe) init_noexec_setting(filename); + switch(loadorder) { case LO_INVALID: diff --git a/dlls/ntdll/loadorder.c b/dlls/ntdll/loadorder.c index c31b633..552ce87 100644 --- a/dlls/ntdll/loadorder.c +++ b/dlls/ntdll/loadorder.c @@ -294,31 +294,35 @@ static inline enum loadorder get_env_loa * * Return a handle to the standard DllOverrides registry section. */ -static HANDLE get_standard_key(void) +HANDLE get_standard_key( const WCHAR *subkey ) { - static const WCHAR DllOverridesW[] = {'S','o','f','t','w','a','r','e','\','W','i','n','e','\', - 'D','l','l','O','v','e','r','r','i','d','e','s',0}; - static HANDLE std_key = (HANDLE)-1; + static const WCHAR winekeyW[] = {'S','o','f','t','w','a','r','e','\','W','i','n','e',0}; + HANDLE std_key, root; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING nameW; + WCHAR *str = NULL; + + if(subkey) { + str = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(winekeyW) + strlenW(subkey) * sizeof(WCHAR)); + if(!str) return 0; + strcatW(str, winekeyW); + strcatW(str, subkey); + RtlInitUnicodeString( &nameW, str ); + } else + RtlInitUnicodeString( &nameW, winekeyW );
- if (std_key == (HANDLE)-1) - { - OBJECT_ATTRIBUTES attr; - UNICODE_STRING nameW; - HANDLE root; - - RtlOpenCurrentUser( KEY_ALL_ACCESS, &root ); - attr.Length = sizeof(attr); - attr.RootDirectory = root; - attr.ObjectName = &nameW; - attr.Attributes = 0; - attr.SecurityDescriptor = NULL; - attr.SecurityQualityOfService = NULL; - RtlInitUnicodeString( &nameW, DllOverridesW ); - - /* @@ Wine registry key: HKCU\Software\Wine\DllOverrides */ - if (NtOpenKey( &std_key, KEY_ALL_ACCESS, &attr )) std_key = 0; - NtClose( root ); - } + RtlOpenCurrentUser( KEY_ALL_ACCESS, &root ); + memset(&attr, 0, sizeof(attr)); + attr.Length = sizeof(attr); + attr.RootDirectory = root; + attr.ObjectName = &nameW; + + /* @@ Wine registry key: HKCU\Software\Wine[<subkey>] */ + if (NtOpenKey( &std_key, KEY_ALL_ACCESS, &attr )) std_key = 0; + NtClose( root ); + + if(str) RtlFreeHeap( GetProcessHeap(), 0, str ); return std_key; }
@@ -328,26 +332,26 @@ static HANDLE get_standard_key(void) * * Get the registry key for the app-specific DllOverrides list. */ -static HANDLE get_app_key( const WCHAR *app_name ) +HANDLE get_app_key( const WCHAR *app_name, const WCHAR *subkey ) { OBJECT_ATTRIBUTES attr; UNICODE_STRING nameW; - HANDLE root; + HANDLE root, app_key; WCHAR *str; static const WCHAR AppDefaultsW[] = {'S','o','f','t','w','a','r','e','\','W','i','n','e','\', 'A','p','p','D','e','f','a','u','l','t','s','\',0}; - static const WCHAR DllOverridesW[] = {'\','D','l','l','O','v','e','r','r','i','d','e','s',0}; - static HANDLE app_key = (HANDLE)-1; + int size; + + app_name = get_basename( app_name );
- if (app_key != (HANDLE)-1) return app_key; + size = sizeof(AppDefaultsW) + strlenW(app_name) * sizeof(WCHAR); + if(subkey) size += strlenW(subkey) * sizeof(WCHAR);
- str = RtlAllocateHeap( GetProcessHeap(), 0, - sizeof(AppDefaultsW) + sizeof(DllOverridesW) + - strlenW(app_name) * sizeof(WCHAR) ); + str = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, size); if (!str) return 0; strcpyW( str, AppDefaultsW ); strcatW( str, app_name ); - strcatW( str, DllOverridesW ); + if(subkey) strcatW( str, subkey );
RtlOpenCurrentUser( KEY_ALL_ACCESS, &root ); attr.Length = sizeof(attr); @@ -358,7 +362,7 @@ static HANDLE get_app_key( const WCHAR * attr.SecurityQualityOfService = NULL; RtlInitUnicodeString( &nameW, str );
- /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\DllOverrides */ + /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe[<subkey>] */ if (NtOpenKey( &app_key, KEY_ALL_ACCESS, &attr )) app_key = 0; NtClose( root ); RtlFreeHeap( GetProcessHeap(), 0, str ); @@ -432,15 +436,17 @@ static enum loadorder get_load_order_val */ enum loadorder get_load_order( const WCHAR *app_name, const WCHAR *path ) { + const static WCHAR DllOverridesW[] = {'\','D','l','l','O','v','e','r','r','i','d','e','s',0}; enum loadorder ret = LO_INVALID; - HANDLE std_key, app_key = 0; + static HANDLE std_key = (HANDLE)-1, app_key = (HANDLE) -1; WCHAR *module, *basename; UNICODE_STRING path_str; int len;
if (!init_done) init_load_order(); - std_key = get_standard_key(); - if (app_name) app_key = get_app_key( app_name ); + if ( std_key == (HANDLE)-1 ) std_key = get_standard_key( DllOverridesW ); + if ( app_name && app_key == (HANDLE)-1 ) + app_key = get_app_key( app_name, DllOverridesW );
TRACE("looking for %s\n", debugstr_w(path));
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index 1225036..310b528 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -144,6 +144,12 @@ struct debug_info char output[1024]; /* current output line */ };
+HANDLE get_standard_key( const WCHAR *subkey ); +HANDLE get_app_key( const WCHAR *app_name, const WCHAR *subkey ); + +void init_noexec_setting(const WCHAR *fullpath); + + struct ntdll_thread_data { struct debug_info *debug_info; /* info for debugstr functions */ diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index c469f76..48859eb 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -51,6 +51,7 @@ #include "winioctl.h" #include "wine/library.h" #include "wine/server.h" +#include "wine/unicode.h" #include "wine/list.h" #include "wine/debug.h" #include "ntdll_misc.h" @@ -143,6 +144,7 @@ static void *user_space_limit = USER_SPA static void *preload_reserve_start; static void *preload_reserve_end; static int use_locks; +static BOOL read_implies_exec = FALSE; /* default to Off */
/*********************************************************************** @@ -460,7 +462,7 @@ static int VIRTUAL_GetUnixProt( BYTE vpr int prot = 0; if ((vprot & VPROT_COMMITTED) && !(vprot & VPROT_GUARD)) { - if (vprot & VPROT_READ) prot |= PROT_READ; + if (vprot & VPROT_READ) prot |= ( read_implies_exec ) ? PROT_READ | PROT_EXEC : PROT_READ; if (vprot & VPROT_WRITE) prot |= PROT_WRITE; if (vprot & VPROT_WRITECOPY) prot |= PROT_WRITE; if (vprot & VPROT_EXEC) prot |= PROT_EXEC; @@ -2020,3 +2022,56 @@ NTSTATUS WINAPI NtWriteVirtualMemory( HA if (bytes_written) *bytes_written = size; return status; } + +/* from heap.c */ +#define HEAP_DEF_SIZE 0x110000 /* Default heap size = 1Mb + 64Kb */ + +static int get_noexec_setting(HANDLE key, UNICODE_STRING *valueW) +{ + const static WCHAR onW[] = {'O','n',0}; + const static WCHAR offW[] = {'O','f','f',0}; + WCHAR buffer[10]; + DWORD count; + int ret = 0; + + if(!key) return 0; + + if( NtQueryValueKey( key, valueW, KeyValuePartialInformation, + buffer, sizeof(buffer), &count ) == STATUS_SUCCESS) { + WCHAR *str = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)buffer)->Data; + + ret = 1; + if(strncmpW(str, onW, count) == 0) { + read_implies_exec = TRUE; + /* fix stack */ + mprotect( NtCurrentTeb()->Tib.StackLimit, + (size_t) NtCurrentTeb()->Tib.StackBase - (size_t)NtCurrentTeb()->Tib.StackLimit, + PROT_READ | PROT_WRITE | PROT_EXEC); + + /* fix heap (FIXME: this is wrong, should only fix already commited memory) */ + mprotect( NtCurrentTeb()->Peb->ProcessHeap, HEAP_DEF_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC); + } + else if(strncmpW(str, offW, count)) { + ERR("invalid registry value for NoExecCompat: %s\n", debugstr_w(str)); + ret = 0; + } + } + + NtClose(key); + return ret; +} + +void init_noexec_setting(const WCHAR *app_name) +{ + static const WCHAR NoExecCompatW[] = { 'N','o','E','x','e','c','C','o','m','p','a','t',0}; + UNICODE_STRING valueW; + HANDLE key; + + RtlInitUnicodeString( &valueW, NoExecCompatW); + + key = get_app_key(app_name, NULL); + if(get_noexec_setting(key, &valueW)) return; + + key = get_standard_key(NULL); + get_noexec_setting(key, &valueW); +}
On Wed, Nov 15, 2006 at 05:58:44PM +0100, Peter Beutner wrote:
Mike McCormack schrieb:
This should fix bug #6622.
The application in question doesn't crash because it needs an executable stack, but because the PE image header of the exe is totally broken, no section is marked as executable there at all. Wine does exactly what it should do here(same goes for Irfanview in #6129, seems both apps use the same exe packer(ASPack) so probably it's the packer which is broken). I bet the applications would also crash under windows if the noexecute protection is activated.
Actually check out dlls/kernel32/except.c:check_no_exec().
It marks pages as executable where code wants to be executed and actually should help in this case. It does help for 2 cases (the 2 lines printed), but fails on the 3rd. (It goes into an endless exception loop exhausting stack space.)
We need to find out why it fails for the 3rd.
Ciao, Marcus
Marcus Meissner schrieb:
On Wed, Nov 15, 2006 at 05:58:44PM +0100, Peter Beutner wrote:
Mike McCormack schrieb:
This should fix bug #6622.
The application in question doesn't crash because it needs an executable stack, but because the PE image header of the exe is totally broken, no section is marked as executable there at all. Wine does exactly what it should do here(same goes for Irfanview in #6129, seems both apps use the same exe packer(ASPack) so probably it's the packer which is broken). I bet the applications would also crash under windows if the noexecute protection is activated.
Actually check out dlls/kernel32/except.c:check_no_exec().
It marks pages as executable where code wants to be executed and actually should help in this case. It does help for 2 cases (the 2 lines printed), but fails on the 3rd. (It goes into an endless exception loop exhausting stack space.)
I think the problem is that it is called from UnhandledExceptionFilter.It is the the last exception handler that gets invoked. If there is any other exception handler registered, chances are good that this one will try to handle the error, but actually doing something totally wrong because it doesn't understand whats going on.
Besides i think it's a bad idea to blindly mark pages executable like this:
"hey, we successfully catched an attempted buffer overflow attack, thanks for NX. But lets ignore it and let the code run anyway ..." :p
Peter Beutner p.beutner@gmx.net writes:
Besides i think it's a bad idea to blindly mark pages executable like this:
"hey, we successfully catched an attempted buffer overflow attack, thanks for NX. But lets ignore it and let the code run anyway ..." :p
Well, the next step can be to pop up a message box of some kind, and let the user decide whether to proceed or not. It still gives more control than blindly making all pages executable from the start...
Alexandre Julliard schrieb:
Peter Beutner p.beutner@gmx.net writes:
Besides i think it's a bad idea to blindly mark pages executable like this:
"hey, we successfully catched an attempted buffer overflow attack, thanks for NX. But lets ignore it and let the code run anyway ..." :p
Well, the next step can be to pop up a message box of some kind, and let the user decide whether to proceed or not. It still gives more control than blindly making all pages executable from the start...
And that everytime the application runs? Would be a bit annoying I guess.
Peter Beutner p.beutner@gmx.net writes:
Alexandre Julliard schrieb:
Peter Beutner p.beutner@gmx.net writes:
Besides i think it's a bad idea to blindly mark pages executable like this:
"hey, we successfully catched an attempted buffer overflow attack, thanks for NX. But lets ignore it and let the code run anyway ..." :p
Well, the next step can be to pop up a message box of some kind, and let the user decide whether to proceed or not. It still gives more control than blindly making all pages executable from the start...
And that everytime the application runs? Would be a bit annoying I guess.
Of course you can have a "don't ask me again for this app" checkbox, or choose to enable only for the current session, or choose to disable for all apps forever, etc.
Alexandre Julliard schrieb:
Peter Beutner p.beutner@gmx.net writes:
Alexandre Julliard schrieb:
Peter Beutner p.beutner@gmx.net writes:
Besides i think it's a bad idea to blindly mark pages executable like this:
"hey, we successfully catched an attempted buffer overflow attack, thanks for NX. But lets ignore it and let the code run anyway ..." :p
Well, the next step can be to pop up a message box of some kind, and let the user decide whether to proceed or not. It still gives more control than blindly making all pages executable from the start...
And that everytime the application runs? Would be a bit annoying I guess.
Of course you can have a "don't ask me again for this app" checkbox, or choose to enable only for the current session, or choose to disable for all apps forever, etc.
Thats all I was arguing for ;). Making it configurable instead of just disabling it at compile time.
Well, the next step can be to pop up a message box of some kind, and let the user decide whether to proceed or not. It still gives more control than blindly making all pages executable from the start...
This is only acceptable if it pop ups only once for each application by default and there is option to turn if off if user don't like it. For example, I run Program.exe and then I see following pop up:
"NoExec fault detected. You can ignore this but then running program will be valnurable to buffer overflow attacks (or it already has been successfully attacked)." "Close" "Ignore (may be unsafe)" "[x] Don't ask again for this application" "[ ] Ignore NoExec faults for all applications (unsafe!)"
Ideally "Don't ask again for this application" and "Ignore" should be default if application crashes on start up and definitely NOT default if it crashes after (for example) 1 minute of normal work (because it likely has been attacked). Of course above example is just example and real-world dialog should be different (more understandable for newbie text, maybe other/different options, etc.). If flexible security option (something like the above) will be implemented into Wine instead of blind workaround that would be nice!
Alexandre Julliard wrote:
Peter Beutner p.beutner@gmx.net writes:
Besides i think it's a bad idea to blindly mark pages executable like this:
"hey, we successfully catched an attempted buffer overflow attack, thanks for NX. But lets ignore it and let the code run anyway ..." :p
Well, the next step can be to pop up a message box of some kind, and let the user decide whether to proceed or not. It still gives more control than blindly making all pages executable from the start...
I think this is a classic case of forcing programmer indecision on the user. Most users will not be able to answer such a question properly, so they'll end up clicking yes anyway.
Microsoft has done the correct thing by not forcing this on the user. If the question can't be answered automatically, the default should be what works for everything.
Mike
Mike McCormack mike@codeweavers.com writes:
I think this is a classic case of forcing programmer indecision on the user. Most users will not be able to answer such a question properly, so they'll end up clicking yes anyway.
Microsoft has done the correct thing by not forcing this on the user. If the question can't be answered automatically, the default should be what works for everything.
My impression from reading MSDN is that Windows pops up a message box too, but I don't have a way of confirming this. And I'm not convinced that "make everything work and ignore security" is the right default, we all know how well this worked for Windows.
Alexandre Julliard wrote:
My impression from reading MSDN is that Windows pops up a message box too, but I don't have a way of confirming this. And I'm not convinced that "make everything work and ignore security" is the right default, we all know how well this worked for Windows.
Sure, don't ignore security, but there's not point in asking users questions they don't know how to answer.
90% of the time the right answer is going to be "let the program continue", so if users keep seeing this dialog box like this:
/-----------------------------------------\ | foo.exe did something questionable | | that you probably won't understand. | | Is that OK? | | [Yes] [No] | -----------------------------------------/
they'll be trained to say "yes". A programmer might know the correct answer, but that doesn't help users.
If you can't determine the right answer automagically, I don't see the point in bugging the user for it, as they're not going to know any better.
Mike
Mike McCormack mike@codeweavers.com writes:
If you can't determine the right answer automagically, I don't see the point in bugging the user for it, as they're not going to know any better.
The real question is "do you care enough about security to not want broken apps to run?". That's obviously not a question that we can answer automatically. Of course it can be hidden in a winecfg setting instead of popping up a message box, but then it means you have to be insecure by default, because you can't have apps simply die and tell users "you should have toggled that obscure setting in winecfg".
So the idea is to default to secure until the user explicitly said otherwise; and the message box is a way to make it easier for users to tell us that they don't care about security. I suppose the alternative is to say that people should turn off no-exec in the kernel if they don't want security, but that's not exactly user-friendly either.
On Thu, Nov 16, 2006 at 09:38:27AM +0100, Alexandre Julliard wrote:
Mike McCormack mike@codeweavers.com writes:
I think this is a classic case of forcing programmer indecision on the user. Most users will not be able to answer such a question properly, so they'll end up clicking yes anyway.
Microsoft has done the correct thing by not forcing this on the user. If the question can't be answered automatically, the default should be what works for everything.
My impression from reading MSDN is that Windows pops up a message box too, but I don't have a way of confirming this. And I'm not convinced that "make everything work and ignore security" is the right default, we all know how well this worked for Windows.
I tried the XnView example on my Windows XP and it just started the program without any questions or messageboxes.
Ciao, Marcus
Marcus Meissner marcus@jet.franken.de writes:
I tried the XnView example on my Windows XP and it just started the program without any questions or messageboxes.
Does your XP box have no-exec protection? Could you investigate a bit more what the behavior is WRT stack, heap, executable sections, etc.?
AFAIK by default Windows XP enables the no-exec protection only for "essential Windows programs and services". I couldn't find what that means but it's described as if it is a fixed list of Windows system binaries. The protection can enabled for all programs (except for a list provided by the user) in System Properties > Advanced > Performance > Data Execution Protection. Then when a program executs data it is killed and a dialog like this is shown: http://img.microsoft.com/library/media/1033/technet/images/prodtechnol/winxp... . After clicking Change Settings the list already contains the buggy program and it's enough to check the checkbox for the program to work the next time. AFAIK this OptOut mode is the default for Windows Server 2003. Apart from these OptIn and OptOut modes by a manual change of system boot params it's possible to set AlwaysOn and AlwaysOff modes. Also the documentation says that the DEP is always enabled for x64 programs regardless for the NoExecute setting.
Mikolaj Zalewski
So for fixing some _broken_ applications this patch unconditionally disables nx protection for every application running under wine. Seems like a bad tradeoff imo. (Though I don't know how widespread these kind of broken applications are. But there are definitly applications out there which don't need this.)
Most of Windows applications will not work. Especialy games. Yes there some applications that work but this is mostly small applications without complex GUI. Some example are Proxomitron (this is a proxy) and mdict (simple 9KB program with graphical interface). But most users use Wine for Games and for applications with complex GUI (complex GUI = complex application in most cases). Just try 10-20 popular games and 10-20 popular applications - most of them will crash without McCormack's patch or with noexec=on. Even if real problem is because of broken PE header this doesn't matter - we must emulate typical Windows behavior in such case (at least by default).
This way would have the advantage that the behaviour is tunable either globally or on a per-app basis.
That's great but what is the default behavior? By default Wine must work in compatibility mode with not-noexec-aware programs. And only if advanced user (simple user just want to run his apps and nothing more) want to try noexec protection with his Windows application it should be activated via registy (globally or for specific app). Otherwise it will be really major regression (most application will crash).
What I want to say that Wine must work out-of-the-box in all cases where this is possible - this is what most users expect.
L. Rahyen schrieb:
So for fixing some _broken_ applications this patch unconditionally disables nx protection for every application running under wine. Seems like a bad tradeoff imo. (Though I don't know how widespread these kind of broken applications are. But there are definitly applications out there which don't need this.)
Most of Windows applications will not work. Especialy games. Yes there some applications that work but this is mostly small applications without complex GUI. Some example are Proxomitron (this is a proxy) and mdict (simple 9KB program with graphical interface). But most users use Wine for Games and for applications with complex GUI (complex GUI = complex application in most cases). Just try 10-20 popular games and 10-20 popular applications - most of them will crash without McCormack's patch or with noexec=on. Even if real problem is because of broken PE header this doesn't matter - we must emulate typical Windows behavior in such case (at least by default).
This way would have the advantage that the behaviour is tunable either globally or on a per-app basis.
That's great but what is the default behavior? By default Wine must work in compatibility mode with not-noexec-aware programs. And only if advanced user (simple user just want to run his apps and nothing more) want to try noexec protection with his Windows application it should be activated via registy (globally or for specific app). Otherwise it will be really major regression (most application will crash).
As I said, I don't know how many application are affected by this.For the ones I tested it was only a minority(though i didn't tested that many). But I wouldn't even argue that much against enabling compatibility mode by default (if it would break the majority of the applications otherwise). I was only in favor of making it adjustible at all.
What I want to say that Wine must work out-of-the-box in all cases where this is possible - this is what most users expect.
This "sacrifice everything for compatibility"-strategy is imo exactly the reason why there are still so many broken applications out there. If MS had this protection enabled by default there would be more whining users for sure, but also more pressure on the vendors to fix their applications. But I guess everybody has different priorities, thats why it should be a configurable option.
On Wednesday November 15 2006 19:25, Marcus Meissner wrote:
This is incorrect, even with NX most applications will work. Only those with broken PE headers like above will not.
For me (at least) this is correct. Most of my application crashes. Even classical games like Unreal Tournament crashes.
On Wednesday November 15 2006 19:20, Peter Beutner wrote:
What I want to say that Wine must work out-of-the-box in all cases where this is possible - this is what most users expect.
This "sacrifice everything for compatibility"-strategy is imo exactly the reason why there are still so many broken applications out there.
Read carefully. I said "Wine must work out-of-the-box in all cases where this is possible". I didn't said "Wine must work out-of-the-box, enabling write access to all hard drives to all programs, don't care about security at all, etc.". If we can implement something without sacrificing minor security (which is NX-protection issue for Wine) - good. But if not - workaround is better than nothing.
But I wouldn't even argue that much against enabling compatibility mode by
default
(if it would break the majority of the applications otherwise). I was only in favor of making it adjustible at all.
User must have simple way to choose what he wants. User (especialy newbie) wants to run his apps and not to tweak registry. I agree with AJ - implementing configurable pop up is good idea.
If MS had this protection enabled by default there would be more whining users for sure, but also more pressure on the vendors to fix their applications. But I guess everybody has different priorities, thats why it should be a >
configurable option.
I agree. Configurable option is great. Especialy if even newbie can use it by default.
On Wed, Nov 15, 2006 at 06:09:40PM +0000, L. Rahyen wrote:
So for fixing some _broken_ applications this patch unconditionally disables nx protection for every application running under wine. Seems like a bad tradeoff imo. (Though I don't know how widespread these kind of broken applications are. But there are definitly applications out there which don't need this.)
Most of Windows applications will not work. Especialy games. Yes there some applications that work but this is mostly small applications without complex GUI. Some example are Proxomitron (this is a proxy) and mdict (simple 9KB program with graphical interface). But most users use Wine for Games and for applications with complex GUI (complex GUI = complex application in most cases). Just try 10-20 popular games and 10-20 popular applications - most of them will crash without McCormack's patch or with noexec=on. Even if real problem is because of broken PE header this doesn't matter - we must emulate typical Windows behavior in such case (at least by default).
This is incorrect, even with NX most applications will work. Only those with broken PE headers like above will not.
This way would have the advantage that the behaviour is tunable either globally or on a per-app basis.
That's great but what is the default behavior? By default Wine must work in compatibility mode with not-noexec-aware programs. And only if advanced user (simple user just want to run his apps and nothing more) want to try noexec protection with his Windows application it should be activated via registy (globally or for specific app). Otherwise it will be really major regression (most application will crash).
What I want to say that Wine must work out-of-the-box in all cases where this is possible - this is what most users expect.
In this case we should perhaps try to detect such applications and mark them executable accordingly.
(Like... "does any section has exec flag? if not ... make all of them exec")
Ciao, Marcus
On Wednesday November 15 2006 19:25, Marcus Meissner wrote:
In this case we should perhaps try to detect such applications and mark them executable accordingly.
(Like... "does any section has exec flag? if not ... make all of them exec")
If we implement pop up then this isn't neccessary. Anyway, this isn't solution for all cases. Some programs run, open window, but crashes soon when they attempt to execute NX-protected areas. Example is Unreal Tournament. It runs, I can choose options, player, etc. But if I try to start gave it crashes if NX enabled.
On Wednesday 15 November 2006 3:00 pm, L. Rahyen wrote:
On Wednesday November 15 2006 19:25, Marcus Meissner wrote:
In this case we should perhaps try to detect such applications and mark them executable accordingly.
(Like... "does any section has exec flag? if not ... make all of them exec")
If we implement pop up then this isn't neccessary. Anyway, this isn't solution for all cases. Some programs run, open window, but crashes soon when they attempt to execute NX-protected areas. Example is Unreal Tournament. It runs, I can choose options, player, etc. But if I try to start gave it crashes if NX enabled.
Some info on how "Data Execution Prevention" (Microsofts name for NX) works http://support.microsoft.com/kb/875352
VC8 also supports a flag called /NXCOMPAT which can be used to flag an executable as compatible with NX. This just adds the DLL characteristic IMAGE_DLLCHARACTERISTICS_NX_COMPAT to the executable to "opt-in" to DEP
Marcus Meissner schrieb:
On Wed, Nov 15, 2006 at 06:09:40PM +0000, L. Rahyen wrote:
So for fixing some _broken_ applications this patch unconditionally disables nx protection for every application running under wine. Seems like a bad tradeoff imo. (Though I don't know how widespread these kind of broken applications are. But there are definitly applications out there which don't need this.)
Most of Windows applications will not work. Especialy games. Yes there some applications that work but this is mostly small applications without complex GUI. Some example are Proxomitron (this is a proxy) and mdict (simple 9KB program with graphical interface). But most users use Wine for Games and for applications with complex GUI (complex GUI = complex application in most cases). Just try 10-20 popular games and 10-20 popular applications - most of them will crash without McCormack's patch or with noexec=on. Even if real problem is because of broken PE header this doesn't matter - we must emulate typical Windows behavior in such case (at least by default).
This is incorrect, even with NX most applications will work. Only those with broken PE headers like above will not.
There are still those apps which allocate some memory( read-writeable only), extract/decrypt some code into that memory and then try to run it. These won't work either.