[fpc-pascal] access violation somehow related to dlopen'ing libssl

Seth Grover sethdgrover at gmail.com
Fri Jul 2 17:11:32 CEST 2010


Greetings once again! I've run into a little bit of a strange problem
that I'm hoping someone here will be able to help me figure out.

I'm using, as I suspect some of you may be, the excellent synapse
project (http://ararat.cz/synapse). I have a simple 64-bit project
which consists only of:
========================================================
program syna64test;

{$mode objfpc}{$H+}

uses
  ssl_openssl;

begin
end.
========================================================

Admittedly, to get this to compile I had to remove the "libc"
dependency from synapse's  ssl_openssl_lib.pas, but I can't see how
that would be a problem since it's not used by anything in that unit
and compiles fine without it.

So, as you can see, this program doesn't do anything except call
ssl_openssl's initialization code, which ends up in a function called
InitSSLInterface in ssl_openssl_lib.pas, which attempts to dlopen
libssl and libcrypt and then call GetProcedureAddress for various
openssl functions. Pretty standard stuff. And, of course, since libssl
isn't linked directly, ldd displays something like this:
========================================================
$ ldd syna64test
	linux-vdso.so.1 =>  (0x00007fff56bff000)
	libdl.so.2 => /lib/libdl.so.2 (0x00007fc599613000)
	libc.so.6 => /lib/libc.so.6 (0x00007fc599291000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fc59983c000)
========================================================

However, the problem I run into is if my program is linked against
something else that also depends on libssl. For a simple example, if I
attempt to also link against libssh2.so like this (I actually do have
a .pas header file for libssh2, but for the sake of simplicity in this
example I'll simply use LINKLIB):
========================================================
program syna64test;

{$mode objfpc}{$H+}
{$LINKLIB ssh2}

uses
  ssl_openssl;

begin
end.
========================================================

Now ldd shows:
========================================================
$ ldd syna64test
	linux-vdso.so.1 =>  (0x00007fffe2bd0000)
	libssh2.so.1 => /usr/lib/libssh2.so.1 (0x00007fdb393f0000)
	libdl.so.2 => /lib/libdl.so.2 (0x00007fdb391ec000)
	libssl.so.0.9.8 => /lib/libssl.so.0.9.8 (0x00007fdb38f9b000)
	libcrypto.so.0.9.8 => /lib/libcrypto.so.0.9.8 (0x00007fdb38c0b000)
	libz.so.1 => /lib/libz.so.1 (0x00007fdb389f4000)
	libc.so.6 => /lib/libc.so.6 (0x00007fdb38671000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fdb3963a000)
========================================================

When I run the program, I get:
========================================================
$ ./syna64test
An unhandled exception occurred at $00007F5DBE8026D5 :
EAccessViolation : Access violation
  $00007F5DBE8026D5
  $00007F5DBD97AF66
  $00007F5DBE3D00C4

An unhandled exception occurred at $00007F5DBE80D3C1 :
EAccessViolation : Access violation
  $00007F5DBE80D3C1
========================================================

When I run it in gdb, it crashes calling GetProcedureAddress with the
dlopen'ed handle:
========================================================
$ gdb ./syna64test
...
Reading symbols from
/media/truecrypt1/tlacuache/devel/seth/trunk/syna64test/bin/syna64test...done.
(gdb) r
Starting program:
/media/truecrypt1/tlacuache/devel/seth/trunk/syna64test/bin/syna64test

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7de66d5 in ?? () from /lib64/ld-linux-x86-64.so.2
(gdb) bt
#0  0x00007ffff7de66d5 in ?? () from /lib64/ld-linux-x86-64.so.2
#1  0x00007ffff6f5ef66 in ?? () from /lib/libc.so.6
#2  0x00007ffff79b40c4 in ?? () from /lib/libdl.so.2
#3  0x00007ffff7dea9c6 in ?? () from /lib64/ld-linux-x86-64.so.2
#4  0x00007ffff79b42ac in ?? () from /lib/libdl.so.2
#5  0x00007ffff79b407a in dlsym () from /lib/libdl.so.2
#6  0x0000000000499963 in
DYNLIBS_GETPROCEDUREADDRESS$INT64$ANSISTRING$$POINTER ()
#7  0x0000000000493acd in GETPROCADDRESS (MODULE=-134393856,
PROC=0x6bfcf8 "SSL_get_error") at src/synafpc.pas:106
#8  0x0000000000487beb in GETPROCADDR (MODULE=-134393856,
PROCNAME=0x6bfcf8 "SSL_get_error") at src/ssl_openssl_lib.pas:1688
#9  0x0000000000487cec in INITSSLINTERFACE () at src/ssl_openssl_lib.pas:1715
#10 0x0000000000433d41 in SSL_OPENSSL_init () at src/ssl_openssl.pas:818
#11 0x000000000042478e in fpc_initializeunits ()
#12 0x0000000000000000 in ?? ()
(gdb) info reg
rax            0xfffffffff7fd5388	-134392952
rbx            0x7f44c24c94e941a0	9170668375404790176
rcx            0x7ffff7fe92dd	140737354044125
rdx            0x433ee85ef9908c1f	4845565743708802079
rsi            0xfffffffff7fd5000	-134393856
rdi            0x7ffff7fe92d0	140737354044112
rbp            0x7fffffffdc50	0x7fffffffdc50
rsp            0x7fffffffdb30	0x7fffffffdb30
r8             0xffffffff	4294967295
r9             0x0	0
r10            0x7fffffffdb00	140737488345856
r11            0x7ffff6f5f360	140737336701792
r12            0x0	0
r13            0x7fffffffdd10	140737488346384
r14            0xfffffffff7fd5000	-134393856
r15            0xf9908c1f	4186999839
rip            0x7ffff7de66d5	0x7ffff7de66d5
eflags         0x10246	[ PF ZF IF RF ]
cs             0x33	51
ss             0x2b	43
ds             0x0	0
es             0x0	0
fs             0x0	0
gs             0x0	0
(gdb) info shared
>From                To                  Syms Read   Shared Object Library
0x00007ffff7ddcaf0  0x00007ffff7df5814  Yes (*)     /lib64/ld-linux-x86-64.so.2
0x00007ffff7bbc2b0  0x00007ffff7bd3ad8  Yes (*)     /usr/lib/libssh2.so.1
0x00007ffff79b3de0  0x00007ffff79b49c8  Yes (*)     /lib/libdl.so.2
0x00007ffff7776c10  0x00007ffff77a25b8  Yes (*)     /lib/libssl.so.0.9.8
0x00007ffff743d040  0x00007ffff74f82e8  Yes (*)     /lib/libcrypto.so.0.9.8
0x00007ffff71be260  0x00007ffff71cad38  Yes (*)     /lib/libz.so.1
0x00007ffff6e588c0  0x00007ffff6f69f5c  Yes (*)     /lib/libc.so.6
(*): Shared library is missing debugging information.
========================================================

The odd thing is, if I compile this program for i386, it runs fine. In
that case:
========================================================
$ ldd ./syna64test
	linux-gate.so.1 =>  (0xf77d8000)
	libssh2.so.1 => /usr/lib32/libssh2.so.1 (0xf778f000)
	libdl.so.2 => /lib32/libdl.so.2 (0xf778a000)
	libgcrypt.so.11 => /lib32/libgcrypt.so.11 (0xf7717000)
	libz.so.1 => /usr/lib32/libz.so.1 (0xf7702000)
	libc.so.6 => /lib32/libc.so.6 (0xf75a8000)
	/lib/ld-linux.so.2 (0xf77d9000)
	libgpg-error.so.0 => /lib32/libgpg-error.so.0 (0xf75a3000)
$ ./syna64test
$
========================================================

So, for some reason, when building for x86_64, the combination of my
program linking against a .so which has a libssl dependency, combined
with synapse's ssl_openssl_lib attempting to dlopen and then call
GetProcedureAddress for a procedure in libssl causes things to blow
up.

Any suggestions?

Thanks,

-SG

--
This email is fiction. Any resemblance to actual events
or persons living or dead is purely coincidental.

Seth Grover
sethdgrover[at]gmail[dot]com



More information about the fpc-pascal mailing list