For Programmers: Free Programming Magazines  


Home > Archive > Unix Programming > September 2004 > how to "wrap" vfork?









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author how to "wrap" vfork?
Mohun Biswas

2004-09-17, 9:00 pm

My program needs to keep track of processes, so it has a little code to
wrap the fork() system call. The wrapper simply makes an entry in a
little embedded database, then calls through to the real fork() using
dlsym(RTLD_NEXT, ...) et al.

This works fine. But I've realized there's still substantial use of
vfork() out there - in fact it seems to be less deprecated than it used
to be - so I figured I'd better catch vfork() uses as well.
Unfortunately it turns out to be impossible to put a wrapper function
around vfork because of the following restriction:

> The procedure that called vfork(), however, should not return
> while running in the child's context, since the eventual return
> from vfork() would be to a stack frame that no longer exists.


This is from the Solaris man page but SUS has similar text. Obviously,
once the wrapper function returns the stack frame is hosed, and there's
no way to get to the exec without the wrapper returning first. The
current workaround is to replace vfork() with fork(); i.e. my vfork
wrapper calls fork under the covers. This is at least technically legal
since SUSv3 says "On some implementations, vfork() is equivalent to
fork()." But I'm still looking for some brilliant hack that would allow
trapping of calls to vfork. Anyone?

BTW, I should note that in some cases I have to inject this tracking
code into programs we don't control via LD_PRELOAD, so simply avoiding
the use of vfork is not a complete solution.

--
Thanks,
M.Biswas
Paul Pluzhnikov

2004-09-17, 9:00 pm

Mohun Biswas <m.biswas@invalid.addr> writes:

> But I'm still looking for some brilliant
> hack that would allow trapping of calls to vfork. Anyone?


The *only* possible solution (I think) is to write your wrapper in
assembly and in such a way that it keeps all its state in registers
and doesn't touch any memory.

Cheers,
--
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.
all mail refused

2004-09-17, 9:00 pm

In article <xYD2d.65442$D%.32367@attbi_s51>, Mohun Biswas wrote:

>BTW, I should note that in some cases I have to inject this tracking
>code into programs we don't control via LD_PRELOAD, so simply avoiding
>the use of vfork is not a complete solution.


Have you looked at Dave Wagner's "Janus" involving a loadable kernel
module for hints at code interception ? I haven't looked at it
in detail.

http://http.cs.berkeley.edu/~daw/janus/

--
Elvis Notargiacomo master AT barefaced DOT ch
http://www.notatla.org.uk/goen/
My energy-saving light bulb caught fire. Now I know
the NSA are beaming microwaves at my flat.
Mohun Biswas

2004-09-17, 9:00 pm

Paul Pluzhnikov wrote:
> Mohun Biswas <m.biswas@invalid.addr> writes:
>
>
> The *only* possible solution (I think) is to write your wrapper in
> assembly and in such a way that it keeps all its state in registers
> and doesn't touch any memory.


I think I see ... you mean the wrapper wouldn't have the usual preamble
code to push a stack frame, so I'd be responsible for not scribbling on
registers and memory. And when vfork() returned in the parent it would
find the stack frame where it expected. Is that right? And if so, if I
called another (regular) function from within this magic half-function
that should be ok, since it would save and restore registers and so on,
right?

Just to make sure the situation is clear, I don't want to mess with
anything at all *after* the split. I just need a hook to make an entry
in a database *before* the split, while everything's still running in
one simple unitary process. The problem is that I have to push a stack
frame in order to get that hook but I'm not allowed to pop a stack frame
afterwards. Catch-22.

--
Thanks,
M.Biswas
Seongbae Park

2004-09-17, 9:00 pm

Mohun Biswas <m.biswas@invalid.addr> wrote:
> Paul Pluzhnikov wrote:
>
> I think I see ... you mean the wrapper wouldn't have the usual preamble
> code to push a stack frame, so I'd be responsible for not scribbling on
> registers and memory. And when vfork() returned in the parent it would
> find the stack frame where it expected. Is that right? And if so, if I
> called another (regular) function from within this magic half-function
> that should be ok, since it would save and restore registers and so on,
> right?
>
> Just to make sure the situation is clear, I don't want to mess with
> anything at all *after* the split. I just need a hook to make an entry
> in a database *before* the split, while everything's still running in
> one simple unitary process. The problem is that I have to push a stack
> frame in order to get that hook but I'm not allowed to pop a stack frame
> afterwards. Catch-22.


Not sure I understand exactly,
but it seems that making a tail call to vfork() inside your wrapper
function will work.
This will make vfork() to return directly to the caller
of the wrapper instead of returning to your wrapper function.
This way, the stack is popped before the vfork call.
Or do you want something else ?
--
#pragma ident "Seongbae Park, compiler, http://blogs.sun.com/seongbae/"
Jonathan Adams

2004-09-17, 9:00 pm

In article <HtI2d.66182$D%.65464@attbi_s51>,
Mohun Biswas <m.biswas@invalid.addr> wrote:

> Paul Pluzhnikov wrote:
>
> I think I see ... you mean the wrapper wouldn't have the usual preamble
> code to push a stack frame, so I'd be responsible for not scribbling on
> registers and memory. And when vfork() returned in the parent it would
> find the stack frame where it expected. Is that right? And if so, if I
> called another (regular) function from within this magic half-function
> that should be ok, since it would save and restore registers and so on,
> right?
>
> Just to make sure the situation is clear, I don't want to mess with
> anything at all *after* the split. I just need a hook to make an entry
> in a database *before* the split, while everything's still running in
> one simple unitary process. The problem is that I have to push a stack
> frame in order to get that hook but I'm not allowed to pop a stack frame
> afterwards. Catch-22.


As long as you don't need to do anything *after* vfork() returns, this
is not impossible. Basically, all you need to do is write a small
assembly routine which:

sets up a stack frame
calls your C routine, which:
does a bunch of work
returns (dlsym(RTLD_NEXT, "vfork"))
tears down the stack frame
jumps through the returned function pointer

On sparc, this would look something like: (call this vfork.S)

--- cut here ---
#define _ASM
#include <sys/asm_linkage.h>

ENTRY(vfork)
save %sp, -SA(MINFRAME), %sp
call vfork_wrapper ! returns &vfork in %o0
nop
jmp %o0
restore ! delay slot
SET_SIZE(vfork)
--- cut here ---

The x86 routine would be about the same complexity. The vfork syscall
will return directly to the caller.

- jonathan
Jonathan Adams

2004-09-17, 9:00 pm

In article <jwadams-A8DAAD.15055217092004@news1nwk.sfbay.sun.com>,
Jonathan Adams <jwadams@gmail.com> wrote:
>
> On sparc, this would look something like: (call this vfork.S)
>
> --- cut here ---
> #define _ASM
> #include <sys/asm_linkage.h>
>
> ENTRY(vfork)
> save %sp, -SA(MINFRAME), %sp
> call vfork_wrapper ! returns &vfork in %o0
> nop
> jmp %o0
> restore ! delay slot
> SET_SIZE(vfork)
> --- cut here ---
>
> The x86 routine would be about the same complexity. The vfork syscall
> will return directly to the caller.


x86:

--- cut here ---
#define _ASM
#include <sys/asm_linkage.h>

ENTRY(vfork)
pushl %ebp
movl %esp, %ebp
call vfork_wrapper
movl %ebp, %esp
popl %ebp
jmp *%eax
SET_SIZE(vfork)
--- cut here ---

(the advantage of this over the "convince the compiler to make it a
tail-call" approach is that sometimes the compiler is hard to convince)

- jonathan
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com