https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=859c10beeeaaf1e0a1964118973aca1bc0460a51

commit 859c10beeeaaf1e0a1964118973aca1bc0460a51
Author: Corinna Vinschen <cori...@vinschen.de>
Date:   Tue Aug 25 22:15:22 2015 +0200

    autload.cc: Avoid clobbering return address in noload on i686
    
        This fixes a long-standing problem when GetProcAddress fails
        to load a function.  The noload code calls SetLastError on
        i686 without saving the edx register.  Starting with Windows 7,
        SetLastError apparently uses $edx and the register is set to
        0x00000000 on return.  So the subsequent `jmp *$edx' in noload
        supposed to return to the caller, actually jumps to address NULL,
        which results in a SEGV.
    
            * autoload.cc (noload): i686 only: Save and restore $edx when 
calling
            SetLastError to avoid clobbering return address stating with 
Windows 7.
    
    Signed-off-by: Corinna Vinschen <cori...@vinschen.de>

Diff:
---
 winsup/cygwin/ChangeLog   | 5 +++++
 winsup/cygwin/autoload.cc | 6 ++++--
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index a23f835..c10d074 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,10 @@
 2015-08-25  Corinna Vinschen  <cori...@vinschen.de>
 
+       * autoload.cc (noload): i686 only: Save and restore $edx when calling
+       SetLastError to avoid clobbering return address stating with Windows 7.
+
+2015-08-25  Corinna Vinschen  <cori...@vinschen.de>
+
        * mmap.cc: Fix a few comments.
 
 2015-08-24  Corinna Vinschen  <cori...@vinschen.de>
diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc
index 4299e3a..8f9823b 100644
--- a/winsup/cygwin/autoload.cc
+++ b/winsup/cygwin/autoload.cc
@@ -254,11 +254,13 @@ noload:                                                   
                \n\
        addl    %eax,%esp       # Pop off bytes                         \n\
        andl    $0xffff0000,%eax# upper word                            \n\
        subl    %eax,%esp       # adjust for possible return value      \n\
-       pushl   %eax            # Save for later                        \n\
+       pushl   %eax            # Save return value for later           \n\
+       pushl   %edx            # Save return address for later         \n\
        movl    $127,%eax       # ERROR_PROC_NOT_FOUND                  \n\
        pushl   %eax            # First argument                        \n\
        call    _SetLastError@4 # Set it                                \n\
-       popl    %eax            # Get back argument                     \n\
+       popl    %edx            # Get back return address               \n\
+       popl    %eax            # Get back return value                 \n\
        sarl    $16,%eax        # return value in high order word       \n\
        jmp     *%edx           # Return                                \n\
 1:                                                                     \n\

Reply via email to