inferno-lab

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.