Live data from Hacker News

Gokrazy: A pure-Go userland for Raspberry Pi 3 appliances

gokrazy.org

71–80 of 90 posts

Re: Gokrazy: A pure-Go userland for Raspberry Pi 3 appliances

#71
post #68
post #63

Earlier quoted context omitted.

I tried: I have used debootstrap to create minimal Debian images in the past. A big part of the motivation for gokrazy is to use a safe, high-level programming language. This allows us to re-implement the userland with small amounts of code, see e.g. the NTP client at https://github.com/gokrazy/gokrazy/blob/master/cmd/ntp/ntp.g... Replacing the implementation language eliminates whole classes of attacks, while stripp…

I still find this effort odd. You already have a well tested and widely used userland, even if it is written in a non memory safe language. The easiest solution to me seems to be to grab the tools you need from the existing userland, instead of reimplementing them in Go. Currently you have reimplemented some of the userland, and packaged it up into a distro. So you have to maintain a stripped down distribution and th…

The userland in question is an NTP, a DHCP client and the init system / web interface. It really isn’t much code. Implementing these in Go reduces the number of moving parts, both in terms of libraries involved in the project and more importantly in terms of programming languages involved.

Have a look at the git history to see how little maintenance is required in practice. I have barely had to touch the code over the last year of the project. Just incorporating new upstream versions of a typical Linux userland would have been more work.

Also note that “distribution” is a rather big word for the few files we’re talking about:

/mnt/gokrazy-root % find -type f ./cacerts ./gokr-pw.txt ./gokrazy/dhcp ./gokrazy/ntp ./gokrazy/init ./user/hello ./localtim ./hostname

If my reasoning doesn’t convince you, so be it. Not every project has to make sense to everybody :). I wanted to do a pure-Go userland, and I’m happy with the amount of work this results in and the properties that come out of this decision (easily automated updates, massively reduced attack surface).

Re: Gokrazy: A pure-Go userland for Raspberry Pi 3 appliances

#72
post #70

Earlier quoted context omitted.

The A/B updating scheme is a massive waste of space in most implementations... In many hardware devices, flash storage space for the OS is actually one of the most expensive components, and one of the main reasons that many devices run little hard-to-program embedded OS's rather than linux or something else high level. Instead, a filesystem like btrfs should be used which can give the appearance of multiple versions,…

Sure it is quite inefficient. Both in storage and in transmission of updates. But it is very simple and robust. What one tests pre rollout is identical to what will go on production devices, down to the byte. Each device with same version is identical. It can be cryptographically verified easily. Automatic rollback can be performed on update fail, including self-checks. This approach of shipping a custom userland wit…

I strongly agree regarding the simplicity!

A minimal gokrazy root file system is 16MB in size. On a 8GB SD card, I certainly am willing to sacrifice another 16MB to get A/B updates :).

Re: Gokrazy: A pure-Go userland for Raspberry Pi 3 appliances

#73
post #10

Earlier quoted context omitted.

I've done a lot of this sort of this as well. The ESP8266 is so great for simple on/off switches and sensors. But-- there are so many applications for having a full IoT Linux distribution that I can't believe this isn't already a solved problem. I'm imagining an ultra-stable distro that is easy to deploy to a headless machine, handles security updates, handles flaky wi-fi issues, tests the SD card (I've had more than…

ResinOS does all that and more. It's container-based. Works super-well on a Pi3.

Thanks. Where would alpine linux fit into this all. It seems like a good candidate for embedded setups.

Re: Gokrazy: A pure-Go userland for Raspberry Pi 3 appliances

#74
post #19
post #17

Earlier quoted context omitted.

Are there not many statically typed, compiled languages that ship a runtime with a garbage collector? Why is Go a good choice here? Why is this choice better than a language that provides memory safety using linear types so you don't even need a runtime or garbage collector?

You can read more about why I like Go at https://michael.stapelberg.de/posts/2017-08-19-golang_favori... . Of course I used my favorite programming language for building gokrazy :).

I've added gokrazy to my list of things to play with over the weekend (when I theoretically have time, hah). One question I'd ask in context of the other poster, can I easily run a Lua VM and tie it into the gocrazy env so that a Lua app would appear like a go app?

Re: Gokrazy: A pure-Go userland for Raspberry Pi 3 appliances

#75

It is really interesting that Gokrazy uses an upstream kernel (with a couple of minor patches). https://github.com/gokrazy/kernel/blob/3ecdc901da51c2c5b6bf7...

Even the raspberry Pi Zero and Zero W are supported in the latest kernels, and those were the latest Pi boards until the B+ came out.

Re: Gokrazy: A pure-Go userland for Raspberry Pi 3 appliances

#76
post #19

Earlier quoted context omitted.

You can read more about why I like Go at https://michael.stapelberg.de/posts/2017-08-19-golang_favori... . Of course I used my favorite programming language for building gokrazy :).

I've added gokrazy to my list of things to play with over the weekend (when I theoretically have time, hah). One question I'd ask in context of the other poster, can I easily run a Lua VM and tie it into the gocrazy env so that a Lua app would appear like a go app?

It might be possible to do this, but certainly not easily.

gokrazy’s unit of application is a Go package, so you’d need to write a Go program which then executes the Lua VM. I don’t know what dependencies Lua has — if it cannot be compiled statically, I’d recommend against using Lua in this context.

Re: Gokrazy: A pure-Go userland for Raspberry Pi 3 appliances

#77
post #55
post #45

Earlier quoted context omitted.

What's the typical definition? With data races, you can access array values out-of-bounds, which seems like the most fundamental thing you'd want protection from in a memory safe language.

You can't access data out of bounds. Go will panic with a runtime exceptions if you do. Memory safety doesn't mean "memory IO errors never happen" it means "if a memory IO error happens, you'll know" If you have an out of bound in C, your program keeps running in 9/10 cases. In Go you'll cause a panic in 10/10 cases which you can either handle and propagate as error or let the program crash entirely, the memory will…

But with Go you CAN access data out of bounds. See the "Exploiting the slice type" section where writing to a slice modifies a function pointer which happens to be stored after the slice. It's an OoB write which does not panic.

Re: Gokrazy: A pure-Go userland for Raspberry Pi 3 appliances

#78
post #70

Earlier quoted context omitted.

The A/B updating scheme is a massive waste of space in most implementations... In many hardware devices, flash storage space for the OS is actually one of the most expensive components, and one of the main reasons that many devices run little hard-to-program embedded OS's rather than linux or something else high level. Instead, a filesystem like btrfs should be used which can give the appearance of multiple versions,…

Sure it is quite inefficient. Both in storage and in transmission of updates. But it is very simple and robust. What one tests pre rollout is identical to what will go on production devices, down to the byte. Each device with same version is identical. It can be cryptographically verified easily. Automatic rollback can be performed on update fail, including self-checks. This approach of shipping a custom userland wit…

Transmission of updates can be quite small: For the info-beamer hosted (https://info-beamer.com/hosted) OS, we also do A/B booting. Updates are implemented using zsync.

The initial installation of the OS is simply done by unzipping a carefully crafted [1] install.zip file to the Raspberry Pi SD card. By exploiting zsync features, it's quite efficient to reconstruct the original install.zip from the unpacked files. Once that's done, all future updates also use zsync and only fetch changes to the locally stored 'install.zip' file. After updating this file we then unpacked everything again to the next A/B partition, so the exact state of the system is always known. Updates are quite small that way. It also helps that the complete OS is only ~37MB compressed at the moment.

[1] The root file system is squashfs and is stored uncompressed in the zip file to avoid double compression and allows zsync to use the squashfs blocksize to find a minimal set of changes. Similarly the initramfs.gz is compressed --rsyncable and also also stored uncompressed in the zip file.

Re: Gokrazy: A pure-Go userland for Raspberry Pi 3 appliances

#79
post #66

Earlier quoted context omitted.

This is only true if you can prove that data races will never cause any bounds checks to be wrong. The blog post linked upthread suggests otherwise, and even appears to provide a counter-example to your claim.

As mentioned in that blog post > You'll notice my address() trick to get the address of a function or variable that I used in my previous exploit. We're relying on package fmt and its %p format specifier which is implemented by using the unsafe package, so we don't need to use it ourselves.

unsafe code is not required or used. The exploit constructs a confused interface value, whose vtable refers to a different type than is what is stored. The result is that Go treats an integer as a function and jumps to it.

The unsafe address() is used to get the address of a function to store in the int, to demonstrate the potential for shellcode injection. But you could just as easily assign pp := 12345 and produce a SIGSEGV or SIGILL, which would not be possible if Go were memory safe.

Re: Gokrazy: A pure-Go userland for Raspberry Pi 3 appliances

#80
Does anyone know of a good tool for building custom PI distributions based on the Raspbian / Raspbian Lite or other distributions that does not involve forking the official image builder and hacking it up? My ideal tool would allow me to do this with a Dockerfile and just export the image after the configuration is complete.
Post reply on HN