This is the mail archive of the libc-alpha@sourceware.cygnus.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

symbol versioning/`hiding' system call wrappers




Here's the text of glibc FAQ 3.12:
> {AJ} With the introduction of versioning in glibc 2.1 it is possible to export only those identifiers (functions, variables) that are
> really needed by application programs and by other parts of glibc. This way a lot of internal interfaces are now hidden. nm will still
> show those identifiers but marking them as internal. ISO C states that identifiers beginning with an underscore are internal to the
> libc. An application program normally shouldn't use those internal interfaces (there are exceptions, e.g. __ivaliduser). If a program
> uses these interfaces, it's broken. These internal interfaces might change between glibc releases or dropped completely. 

You've seen (and responded, thank you)  my previous post...and now it
seems that the problem may be more general than I even originally
thought.

We use memory protection and a handler for SIGSEGV to trace virtual
memory access by a program (all of which resides in a preloaded
library). For any access that occurs in user space, we have no problem:
a SIGSEGV is generated, we record the touch, and fix the protection in
order that the program can proceed. 

System calls (or any libc call that ultimately resolves to a system
call) have problematic semantics; instead of producing a SIGSEGV, they
merely fail and set errno to EFAULT.

Before 2.1.x, we were able to interpose on the actual system call
wrapper (usually __functionname) with a wrapper of our own that would
take care of possible protection problems (those that would cause an
EFAULT), and make note of anything that needed to be `fixed'. Further,
this method meant that we could do the fixup/bookkeeping even if the
call was made within libc itself--everything would go through our
wrapper.

Now, it seems that we no longer have this ability, due to the `hiding'
of the `real' system call wrappers.

Though annoying in general, this policy change really rears its ugly
head in cases like the exec family of functions. Though they all
ultimately resolve to the system call wrapper (__execve), we can no
longer interpose on the system call wrapper itself. The only option that
remains would be to interpose on each of execv, execvp, execl,
etc.--though in each case we'd duplicating the same work, i.e.
`touching' the arguments and `touching' the environment, if needed. This
seems to be a Bad Thing.

IIRC, another place that could be problematic is longjmp (I haven't
looked at the current source yet), as it's another case where a single
`primitive', i.e. __longjmp, is used by multiple normally-exported
symbols (longjmp and siglongjmp).

In order to get around the difference in semantics between normal
user-space calls and actual system calls (i.e. the former causes a
SIGSEGV the latter merely fails), we would like to (and had in the past
successfully) interpose at the most primitive possible level, both to
require as few wrappers as possible and, more importantly, to ensure
that calls internal to libc get our wrapper as well.

Is there a workaround for this?
If not, it seems as if a VERY USEFUL HOOK has been removed.

Is there any useful documentation regard issues such as this? All the
glibc docs I've seen, are relative to 2.0.x, before this was a problem.

Many thanks.
--ag


-- 
Artie Gold, Austin, TX  (finger the cs.utexas.edu account for more info)
mailto:agold@bga.com or mailto:agold@cs.utexas.edu

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]