I've compiled an example program from O'Reilly book which uses basic 
socket BIO routines. But it crashes when executed with memory access 
exception in function BIO_new_accept.
I used Openssl-1.0.0-beta4 built under win32 (windows XP SP3) using MSVC 
2005 as described in INSTALL.W32:

$ perl Configure VC-WIN32 enable-static-engine
$ ms\do_nasm.bat
$ nmake -f ms\ntdll.mak

The error is caused by a dynamic call of WINAPI function getaddrinfo. 
This function uses stdcall call convention, but called as cdecl.

MSVC

1004F8F3    51              PUSH ECX
1004F8F4    56              PUSH ESI
1004F8F5    53              PUSH EBX
1004F8F6    FF15 3CE81110   CALL DWORD PTR DS:[1011E83C]             ; 
WS2_32.getaddrinfo
1004F8FC    83C4 10         ADD ESP,10                               ; 
stack was damaged
1004F8FF    85C0            TEST EAX,EAX
1004F901    0F84 AF000000   JE LIBEAY32.1004F9B6
...
1004F9B6    8B7424 14       MOV ESI,DWORD PTR SS:[ESP+14]         
1004F9BA    8B46 10         MOV EAX,DWORD PTR DS:[ESI+10]            ; 
exception here
1004F9BD    83F8 1C         CMP EAX,1C
1004F9C0    76 05           JBE SHORT LIBEAY32.1004F9C7


As a result the stack is damaged and the pointer to the returned value, 
which address is in a stack, is bad, thus leading to exception.

The problem is in the declaration of pointer to function addrinfo:

b_sock.c (line 629)

    static union {    void *p;
            int (*f) (const char *, const char *, <- bug (should be "int 
(__stdcall *f)")
                 const struct addrinfo *,
                 struct addrinfo **);
            } p_getaddrinfo = {NULL};


First we tried to compile openssl with stdcall call convention by 
default (-mrtd compiler switch) but it leaded to problems in the module 
mem.c at point of getting pointers and use of functions for work with 
memory (which use cdecl call convention).
We sloved the problem by correcting the declarations of p_getaddrinfo, 
p_freeaddrinfo and p_getnameinfo unions (see patch below). After 
correction of these declaration the library compiles and works correctly.
In earlier versions (0.9.8l, 0.9.8h) this problem it is not present 
because dynamic call of Win32 API is not used there.

Eugeniy Gostyukhin [[email protected]]
Peter Ivanov [[email protected]]

--- C:/openssl-1.0.0-beta4/crypto/bio/b_sock.c    Mon Nov  9 17:09:54 2009
+++ C:/openssl-1.0.0-beta4-patched/crypto/bio/b_sock.c    Fri Dec 25 
13:36:53 2009
@@ -88,6 +88,13 @@
 static int wsa_init_done=0;
 #endif
 
+#ifdef OPENSSL_SYS_WINDOWS
+#define ADDRINFO_CONVENTION __stdcall
+#else
+#define ADDRINFO_CONVENTION
+#endif
+
+
 #if 0
 static unsigned long BIO_ghbn_hits=0L;
 static unsigned long BIO_ghbn_miss=0L;
@@ -627,12 +634,12 @@
 #ifdef EAI_FAMILY
     do {
     static union {    void *p;
-            int (*f)(const char *,const char *,
+            int (ADDRINFO_CONVENTION *f)(const char *,const char *,
                  const struct addrinfo *,
                  struct addrinfo **);
             } p_getaddrinfo = {NULL};
     static union {    void *p;
-            void (*f)(struct addrinfo *);
+            void (ADDRINFO_CONVENTION *f)(struct addrinfo *);
             } p_freeaddrinfo = {NULL};
     struct addrinfo *res,hint;
 
@@ -839,7 +846,7 @@
     char   h[NI_MAXHOST],s[NI_MAXSERV];
     size_t nl;
     static union {    void *p;
-            int (*f)(const struct sockaddr *,size_t/*socklen_t*/,
+            int (ADDRINFO_CONVENTION *f)(const struct sockaddr 
*,size_t/*socklen_t*/,
                  char *,size_t,char *,size_t,int);
             } p_getnameinfo = {NULL};
             /* 2nd argument to getnameinfo is specified to


______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [email protected]
Automated List Manager                           [email protected]

Reply via email to