Thread View: comp.unix.programmer
5 messages
5 total messages
Started by Arthur Gold
Thu, 07 Oct 1999 00:00
Multiple instances of libc (ELF shared object)
Author: Arthur Gold
Date: Thu, 07 Oct 1999 00:00
Date: Thu, 07 Oct 1999 00:00
26 lines
1665 bytes
1665 bytes
Perhaps someone can help me here. I have a need, within a shared object, to have multiple instances of libc in my address space (this has to do with tracing library access), one to be linked dynamically (by the process that uses the shared object) and one explicitly dlopen()-ed. Even worse, I need to make sure that the libraries don't "communicate", i.e.that functions in the dlopen()-ed version do not accesss code in the normally linked instance. The straightforward approach does _not_ work as needed, functions from the 'private' (dlopen()-ed) instance "see" the 'public' version's code when functions called from within dlsym()-ed calls are linked. In addition, using multiple libcs seems to mess with the environment (after dlopen()-ing the second libc, the __environ variable changes) in ways I don't really understand (yet ;-) ). Any help would be greatly appreciated! TIA, --ag -- Artie Gold, Austin, TX mailto:agold@bga.com or mailto:agold@cs.utexas.edu -- Pet peeve: "its" = belonging or pertaining to "it" | "it's" = "it is"
Re: Multiple instances of libc (ELF shared object)
Author: John Hickin
Date: Thu, 07 Oct 1999 00:00
Date: Thu, 07 Oct 1999 00:00
23 lines
1369 bytes
1369 bytes
Even Microsoft advises against this chicanery (for those with VC6 search on LNK4096). I doubt that the Unix community would sanction this type of thing either (and I don't know if Unix environments even let you do it). Suppose, for example, that you execute: void* ptr = malloc(42); // malloc bound to libc #1 and subsequently do free( ptr ); // free bound to libc #2 You are hosed, well and truely. Similar _opportunities_, somewhat disguised, occur with tempnam/free and strdup/free. Cheers, John. Arthur Gold wrote: > > Perhaps someone can help me here. > > I have a need, within a shared object, to have multiple instances of > libc in my address space (this has to do with tracing library access),
Re: Multiple instances of libc (ELF shared object)
Author: Arthur Gold
Date: Fri, 08 Oct 1999 00:00
Date: Fri, 08 Oct 1999 00:00
55 lines
2832 bytes
2832 bytes
Alas, I need this functionality for a _very specific_ reason (yes, I know it's specifically _not_ something you want to be able to do general--and I'm quite familiar with the fact that malloc()--and functions that _call_ malloc() "behind the scenes"--and free() will hose ya): a need to trace library access. In order to do this, we protect the pages containing the library's code and data and notice (and fix) the seg faults that occur. The problem, of course, is that if you protect the page containing mprotect(), you've locked the keys in the car! (and if you just punt and _not_ protect that page, you lose accuracy in the trace)... In addition, we do _not_ want to notice accesses that occur in the tracing code itself (i.e. while the faults are being handled). hence the conundrum. Further, we can always wrap malloc to either just plain forbid its use, or to appropriately dispatch the allocation requests. While it _is_ a hack in a certain sense, because the goal is to observe the running code, I believe it to be a princpled one. IOW, I'm familiar with the "why not"s...and can account for them--but I need to do it anyway!!!! Thanks. --ag John Hickin wrote: > > Even Microsoft advises against this chicanery (for those with VC6 search > on LNK4096). I doubt that the Unix community would sanction this type of > thing either (and I don't know if Unix environments even let you do it). > > Suppose, for example, that you execute: > > void* ptr = malloc(42); // malloc bound to libc #1 > > and subsequently do > > free( ptr ); // free bound to libc #2 > > You are hosed, well and truely. Similar _opportunities_, somewhat > disguised, occur with tempnam/free and strdup/free. > > Cheers, John. > > Arthur Gold wrote: > > > > Perhaps someone can help me here. > > > > I have a need, within a shared object, to have multiple instances of > > libc in my address space (this has to do with tracing library access), -- Artie Gold, Austin, TX mailto:agold@bga.com or mailto:agold@cs.utexas.edu -- Pet peeve: "its" = belonging or pertaining to "it" | "it's" = "it is"
Re: Multiple instances of libc (ELF shared object)
Author: Chris Torek
Date: Sat, 09 Oct 1999 00:00
Date: Sat, 09 Oct 1999 00:00
44 lines
2368 bytes
2368 bytes
In article <37FE4E5A.E2F54AF8@bga.com> Arthur Gold <agold@bga.com> wrote: >... to trace library access. In order to do this, we protect the >pages containing the library's code and data and notice (and fix) the >seg faults that occur. The problem, of course, is that if you protect >the page containing mprotect(), you've locked the keys in the car! (and >if you just punt and _not_ protect that page, you lose accuracy in the >trace)... >In addition, we do _not_ want to notice accesses that occur in the >tracing code itself (i.e. while the faults are being handled). hence the >conundrum. A much-less-head-achey way to do this is to enumerate all of the calls you want to make directly, then write those yourself using some *other* name: .global __trace_mprotect __trace_mprotect: push $SYS_mprotect chmk bcc 0f negl $1,r0 0: ret .global __trace_write __trace_write: push $SYS_write chmk bcc 0f negl $1,r0 0: ret /* etc */ Assemble your new system call stubs and call *those* functions from your trace code. Once you have done that, only those functions whose names do *not* fit your special, easily-recognized pattern (here __trace_*) get traced. (Note that you may need to learn the local assembly language and system call conventions. The above are sort of a vague approximation to ones for the VAX, just so that no one will try to use them directly.) -- In-Real-Life: Chris Torek, Berkeley Software Design Inc El Cerrito, CA Domain: torek@bsdi.com +1 510 234 3167 http://claw.bsdi.com/torek/ (not always up) I report spam to abuse@.
Re: Multiple instances of libc (ELF shared object)
Author: Arthur Gold
Date: Tue, 12 Oct 1999 00:00
Date: Tue, 12 Oct 1999 00:00
90 lines
4507 bytes
4507 bytes
[Chris: I hope you don't mind the email response] I was taking an approach somewhat similar to this--i.e. just brute force copying of code to some safe place--and it works fine, but only for true system calls (IOW write and mprotect were fine). The problem has come with the need to segregate wrappers that are more substantial (well, not a _whole_ lot more substantial, but more substantial nevertheless) like sigprocmask(). In Linux i386 (my primary platform, though platform independence--for some value of independence--is the real goal), sigprocmask() ends up using bzero to clean out a buffer and ultimately calls __syscall_sigprocmask() which is the wrapper for the straight system call. Solaris does it differently, as I suspect *BSD might as well. My current proposed solution is to assemble a shared object containing the functions I need to segregate that links in libc statically, using the --wrap directive in ld for those particular functions to avoid polluting the namespace (this is all to be part of a shared object that will be a preloaded library). My hope is that this will give me the control I need to make sure that names don't 'leak through' to the application. Actually, there's something even somewhat prinipled in all this! As most of the work of a tracing module is done in signal handlers, only 'safe' (i.e. non malloc()-ing, non libc state-mutating functions should even be available! Damn I hope this gives me what I need! (Can someone say 'true module system'?) Comments? Many thanks. --ag [BTW, my ISPs news feed seems a little strange; this reply just popped up today] Chris Torek wrote: > > In article <37FE4E5A.E2F54AF8@bga.com> Arthur Gold <agold@bga.com> wrote: > >... to trace library access. In order to do this, we protect the > >pages containing the library's code and data and notice (and fix) the > >seg faults that occur. The problem, of course, is that if you protect > >the page containing mprotect(), you've locked the keys in the car! (and > >if you just punt and _not_ protect that page, you lose accuracy in the > >trace)... > >In addition, we do _not_ want to notice accesses that occur in the > >tracing code itself (i.e. while the faults are being handled). hence the > >conundrum. > > A much-less-head-achey way to do this is to enumerate all of the > calls you want to make directly, then write those yourself using > some *other* name: > > .global __trace_mprotect > __trace_mprotect: > push $SYS_mprotect > chmk > bcc 0f > negl $1,r0 > 0: ret > > .global __trace_write > __trace_write: > push $SYS_write > chmk > bcc 0f > negl $1,r0 > 0: ret > /* etc */ > > Assemble your new system call stubs and call *those* functions from > your trace code. Once you have done that, only those functions > whose names do *not* fit your special, easily-recognized pattern > (here __trace_*) get traced. > > (Note that you may need to learn the local assembly language and > system call conventions. The above are sort of a vague approximation > to ones for the VAX, just so that no one will try to use them directly.) > -- > In-Real-Life: Chris Torek, Berkeley Software Design Inc > El Cerrito, CA Domain: torek@bsdi.com +1 510 234 3167 > http://claw.bsdi.com/torek/ (not always up) I report spam to abuse@. -- Artie Gold, Austin, TX mailto:agold@bga.com or mailto:agold@cs.utexas.edu -- Pet peeve: "its" = belonging or pertaining to "it" | "it's" = "it is"
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads