|Portable OpenSSL for Linux|
Tags: shared-object linux openssl scribe
|A year ago I worked out how to make a portable build of OpenSSL for Mac. And now with the imminent release of the Linux build of Scribe I need to do the same with the Linux build of OpenSSL.|
After downloading and unpacking OpenSSL I configured it with:
./config shared -DPURIFYThe reason for adding the -DPURIFY #define is to suppress valgrind errors related to uninitialized memory usage.
Once that is built I had a look at the shared object paths with ldd:
matthew@ubuntu:~/Downloads/openssl$ ldd ./libssl.so.1.0.0 linux-vdso.so.1 => (0x00007ffc0e197000) libcrypto.so.1.0.0 => /lib/x86_64-linux-gnu/libcrypto.so.1.0.0 (0x00007f5c5ab6c000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5c5a7a7000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f5c5a5a3000) /lib64/ld-linux-x86-64.so.2 (0x00007f5c5b1c1000)So it's not portable yet. I initially tried using the chrpath command but it can only modify existing RPATH records. My binary doesn't have any RPATH yet. So that didn't work. The next thing I tried was the patchelf command from here:
http://nixos.org/releases/patchelf/patchelf-0.8/After building and installing I issued this command in the OpenSSL folder:
patchelf --set-rpath '$ORIGIN' ./libssl.so.1.0.0Now to check if libssl pulls in the local libcrypto:
matthew@ubuntu:~/Downloads/openssl$ ldd ./libssl.so.1.0.0 linux-vdso.so.1 => (0x00007ffcdce86000) libcrypto.so.1.0.0 => /home/matthew/Code/Scribe/trunk/./libcrypto.so.1.0.0 (0x00007f39b99d8000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f39b9613000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f39b940f000) /lib64/ld-linux-x86-64.so.2 (0x00007f39ba0a5000)Yes! Now this build can be installed in the same folder as the Scribe binary and Scribe will use it without interfering with the system OpenSSL which is often out of date, or not built with -DPURIFY or missing.
|(0) Comments | Add Comment|
|Portable OpenSSL on Mac OS X|
Tags: dylib openssl
|So it's been brought to my attention that Scribe's self install of OpenSSL on Mac doesn't actually work in v2.0.x, so the last week I've been looking into what it takes to do that.|
The main issue is that load paths, are by default, absolute and hardcoded. Which works against you when you want a portable install of something. Secondly the OpenSSL .dylib is made of 2 libraries; libssl and libcrypt. And when you dlopen the first (libssl) the system needs to be able to find libcrypt. The link is embedded in the Mach-O image as a LC_LOAD_DYLIB segment. You can see that by issue the command:
otool -l ./libssl.1.0.0.dylibPart of the output you'll get:
cmd LC_LOAD_DYLIB cmdsize 64 name /usr/lib/libcrypto.1.0.0.dylib (offset 24) time stamp 2 Thu Jan 1 10:00:02 1970That absolute path is what is causing the dlopen of libssl to fail. So we need to fix that. And the tool to do it 'install_name_tool', which is provided from Apple. Now I had two problems. Firstly what do you change the path to? And how do you actually get the tool to change the path?
Firstly Apple has several ways of locating shared libraries:
But how to call install_name_tool to actually do that? Well to start with I tried:
install_name_tool -change /usr/lib/libcrypto.1.0.0.dylib @executable_path/libcrypto.1.0.0.dylib ./libssl.1.0.0.dylibWhich is actually the right command. But because the new string is longer than the old string the command fails (silently I might add). The trick to getting it to work is to add the linker command:
-Wl,-headerpad_max_install_namesto the CFLAG variable in the OpenSSL root Makefile. This causes the load segments to have extra padding bytes so that you can change the paths as much as you want later. Now after rebuilding the OpenSSL dylibs you can reissue the install_name_tool command and the link path changes:
MacOS matthew$ otool -l ./libssl.1.0.0.dylib ... cmd LC_LOAD_DYLIB cmdsize 64 name @executable_path/libcrypto.1.0.0.dylib (offset 24) ...Then I could dlopen 'libssl.1.0.0.dylib' and it would pull in the right libcrypt file (both as sitting in the same folder as the executable).
I'm putting this here so I don't forget how to do this next time. Ha.
|(3) Comments | Add Comment|