is it possible to setsockopt() from command line - linux

I need to change the sk_rcvlowat of program applications to to performance test. Is there a way to change the socket options from command line? Otherwise, we have to change all the source code of application program and re-compile them. I guess that each socket is associated with an inode, so that we can change the socket option via the inode.
By the way, please can anyone show me where the "socket file" located when the process created it. I have already checked /proc/<pid>/fd/<fd[X]> but they are only symbolic links like this one 10 -> socket:[13895]
Any suggestions are appreciated. Thanks in advance.

You can create a wrapper library, which will intercept all calls to setsockopt and will be able to change some parameters. This works if your application have the call to setsockopt. In another case, you can wrap different function, e.g. socket using the same approach. In wrapper of socket you need to create a socket with __socket and then change any parameter you want.
Wrapper library must be a dynamic one, with setsockopt function. This function is allowed to be overloaded by glibc. Then, start your programm as follows:
LD_PRELOAD=path_to_wrapper_library/libwrap.so ./you_program
The library will be injected (linked) into programm and will replace the setsockopt function.
This works only with dynamically linked programms (check it with ldd ./you_program - there will be some /lib/*.so if it is dynamically linked).
Original function can be called from your code with __ prefix: __setsockopt or using dlsym(RTLD_NEXT, "setsockopt");.
Some examples (not a setsockopt, but the idea of preload wrapper): http://scaryreasoner.wordpress.com/2007/11/17/using-ld_preload-libraries-and-glibc-backtrace-function-for-debugging/ or http://developers.sun.com/solaris/articles/lib_interposers_code.html
Compile to dynamic library with:
gcc wrap.c -fPIC -shared -ldl -o libwrap.so

Related

LD_PRELOAD to override functions from dynamically loaded library

I'm using a wrapper library to trace functions using LD_PRELOAD which does work when the functions I'm tracing are referenced in the application.
The wrapper library uses dlsym to populate symbols it wraps.
But this is not working if the application doesn't reference functions directly but through dlopen.
Should the wrapper library work with dynamically loaded libraries? If not, is there a way to make it work?
But this is not working if the application doesn't reference functions directly but through dlopen.
If the application performs:
void *h = dlopen("libfoo.so", ...);
void *sym = dlsym(h, "symbol");
then the symbol will be resolved to libfoo.so, regardless of any LD_PRELOADs (and indeed regardless of any other instances of symbol in other already loaded libraries). This is working as intended.
Should the wrapper library work with dynamically loaded libraries?
No.
If not, is there a way to make it work?
Yes, you can make it work. You would need to provide a replacement.so which provides all the symbols which the application looks up in libfoo.so, and then make it so the replacement.so is dlopend()ed by the application.
One way to do that is to rename libfoo.so -> libfoo.so.orig, copy replacement.so -> libfoo.so, and have replacement.so itself dlopen("libfoo.so.orig", ...).
If the application dlopens libfoo.so without absolute path, you may be able to arrange so replacement.so is earlier in the search path, e.g.
mkdir /tmp/replacement
ln -s /path/to/replacement.so /tmp/replacement/liboo.so
LD_LIBRARY_PATH=/tmp/replacement /path/to/a.out
If you go that route, replacement.so would still need to know how to dlopen the original libfoo.so (could use hard-coded absolute path for that).

Is it possible to start a program with a missing shared library

I'm running Linux and have a situation like this:
A binary file 'bin1' loads via dlopen 'shared1.so' which is linked with 'shared2.so' and 'shared3.so'.
if 'shared2.so' or 'shared3.so' is missing the program 'bin1' won't run.
There are runs that I know that I won't touch any code from 'shared2.so' and I want 'bin1' to be able to run even when this library is missing, can this be done ?
You could ship program with dummy shared2.so library. You might need to add dummy functions which shared1 expects to find there. This can be done manually or via automatic tool like Implib.so.

When a shared library is loaded, is it possible that it references something in the current binary?

Say I have a binary server, and when it's compiled, it's linked from server.c, static_lib.a, and dynamically with dynamic_lib.so.
When server is executed and it loads dynamic_lib.so dynamically, but on the code path, dynamic_lib.so actually expects some symbols from static_lib.a. What I'm seeing is that, dynamic_lib.so pulls in static_lib.so so essentially I have two static_lib in memory.
Let's assume there's no way we can change dynamic_lib.so, because it's a 3rd-party library.
My question is, is it possible to make dynamic_lib.so or ld itself search the current binary first, or even not search for it in ld's path, just use the binary's symbol, or abort.
I tried to find some related docs about it, but it's not easy for noobs about linkers like me :-)
You can not change library to not load static_lib.so but you can trick it to use static_lib.a instead.
By default ld does not export any symbols from executables but you can change this via -rdynamic. This option is quite crude as it exports all static symbols so for finer-grained control you can use -Wl,--dynamic-list (see example use in Clang sources).

Linux library code injection & calls to identically named functions in SOs

I have built a linux shared object which I inject into a 3rd party program to intercept some dynamic function calls using LD_PRELOAD.
The 3rd party program uses a SO "libabc.so" located at some path. My injected SO uses another SO, also called "libabc.so" located at another path (essentially identical but slight code differences).
My problem is now, that calls to a function "def" which appear in both libabc.so are always resolved by the first. (Presumably because it is loaded first?!) How can I get them to be resolved with the second libabc.so?
Many thanks!
Unless something changed since I used to do this, you will need to dlopen() the library you want to pass calls on to and call the function manually, something like;
handle = dlopen("/path/to/libabc.so", RTLD_LAZY);
otherDef = dlsym(handle, "def");
orderDef(parameter);
There is a complete example how to do this very thing at LinuxJournal.
If you only want to use one libabc.so version, you can always use LD_PRELOAD to load it along with your own shared object before anything else.
If you want to use multiple versions, you have a few alternatives:
Use dlopen() in your shared object to load that library. Since you have created a function injection object you should be familiar with this procedure. This is the more generic and powerful way - you could even mix & match functions from different library versions.
Use a different DT_SONAME for the library version your shared object links against. Unfortunately this requires (slightly) changing the build system of that library and recompiling.
Link your shared object statically against the library in question. Not always possible but it does not require modifying the library in question. The main issue with this alternative is that any change in the library should be followed by a relinking of your shared object for the changes to be pulled in.
Warning: you may need to use a custom linker script or specific linker options to avoid symbol conflicts.

How to check Shared Library exposed functions in program

I am using a third party shared library and I need to check whether a function is exported by shared library programatically.
How to do this. I need this because if function does not exist I need to run some other function locally.
You could probably use dlsym for this.
If you load the library with dlopen, you will use the handle that it returns.
If you're linked against this library you may use special pseudo-handles (10x to caf for pointing it out):
From dlsym man:
There are two special pseudo-handles, RTLD_DEFAULT and RTLD_NEXT. The former will find the first occurrence of the desired symbol using the default library search order. The latter will find the next occurrence of a function in the search order after the current library. This allows one to provide a wrapper around a function in another shared library.
Check the header file of the intended library to get the function signature.
Using dlopen you can load the library dynamically and fetch the symbol if it is exposed in the library with subsequent calls to dlsym and dlclose.
may be you can use objdump command to check all symbol exposed like this
objdump -T libtest.so

Resources