Discussion:
system call interposition using LD_PRELOAD
Godmar Back
2012-03-30 02:25:30 UTC
Permalink
Hi,

a student of mine is working on a project that requires system call
interposition. In the old days, this could be accomplished using a
LD_PRELOAD library that would redefine the system call entry points.

He tells me that for several years now, this is no longer possible with GNU
libc because functions such as fopen() do not dynamically link against the
stubs, but rather a local PLT is used. He also claims some system call
sequences are even inlined in parts of the libc code.

He is now considering changing libc, but finds that its design does not lend
itself easily to doing that.

If this is true, what is the new state of the practice with respect to
system call interposition?

I would like to hear other's experience/tips/recommendations. Thank you.

 - Godmar
Jonathan Nieder
2012-03-30 02:43:26 UTC
Permalink
Hi Godmar,
Post by Godmar Back
He tells me that for several years now, this is no longer possible with GNU
libc because functions such as fopen() do not dynamically link against the
stubs, but rather a local PLT is used. He also claims some system call
sequences are even inlined in parts of the libc code.
He is now considering changing libc, but finds that its design does not lend
itself easily to doing that.
If this is true, what is the new state of the practice with respect to
system call interposition?
Use ptrace(2).

Hope that helps,
Jonathan
Carlos O'Donell
2012-03-30 02:44:12 UTC
Permalink
Post by Godmar Back
a student of mine is working on a project that requires system call
interposition. In the old days, this could be accomplished using a
LD_PRELOAD library that would redefine the system call entry points.
I don't know that it has *ever* been possible to use ELF symbol
interposition to intercept all system calls made by glibc.
Post by Godmar Back
He tells me that for several years now, this is no longer possible with GNU
libc because functions such as fopen() do not dynamically link against the
stubs, but rather a local PLT is used. He also claims some system call
sequences are even inlined in parts of the libc code.
This is all true.
Post by Godmar Back
He is now considering changing libc, but finds that its design does not lend
itself easily to doing that.
That depends on your level of experience, but yes it's not currently
easy to intercept all system calls.
Post by Godmar Back
If this is true, what is the new state of the practice with respect to
system call interposition?
On Linux you would use the ptrace API to catch the system call on the
kernel side using PTRACE_SYSCALL. On the kernel side there is a well
defined syscall entry and exit process.
Post by Godmar Back
I would like to hear other's experience/tips/recommendations. Thank you.
For many reasons it's impractical to arrange the C library to be the
point of interception of the syscall, thus there is no good mechanism
for interception.

Good luck to your student and good luck with your work.

Cheers,
Carlos.
Godmar Back
2012-03-30 02:49:29 UTC
Permalink
Thanks for the replies.

ptrace will not work - this is not for an strace or debugging tool,
it's for an exceptionless system call implementation, similar to
FlexSC: http://www.eecg.toronto.edu/~livio/papers/flexsc-osdi10.pdf

Obviously, they must have found a way - I'm wondering if they were
using GNU libc or a different library.

- Godmar
Carlos O'Donell
2012-03-30 03:21:51 UTC
Permalink
Post by Godmar Back
Thanks for the replies.
ptrace will not work - this is not for an strace or debugging tool,
it's for an exceptionless system call implementation, similar to
FlexSC: http://www.eecg.toronto.edu/~livio/papers/flexsc-osdi10.pdf
In the future please start by answering "What problem are you trying to solve?"

It saves everyone time :-)

The paper is very interesting, even if x86 already has special faster
special case syscall instructions.

The kernel also has vsyscalls for *simple* syscalls which don't
require crossing into the kernel
Post by Godmar Back
Obviously, they must have found a way - I'm wondering if they were
using GNU libc or a different library.
They don't say the replaced *all* system calls.

They provide a pthreads library which uses their special exceptionless
system, but not an entire C library.

They can also override open/close and some common low-level IO because
these symbols are designed to be changed by user applications
(including mmap).

Thus you catch some but not *all* of the system calls in this way.

The *best* way to catch all the system calls is to rebuild glibc.

You'll need to change sysdep.h and provide your own versions of the
following macros:
PSEUDO
PSEUDO_END
PSEUDO_NOERROR
PSEUDO_END_NOERROR
PSEUDO_ERRVAL
PSEUDO_END_ERRVAL
ret
SYSCALL_ERROR_HANDLER
DO_CALL
DOARGS_*
POPARGS_*
LOADARGS_*
RESTOREARGS_*
INLINE_SYSCALL
INTERNAL_SYSCALL
INTERNAL_SYSCALL_DECL
INTERNAL_SYSCALL_ERROR_P
INTERNAL_SYSCALL_ERRNO

In both PIC and non-PIC cases.

The macros in sysdep.h for the machine are used to:

(a) Generate assembly syscall wrappers from syscalls.list for all
function calls that are simple wrapper around kernel system calls

and

(b) Generate inline system calls for functions that want to make
inline system calls to the kernel from C code.

By interposing yourself with a custom sysdep.h you will have control
over *all* the system calls made by the C library.

Cheers,
Carlos.
Carlos O'Donell
2012-03-30 13:20:51 UTC
Permalink
On Thu, Mar 29, 2012 at 11:21 PM, Carlos O'Donell
Post by Carlos O'Donell
(a) Generate assembly syscall wrappers from syscalls.list for all
function calls that are simple wrapper around kernel system calls
and
(b) Generate inline system calls for functions that want to make
inline system calls to the kernel from C code.
By interposing yourself with a custom sysdep.h you will have control
over *all* the system calls made by the C library.
I remembered one more wrinkle. In addition you'll need to define the
cancellation equivalents from sysdep-cancel.h. Which means you'll have
to think about how cancellation works with an exception-less syscall
system e.g. how do you cancel an outstanding request for IO which
*would* have blocked had the caller actually called a kernel syscall.

This research looks *very* interesting, please keep the list updated
on your progress and post any links to published papers you present.

Cheers,
Carlos.

Mike Frysinger
2012-03-30 04:38:09 UTC
Permalink
Post by Godmar Back
ptrace will not work - this is not for an strace or debugging tool,
ptrace is used in more than just strace or debugging tools
-mike
Loading...