Extensions
lab 92 - vxinferno
In this lab I create a new Inferno builtin module that calls the vx32
library and get a minimal system working
that runs native x86 code, with system calls redirected to inferno’s system calls
and therefore making the inferno namespace visible to the sandboxed code.
From the vx32 paper,
"Vx32 is a multipurpose user-level sandbox that enables any application to
load and safely execute one or more guest plug-ins, confining each guest
to a system call API controlled by the host application and to a restricted
memory region within the host’s address space."
Inferno, being a virtual operating system, provides its own system call API to limbo applications. The same system calls are available as a C API for use by linked native libraries that appear as builtin modules or devices within the inferno environment. This API is a natural fit for building a Vx32 sandbox allowing native code of all kinds to run within inferno, which controls the namespace.
Please read the vx32 paper, download the code and play with it. I haven't
included the vx32 code in the lab. Instead this lab is more tutorial
in creating a new builtin module for inferno. This labs code, linked
to in the steps below, is all the code necessary to make vx32 appear
as a builtin. I've done enough to show some simple examples working,
but I haven't defined the full system call interface.
So here are the steps in creating a new builtin module linkage.
module interface
Create the limbo module interface, e.g.
/module/vxrun.m.
I created the interface to closely resemble the vxrun
application in the vx32 distribution. The module contains
one function to load and run a native ELF executable.
Edit
/module/runt.m
to include new include the new module
interface. This file includes all builtin modules and is used
later to generate a runtime C struct.
incorporate library code
Copy library and header files into inferno-os tree.
I copied vx32.h to
/include/vx32.h.
I created a new
libvx32 folder at the root of the tree and create a
dummy mkfile. I didn't copy all the source into the tree,
I cheated and just copied libvx32.a to /Linux/386/lib.
But the emu build will expect the folder and mkfile to
exist. So this is a placeholder for now.
add builting to libinterp
Implement the builtin linkage
/libinterp/vxrun.c
This is the bulk of the work, where we call the vx32 API
and map the system calls defined in the codelet C library
that comes with the vx32 distribution, libvxc, to inferno's
API defined in /include/kernel.h.
A lot of this code was taken from vx32/src/vxrun/vxrun.c
and other pieces are more template code for builtin modules.
To get this to build we need to
edit the
/libinterp/mkfile
to include the new module,
with dependency on header file, generate header file. Add vxrun.$O to the
list of OFILES, add vxrun.m to the list of MODULES, and the following rules to ensure the module header,
vxrunmod.h, is generated.
vxrunmod.h:D: $MODULES
rm -f $target && limbo -t Vxrun -I../module ../module/runt.m > $target
vxrun.$O: vxrunmod.h
We can now compile libinterp.
edit emu config
The final step is to edit
/emu/Linux/emu
configuration file
and add the dependencies on the vxrun module and
the vx32 library.
We can now build a new emu that has the vx32 vxrun as
a builtin module.
test
We need a limbo command to call the module.
I included
vxinferno.b in the lab code.
But it does nothing more than load the module and
call it passing in any command line arguments.
init(nil:ref Draw->Context, args:list of string)
{
vxrun := load Vxrun Vxrun->PATH;
vxrun->run(tl args);
}
I used the vx32-gcc to compile the native code. I included one example,
cat.c, that would test the system calls, open, read, write, from the inferno
namespace. Note that the name of the executable to call from inside
Inferno is the host pathname, because vx32 itself is not using the Inferno
system calls. This could be fixed by either changing the elf loader, or
by using the library call to load the ELF from memory.
$ cd ~/vx32/src/vxrun
$ vxrungcc cat.c
$ emu -s -r ~/inferno-os
; vxinferno /home/caerwyn/vx32/src/vxrun/_a.out /dev/drivers
#/ root
#c cons
#e env
#M mnt
...
conclusion
This lab confirmed vx32 as a builtin to inferno would work.
Now it needs to be implemented in full.
There is an effort to port
vx32 to windows,
but it seems to have stalled.
I really hope that vx32 will get ported.