Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  newsreader  groups  login

Message-ID:  

Experience varies directly with equipment ruined.


devel / comp.lang.c / Compile-time alternative to LD_PRELOAD

SubjectAuthor
* Compile-time alternative to LD_PRELOADFrederick Gotham
`- Re: Compile-time alternative to LD_PRELOADManfred

1
Compile-time alternative to LD_PRELOAD

<39e9a38c-db8b-4e60-8a2e-08f3905731f4n@googlegroups.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17548&group=comp.lang.c#17548

  copy link   Newsgroups: comp.lang.c
X-Received: by 2002:ac8:6b0f:: with SMTP id w15mr21409673qts.366.1626698800523;
Mon, 19 Jul 2021 05:46:40 -0700 (PDT)
X-Received: by 2002:a37:5d5:: with SMTP id 204mr23867007qkf.17.1626698800359;
Mon, 19 Jul 2021 05:46:40 -0700 (PDT)
Path: i2pn2.org!i2pn.org!weretis.net!feeder8.news.weretis.net!proxad.net!feeder1-2.proxad.net!209.85.160.216.MISMATCH!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.c
Date: Mon, 19 Jul 2021 05:46:40 -0700 (PDT)
Injection-Info: google-groups.googlegroups.com; posting-host=92.40.195.117; posting-account=w4UqJAoAAAAYC-PItfDbDoVGcg0yISyA
NNTP-Posting-Host: 92.40.195.117
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <39e9a38c-db8b-4e60-8a2e-08f3905731f4n@googlegroups.com>
Subject: Compile-time alternative to LD_PRELOAD
From: cauldwel...@gmail.com (Frederick Gotham)
Injection-Date: Mon, 19 Jul 2021 12:46:40 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
 by: Frederick Gotham - Mon, 19 Jul 2021 12:46 UTC

I have a special audio driver that needs additional clean-up when the ALSA (Advanced Linux Sound Architecture) function, 'snd_pcm_close', is called.

This additional clean-up can't take place inside the C code for the audio driver, and so it must happen inside the ALSA library 'libasound.so' whenever a process calls 'snd_pcm_close'. To make things a little more complicated, 'libasound.so' is a pre-compiled binary for which I don't have the source code (a 3rd party has already made alterations to 'alsa-lib' and they won't give me the source code).

I could create a small shared library file with just one function 'snd_pcm_close', and then when I start any program that uses ALSA, I can use LD_PRELOAD as follows:

LD_PRELOAD=my_small_library.so some_program_that_uses_sound

This would be fine if I only had one or two programs that use sound, and if this rarely changed.

I'm looking for a solution though that will work with *any* program that links with 'libasound.so'. So here's what I did:

Step 1) Rename the original library
mv libasound.so libAsound.so
Step 2) Change the 'soname' inside the original library
sed -i 's/libasound.so/libAsound.so/g' libAsound.so
Step 3) Write my own small library containing one function 'snd_pcm_close'
(see the source code for this library at the end of this post)
Step 4) Build my own small library to link with the original renamed library:
gcc -o libasound.so.2.0.0 my_small_library.c -ldl -L./ -l:libAsound..so.2.0.0 -Wl,-soname,libasound.so.2

So then when any process (for example 'baresip') links with 'libasound.so', here's what will happen:

a) baresip links with our small library libasound.so
b) libasound.so links with the original library named libAsound.so
c) So now both shared libraries, libasound.so and libAsound.so, have been loaded into the address space of baresip
d) Since libasound.so was loaded before libAsound.so, the function 'snd_pcm_open' is taken from my small library
e) All other functions such as 'snd_pcm_open' and 'snd_pcm_writei' are of course missing from our small library, but the Linux operating system automatically finds these functions in any other library that's linked in, and hence finds them in libAsound.so

I have tested this out and it works. What surprises me though is that I can't find a similar implementation to this on the internet -- I mean surely somebody has done this before? If anyone can suggest a better way of doing this, I'm all ears.

Source code for my small shared library:

#include <dlfcn.h> /* dlopen, dlsym, dlclose */

static void Patch_Code(void); /* Defined lower down in this file */

int snd_pcm_close(void *arg)
{ int retval = -1; /* ALSA manual says "Zero on success, or a negative value on error" */

void *const dlhandle = dlopen("libAsound.so", RTLD_NOW|RTLD_LOCAL); /* Load original lib */

if ( dlhandle )
{
int (*const snd_pcm_close_PROPER)(void*) = dlsym(dlhandle, "snd_pcm_close");

if ( snd_pcm_close_PROPER ) retval = snd_pcm_close_PROPER(arg); /* Call original func */

dlclose(dlhandle);
}

Patch_Code(); /* <--------------- Our patch is invoked here */

return retval;
}

static void Patch_Code(void)
{ /* We put our patch in here */
}

Re: Compile-time alternative to LD_PRELOAD

<sd3v73$1n85$1@gioia.aioe.org>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17549&group=comp.lang.c#17549

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!aioe.org!Puiiztk9lHEEQC0y3uUjRA.user.46.165.242.75.POSTED!not-for-mail
From: non...@add.invalid (Manfred)
Newsgroups: comp.lang.c
Subject: Re: Compile-time alternative to LD_PRELOAD
Date: Mon, 19 Jul 2021 15:37:39 +0200
Organization: Aioe.org NNTP Server
Message-ID: <sd3v73$1n85$1@gioia.aioe.org>
References: <39e9a38c-db8b-4e60-8a2e-08f3905731f4n@googlegroups.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Info: gioia.aioe.org; logging-data="56581"; posting-host="Puiiztk9lHEEQC0y3uUjRA.user.gioia.aioe.org"; mail-complaints-to="abuse@aioe.org";
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.12.0
X-Notice: Filtered by postfilter v. 0.9.2
Content-Language: en-US
 by: Manfred - Mon, 19 Jul 2021 13:37 UTC

On 7/19/2021 2:46 PM, Frederick Gotham wrote:
> I have tested this out and it works. What surprises me though is that I can't find a similar implementation to this on the internet -- I mean surely somebody has done this before? If anyone can suggest a better way of doing this, I'm all ears.

I think this is one of those things where "I tried and it works" may be
misleading.
In my experience Linux DSO's are somewhat diverse across implementations
- for example I seem to remember that selinux may disable LD_PRELOAD on
some systems for security reasons; or the algorithm to resolve symbols
may be more complicated than just looking them up in whatever library
happens to be loaded.

That said, I have been using the LD_PRELOAD trick myself, but in that
case it was for one system only, so making it work for that specific box
was good enough for me.

One useful resource is

https://www.akkadia.org/drepper/dsohowto.pdf

which explains a lot about Linux DSO's, although it probably doesn't
address your requirement in full detail.

PS.
> This additional clean-up can't take place inside the C code for the audio driver, and so it must happen inside the ALSA library 'libasound.so' whenever a process calls 'snd_pcm_close'. To make things a little more complicated, 'libasound.so' is a pre-compiled binary for which I don't have the source code (a 3rd party has already made alterations to 'alsa-lib' and they won't give me the source code).

That sounds weird, alsa-lib is LGPL, so any modification has to be LGPL
as well, isn't it?

1
server_pubkey.txt

rocksolid light 0.9.8
clearnet tor