Aloha -

My recent experiments with 'netmsg' have lead me to investigate the
operation of Hurd's exec server, and I've got a few questions.

First off, the current obstacle to exec'ing files over netmsg is the need
to operate the memory_object protocol over the TCP/IP connection.  libpager
has a problem with this, because it can't handle multiple clients.  It
needs to, because in a multi-node environment a file server is likely to be
interacting with multiple kernels using memory_object calls.  Also, my test
program can mount denial of service attacks against the kernel by grabbing
libpager's only available client connection for a given file before the
kernel does.

So, I'll modify libpager to handle multiple clients.  Not trivial, but it
seems necessary and correct.

However, the protocol exchange over the network connection isn't what I
expected.  The failing vm_map turns out to be running on the server, not
the client!

Think about this for a minute.  We've mounted a remote file system and
tried to exec a file on it.  I expected the client to be mapping the file,
which is on the server, not the other way around!

The reason is that the failing vm_map arises from the exec server's attempt
to examine the ELF header of /lib/ld.so.  When the client called
file_exec_file_name, it passed a bunch of ports across the network
connection, including INIT_PORT_CRDIR.  The file server then passed that
along to the exec server (running on the server), which examined the file
(no network ops needed; both the exec server and the file are on the
server), determined the need to map /lib/ld.so, did a dir_lookup on
INIT_PORT_CRDIR (this went back across the network), and then tried to map
the file's ELF header into its own memory space.  Not the new process's
memory space, mind you; it maps it into its own memory space!

One question is whether the exec server really needs to do a vm_map to
examine an ELF header.  A simple read would suffice.  Which should be
preferred?

A more serious question is why the exec server is running on the server
side at all.  Shouldn't it be running on the client?  Then the only network
operation it would need is to map the one file that it's trying to execute.

Examining diskfs_S_file_exec reveals some interesting behavior.  The file
server caches a port to its exec server, so the same exec server gets used
by all of its clients!  Furthermore, it gets the exec server in the first
place by looking up _SERVERS_EXEC in its own name space, not the client's!

Shouldn't the exec server be looked for in the client's name space?

While trying to figure all of this out, I googled around and found the
discussion on this list about the EXECSERVERS environment variable, which
has apparently been deprecated in favor of the remap translator.  I can't
get remap to work, and it's real simple, so I suspect that it's currently
broken.  Yet even if it were working, I can't see how it could affect the
choice of exec server, since it only modifies the client's name space!

I'm thinking that maybe the C library's exec() should lookup _SERVERS_EXEC
and pass it to the file server in the file_exec_file_name call.  Then, if
SUID execution is being requested, maybe the file server ignores that and
looks up _SERVERS_EXEC in its own name space.

What do you think?

    agape
    brent

Reply via email to