dealing with dup2() from a rump kernel fd to a host kernel fd.
Consider:
s1 = socket();
s2 = socket();
dup2(s2, 0);
Instead, maintain a real mapping table (and get on my knees and
pray i don't have to touch this hair-splitting code ever again).
Apparently bourne shell scripts from a rump kernel fs work now
(sh script.sh; ./script.sh doesn't work for obvious "IT'S THE WRONG
FS NAMESPACE" reasons). No test regressions either, so I'm a
happy camper.
yesterday on powerpc broke overnight. Apparently adding one more
function before the call to dlsym() fixes things again. I hope
I don't have to add another one tomorrow ....
function call instead of a call through a function pointer.
Apparently powerpc ld.elf_so gets __hackish_return_address() wrong
if the call is done through a function pointer (digging deeper into
that stuff is beyond my interest).
Thanks to riz for providing access to a macppc for debugging.
Unthanks to the broken toolchain in the default installation which
wasted approximately 4 hours of time last night.
module which is compiled -fno-optimize-sibling-calls instead of
trying to fool the optimizer in various ways in the trampoline.
thanks to yamt for the tip
be hijacked. If it's not specified, the default is
"path=/rump,socket=all:nolocal".
So, if you're moof and want to relive your domain/os days (??),
you can do this:
pain-rustique:51:~> setenv RUMPHIJACK 'path=//'
pain-rustique:52:~> df //dev
Filesystem 1K-blocks Used Avail %Cap Mounted on
rumpfs 1 1 0 100% /
pain-rustique:53:~> df /dev
Filesystem 1K-blocks Used Avail %Cap Mounted on
/dev/wd0a 1019864 280640 688232 28% /
where you can mount a file system with a userspace server *without*
it having to go through puffs.
Say, you first start a server with ffs capability and map a host
ffs image into it:
rump_server -lrumpvfs -lrumpfs_ffs \
-d key=/ffsimg,hostpath=ffs2.img,size=e unix:///tmp/ffsserv
Then, configure your shell to talk to the rump server:
setenv RUMP_SERVER unix:///tmp/ffsserv
setenv LD_PRELOAD /usr/lib/librumphijack.so
Create a mountpoint and mount the file system:
pain-rustique:60:~> sh
$ cd /rump
$ ls
dev
$ ls -l
total 1
drwxr-xr-x 2 root wheel 512 Feb 17 18:00 dev
$ mkdir mnt
$ mount_ffs /ffsimg /rump/mnt
mount_ffs: Warning: realpath /ffsimg: No such file or directory
$ df -h mnt
Filesystem Size Used Avail %Cap Mounted on
/ffsimg 496M 380M 91M 80% /mnt
$ du -sckh *
192K dev
380M mnt
381M total
$ umount -R mnt
$ df -h mnt
Filesystem Size Used Avail %Cap Mounted on
rumpfs 1.0K 1.0K 0B 100% /
$
(note, you need -R to umount due to various degrees of unsuccesful
magic it attempts to perform without it)
distinct file descriptors, but the rump kernel thinks they are both
the same. Now, if either one is closed by the application, "both"
will be closed in the rump kernel. To fix this, maintain an
alias-mask. It's not a perfect solution, though (consider e.g.
F_SETFL). Maybe we should actually dup the fd and maintain a
mapping table?
Also, prevent the host from opening file descriptors onto the places
in the fd namespace that have been dupped.
These together fix "cat < /rump/foo" in a hijacked /bin/sh.
(the first one makes sure stdin is open in cat and the second one
makes sure it doesn't try to cat something from /usr/share/locale
instead of stdin)
/rump are hijacked to go to the rump server. So you can e.g. start
a hijacked shell and cd to /rump:
$ cd /rump
$ pwd
/rump
$ ls -l dev/null
crwxr-xr-x 1 root wheel 2, 2 Feb 17 12:35 dev/null
$ ls -l /dev/null
crw-rw-rw- 1 root wheel 2, 2 Dec 22 2009 /dev/null
$ chmod 0 /dev/null
chmod: /dev/null: Operation not permitted
$ chmod 0 dev/null
$ ls -l /rump/dev/null
c--------- 1 root wheel 2, 2 Feb 17 12:35 /rump/dev/null
(of course the rump server must have vfs loaded for that to work)
while for some cases attempting retry after server restart works
brilliantly (e.g. firefox), in other cases it's quite disasterous
(sshd doesn't like its file descriptors going missing and does not
attempt to reopen them, leading to a quite catastophic loop of
EBADF once the server does come back)
* rename RUMPHIJACK_RETRY to the slightly more sensible
RUMPHIJACK_RETRYCONNECT
rump tcp/ip stack:
* sshd likes to fork and then re-exec itself
==> trap execve() and augment the env with the current parameters
essential to a rump kernel (kernel communication fd, information
about dup2'd file descriptors)
* sshd likes to play lots of games with pipes, socketpairs and dup{,2}()
==> make sure we do not close essential rump client descriptors:
dup() them to a safe place, except for F_CLOSEM where we
simply leave them alone. also, partially solved by the above,
make sure the process's set of rump kernel descriptors persists
over exec()
* sshd likes to chdir() before exec
==> for unix-style rump_sp(7) sockets save the full path on the
initial exec and use it afterwards. thread the path through
the environment in execve()
expired it would assume that all input set descriptors had activity.
In case we get rv == 0 from the poll backend, zero out the fd sets
to signal that in fact no descriptors have activity.
Before this commit ssh was "jittery" when run through a rump tcp/ip
stack (interactive sessions kept blocking on stdin and you had to
"peddle" the connection). Now it works smoothly ... or at least
smoothly enough so that this commit could be done through a rump
tcp/ip stack:
USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS
root ssh 125 0 tcp localhost.65517 cvs.netbsd.org.22
libc resolver uses it. Error out in case of rump fd kevent (TODO).
Fixes one more problem pointed out by Alexander Nasonov.
Also, implement dup().
(TODO: implement it along the fcntl path too)
it. I still don't have any idea what the ssp stuff is supposed to
do and how it's supposed to even begin to work. If someone wants
to change this now, run tests/lib/librumphijack before commit so
that I can avoid another multihour debugging session!