C compiling with glibc, not default libraries: permission denied at runtime

this is my first stackoverflow question, so I will try to do it well.

Context:

I would like to provide a program that could work on every Linux distribution (for example, a program that will use C ++ 11 running on a system that does not have a C ++ 11 library). To do this, I would like to copy all the libraries that are used by my program and put them in a folder with an executable file, so it can use these libraries instead of the system one.

I have 2 environments for testing: - Opensuse, with (GNU libc) 2.19 - Ubuntu, with (Ubuntu EGLIBC 2.17-Oubuntu5.1) 2.17

I will compile my program under Opensuse and run it under Ubuntu. A program works well when it uses the default library.

Project:

Here is main.c:

int main(int ac, char **av) { printf("Hello World !\n"); } 

Here is the tree of my folder under Opensuse (the same in Ubuntu without main.c et exec.sh):

 + project | +--- main.c +--- a.out +--- exec.sh +---+ lib | +--- libc.so.6 +--- ld-linux-x86-64.so.2 

And finally, here is ldd and readelf when I run the program with simple compilation:

 > gcc main.c -o a.out > ldd ./a.out linux-vdso.so.1 (0x00007fff85f57000) libc.so.6 => /lib64/libc.so.6 (0x00007f1fdaaaf000) /lib64/ld-linux-x86-64.so.2 (0x00007f1dae75000) > readelf -d a.out | grep "library\|Library" 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] 

I did some research and finally found this post which explain ld-linux.so a bit.

Here is the script that I use to compile:

 #!/bin/bash dir=`pwd` execName="a.out" libDir="/lib" linker="ld-linux-x86-64.so.2" gcc main.c -o ${execName} -Wl,--rpath=${dir}${libDir} -Wl,--dynamic-linker=${dir}${libDir}/${linker} 

When I run my a.out compiler using a script on my Opensuse, I got the following:

 > ./a.out Hello World ! > ldd ./a.out linux-vdso.so.1 (0x00007f3222e27000) libc.so.6 => /path/to/project/lib/libc.so.6 (0x00007f3222a7e000) /path/to/project/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x000073222e2b000) > readelf -d a.out | grep "library\|Library" 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] 0x000000000000001d (RUNPATH) Library runpath: [/path/to/project/lib] 

Problem:

Now, when I run this a.out executable (compiled under Opensuse) on my Ubuntu, I got the following output:

 > ./a.out ./a.out: Permission denied. > ldd ./a.out linux-vdso.so.1 (0x00007fff5b5fe000) libc.so.6 => /path/to/project/lib/libc.so.6 (0x00007f47df480000) /path/to/project/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x00007f47df82a000) > readelf -d a.out | grep "library\|Library" 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] 0x000000000000001d (RUNPATH) Library runpath: [/path/to/project/lib] 

I always refuse this permission when I run the executable, and I donโ€™t know why.

I transfer my a.out and my lib folder from Opensuse to Ubuntu with Filezilla, and a.out is not executable after this transfer, so I need to do:

 chmod 755 a.out 

I have the same tree under Opensuse and Ubuntu 2 libraries in the lib folder are the default library from Opensuse

Any help in resolving the denial, or another way to do what I want, would be welcome. Thanks in advance for your help!

Note. I cannot use LD_PRELOAD, since you need to be root in order to use it, this will not work for what I want to do. I would also like to avoid static compilation, but if this is the only solution, I will think about it

+5
source share
4 answers

There are many things that may be wrong with this. Here are some suggestions.

Check file permissions for copied libraries

You mentioned that everything you use to copy a.out changes the permissions for this file. Libraries also need special permissions, so check them out.

Check for broken symbolic links

Many of these libraries are usually symbolic links to a real binary file. If you just copied the links and not the basic binaries, this will not work.

Check for Inappropriate Libraries

As you know, libc is more than just one file. For example, on my Linux machine, if I run ldd /lib64/libc.so.6 , I get this result:

 /lib64/ld-linux-x86-64.so.2 (0x0000003531200000) linux-vdso.so.1 => (0x00007ffe2c78c000) 

If you do not copy all the necessary libraries, this will not work.

Consider using -R for the linker

The -L flag tells the linker where he can find the libraries, but also the -R flag, which tells the resulting executable where to find the libraries at run time. It is not clear to me whether you need it or not.

+3
source

You can follow a simpler way to compile your application, independent of the general object. In this case, your application will be statically compiled, and you should use the -static flag.

Take a look at my example:

 $ cat main.c #include <stdio.h> int main(int ac, char **av) { printf("Hello World !\n"); } $ gcc main.c -o main -static $ ldd main not a dynamic executable 
+1
source

Any help in resolving is rejected.

This part is simple: not only a.out should be executed using chmod , but /path/to/project/lib/ld-linux-x86-64.so.2 should also be executed.

Note. I can not use LD_PRELOAD, since you need to use its root

You are mistaken: you absolutely do not need to be root to use LD_PRELOAD (unless you use it in the binary set-uid).

+1
source

Reproduce a permission error by running the application in the strace utility and analyzing the logs to isolate the real execution problem.

$ strace -fv./a.out

0
source

All Articles