enarx / enarx

Enarx: Confidential Computing with WebAssembly
https://enarx.dev/
Apache License 2.0
1.3k stars 140 forks source link

Be more explicit about mapping file descriptors in Enarx.toml #2298

Open bstrie opened 2 years ago

bstrie commented 2 years ago

Currently, a basic Enarx.toml looks like this:

[[files]]
kind = "stdin"

[[files]]
kind = "stdout"

[[files]]
kind = "stderr"

If someone wants to map a new file descriptor, they might modify the file to look like this:

[[files]]
name = "listen"
kind = "listen"
port = 12345

[[files]]
kind = "stdin"

[[files]]
kind = "stdout"

[[files]]
kind = "stderr"

However, this is incorrect and will produce unpredictable runtime errors with unhelpful error messages. The problem is that the order of files in Enarx.toml has semantic importance: the first file to be mentioned is mapped to FD 0, the second is mapped to FD 1, and so on. What the user intended here would have been to append the new file entry to the end of the list, rather than the beginning.

For most files this wouldn't be a problem because we encourage users to look up their custom-mapped files by name, using the FD_NAMES environment variable to translate a file's name to its FD number. However, for the three well-known files stdin, stdout, and stderr, all third-party code in the wild (for example, the standard libraries of every programming language) will assume that FD 0 is for stdin, FD 1 is for stdout, and FD 2 is for stderr. If the user accidentally lists stdout third in the file (e.g. if someone reformats their TOML file alphabetically), then there's no way to e.g. make println! in Rust use FD 2 rather than FD 1.

While it's fine to continue to allow most files to exist in an arbitrary list, for stdin, stdout, and stderr we should be more explicit and have keys dedicated to FD 0, FD 1, and FD 2. For example, it could look something like this:

[files]
stdin = true
stdout = true
stderr = true
extra = [
    { name = "listen", kind = "listen", port = 12345 },
    { name = "stream", kind = "connect", host = "localhost", port = 23456 }
]

This would still allow users to override stdin etc. (using the same file specification shown in the extra array) while making it explicit which mappings are referring to well-known file descriptors.

Another advantage of this is that, currently, if you want to add an arbitrary file to your Enarx.toml, you must specify stdin etc. in your Enarx.toml as well unless you want to risk weird things happening the first time that someone adds an errant dbg! or something. With the change proposed here, we could use default values for stdin etc (mapping them all to a null device), allowing users who don't intend to use them to avoid the need to mention them at all.

rvolosatovs commented 2 years ago

@bstrie this is already done in #2245