aboutsummaryrefslogtreecommitdiff
path: root/blog/olin-progress-2019-12-14.markdown
blob: 451b973c3ec8fe202066c6de52239d3b83de0d0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
---
title: Olin Improvements
date: 2019-12-14
series: olin
tags:
 - wasm
 - wasmcloud
 - rust
 - zig
 - cgi
---

# Olin Improvements

Over the last week or so I've been doing a _lot_ of improvements to [Olin][olin] in order to make it ready to be the kernel for the minimum viable product of [wasmcloud][wasmcloud-hello-world]. Here's an overview of the big things that have happened from version [0.1.1][olin-0.1.1] to version [0.4.0][olin-0.4.0].

[olin]: https://github.com/Xe/olin
[wasmcloud-hello-world]: https://christine.website/blog/wasmcloud-progress-2019-12-08
[olin-0.1.1]: https://github.com/Xe/olin/releases/tag/v0.1.1
[olin-0.4.0]: https://github.com/Xe/olin/releases/tag/v0.4.0

## What is Olin?

[Olin][olin] is a userspace kernel designed for multi-tenant secure computing. It provides isolation via WebAssembly to limit the attack scope of malicious user input, resource accounting via its runtime statistics, and a familiar Unix-like API. It is the core that you can build a functions as a service platform on top of. 
For an example of Olin in action, please click [here][olin-example]. 

[olin]: https://github.com/Xe/olin
[olin-example]: https://home.cetacean.club/cwagi

As Olin is just a kernel, it needs some work in order to really shine as a true child of the cloud. That work is incoming during the next weeks and months.

## Announcements

Here is what has been done since the [last Olin post][last-olin-post]:

[last-olin-post]: https://christine.website/blog/olin-2-the-future-09-5-2018

* An official, automated build of the example Olin components has been published to the Docker Hub
* The Go ABI has been deprecated for the moment
* The entrypoint of Olin programs has changed to _start
* The beginning of support in the Zig standard library
* Official binfmt_misc rigging has been created for experimentation

### Official Docker Hub Build

The Docker Hub repo [xena/olin][docker-hub] now is automatically built off of the latest master release of Olin. 

[docker-hub]: https://hub.docker.com/r/xena/olin

To use this image, run the following commands:

```console
$ docker pull xena/olin:latest
$ docker run --rm -it xena/olin:latest sh
```

Then you can use the `cwa` tool to run programs in `/wasm`. See `cwa -help` for more information.

### Deprecation of Go Support

For the moment, I am deprecating support for [Go][golang] in `GOOS=js GOARCH=wasm`. The ABI for the Go compiler in this mode is too unstable for me right now. If other people want to fix [`abi/wasmgo`][abi-wasmgo] to support Go 1.13 and newer, I would be _very_ welcome to the patches.

[golang]: https://golang.org
[abi-wasmgo]: https://github.com/Xe/olin/tree/master/abi/wasmgo

### The Entrypoint is Now `_start()`

Early on in the experiments that make up Olin, I have made a mistake in my fundamental understanding of how operating systems run programs. I thought that the main function would return the exit code of the program. This is not the case. There is a small shim that wraps the main function of your language and passes the result of it to `exit()`. Olin now copies this behavior. In order to return a value to the Olin runtime, you can either call `runtime_exit()` or return from the `_start()` function to exit with 0. Many thanks to Andrew Kelly for helping me realize this error.

This behavior is copied in the [Olin rust package][olin-rust-entrypoint], which now has a fancy macro to automate the creation of the `_start()` function.

[olin-rust-entrypoint]: https://github.com/Xe/olin/blob/ffc4ec5d436b6536d8b3917990ac6c53650f4297/rust/olin/src/lib.rs#L424

I am waiting on Zig to release a new nightly version in order to enable it, but the [bring-your-own-OS package][bring-your-own-os] support in Zig means that the Zig standard library is starting to be exposed into Olin programs. Here's an example based on the [example program][zig-example-program]:

[bring-your-own-os]: https://github.com/ziglang/zig/commit/b375f6e027a159616e80906aa05e253fbe8cc9df
[zig-example-program]: https://github.com/ziglang/zig/blob/master/lib/std/special/init-exe/src/main.zig

```zig
pub const os = @import("./olin/olin.zig");
const std = @import("std");

pub fn main() anyerror!void {
    std.debug.warn("All your base are belong to us.\n", .{});
}
```

### `binfmt_misc` Rigging

For a while I've had a [binfmt_misc][binfmt-misc] configuration floating around in the Olin repo. Here's how to use [it][olin-binfmt]:

[binfmt-misc]: https://en.wikipedia.org/wiki/Binfmt_misc
[olin-binfmt]: https://github.com/Xe/olin/blob/master/run/binfmt_misc/cwa.cfg

First, install Olin's `cmd/cwa` to `/usr/local/bin`:

```console
$ cd cmd/cwa
$ go build
$ sudo mv cwa /usr/local/bin
```

Then activate the binfmt_misc configuration:

```console
$ cd ../../run/binfmt_misc
$ cat cwa.cfg | sudo tee /proc/sys/fs/binfmt_misc/register
```

Then you can run Olin programs without calling `cwa`:

```console
$ ./olinfetch.wasm
```

## Features

### Policy Support

Olin now has a declarative policy engine for accessing external resources. This is inspired from OpenBSD `pledge()` and macOS sandboxing. These policies allow setting the following attributes:

* Resources an Olin program can access, matched by regular expressions
* Resources an Olin program CANNOT access, matched by regular expressions 
* The maximum amount of memory an Olin program can use
* The maximum number of WebAssembly instructions a WebAssembly program can execute

Here's an example policy file intended to help with relaying webhooks: 

```
## This is an example policy, the ## signifies this line is a comment.

## These are the URL patterns that this handler can open:
allow (
  ^https://tulpa.dev
  ^https://discordapp.com/api/webhooks/
  ^random://$
)

## These are the URL patterns that this handler cannot open:
disallow (
  ^https://tulpa.dev/admin.*$
)

## This is the ram limit in pages (64k each):
ram-page-limit 128

## This is the gas limit in instructions:
gas-limit 1048576
```

This would allow a WebAssembly program to open a HTTP socket to https://tulpa.dev (my git server) and Discord, but disallows any administrative API calls to my git server. It also allows the Olin program to use up to 128 pages of memory (about 8MB, which goes surprisingly far) and 1.04 million instructions. If the handler tries to open any resource that is not explicitly allowed, it is killed. If the handler tries to open a resource that is explicitly forbidden, it is killed. If the handler uses too much ram or too many instructions, it is killed. 

This allows handlers to safely process user controlled input and even use that as part of the call to the open function.

When policies are violated, the error thrown is a [vibe check failure][vibe-check]:

[vibe-check]: https://www.urbandictionary.com/define.php?term=Vibe%20Check

```console
$ cwa -policy ../policy/testdata/gitea.policy httptest.wasm
httptest.wasm: 2019/12/13 13:16:15 info: making request 
  to https://xena.greedo.xeserv.us/files/hello_olin.txt
httptest.wasm: 2019/12/13 13:16:15 vibe check failed: 
  https://xena.greedo.xeserv.us/files/hello_olin.txt 
  forbidden by policy
2019/12/13 13:16:15 httptest.wasm: exit status -1
```

### `runtime_exit()` System Call

Along with making `_start()` the entrypoint, there comes a new problem: exiting. I fixed this by adding a [`runtime_exit()`][runtime-exit] system call in Olin. When you call this function with the status code you want to return, execution of the Olin program instantly ends, uncleanly stopping everything and closing all files the program has open. This is similar to Linux's `exit()` system call.

[runtime-exit]: https://github.com/Xe/olin/commit/0036ee8620abe8a25b24c5b7feb76caefba35a8f

It's probably best to save this call for cases where the program _really can't/shouldn't_ continue executing, like for panic handlers.

### Generic CGI Support

Previously there was a half-baked idea I called cwagi in Olin's codebase. The idea was to emulate part of how CGI worked in order to let Olin programs handle HTTP easily. I realize this was a mistake, so now it [just supports normal CGI][cgi-patch], conforming to [RFC 3875][rfc3875]. 

[cgi-patch]: https://github.com/Xe/olin/commit/92e703fcb2571e1f32e0bf1ba4f17bb45c1d6408
[rfc3875]: https://tools.ietf.org/html/rfc3875

### End of File Error

One of the more common errors in operating systems is the "end of file" error. It is raised when a file has no more data in it. Olin didn't have this, but [now it does][eof-patch].

[eof-patch]: https://github.com/Xe/olin/commit/beb19fd9c6ee2de11f61c6f93fc1813f5f317aff

## Wasmcloud Features

Thanks to these improvements, the following wasmcloud features have been implemented:

* Updating handlers (`wasmcloud update`) [link](https://tulpa.dev/within/wasmcloud/issues/11)
* Deleting handlers (`wasmcloud delete`) [link](https://tulpa.dev/within/wasmcloud/issues/21)
* Listing deleted handlers (`wasmcloud list -show-deleted`)
* Brand outgoing HTTP requests [link](https://tulpa.dev/within/wasmcloud/commit/3024971fdf3d437a2bda95206f7fb123be1a8df5)

As of the writing of this post, wasmcloud is currently 75% through the [MVP development cycle][mvp-milestone]. Here are the remaining issues:

[mvp-milestone]: https://tulpa.dev/within/wasmcloud/milestone/1

* CGI support for handlers [link](https://tulpa.dev/within/wasmcloud/issues/16)
* Policy support for handlers [link](https://tulpa.dev/within/wasmcloud/issues/12)
* Configuration variables for handlers [link](https://tulpa.dev/within/wasmcloud/issues/6)

--- 

Overall, this project is fun. Here's to 1.0 happening soon! Be well.