acha.ninja

Memory Safeish Hare

Since the Hare programming language became public, it has been subject to some passionate criticism regarding a perceived lack of memory safety. I agree that memory safety concerns are very valid as shown by clear evidence, so the question becomes: should we write Hare off because someone online said it’s not strictly memory safe? I think that Hare can mitigate many of these problems today, while still being a small, simple and coherent language. let me explain how…

Out of bounds access

Hare provides the same tools for dealing with out of bounds access that languages like Go or Java do. Hare enforces bounds checks on array access, enforces type checks on union types and enforces null checks on nullable pointers. Yes, Hare offers unsafe access to pointers, just like Go and Rust do, which did not immediately disqualify those languages as unsafe.

Honestly, I think many people understate how big of a deal bounds checking is compared to pointer twiddling in C when making claims about relative memory safety of languages.

Thread safety and data races

Hare doesn’t support shared memory threading and therefore does not suffer from data races… while perhaps a cop-out to some, maybe it really could be that simple for many programs. It should also be noted that if you need to utilize multiple cpu cores in Hare, you can use the fork system call and communicate between processes via file descriptors, all of which is memory safe.

If your use case absolutely needs shared memory threads… That is fine, just use Rust/Go/Java/Whatever and be happy knowing you are using the right tool for the job.

Use after free bugs

But what about use after free bugs? An internet facing server written in Hare could still suffer vulnerabilities caused by use after free bugs. What can we do?

Actually there is a solution that is both ergonomic and robust that you can use with Hare today… Garbage Collection! Seriously, with the flick of a switch, you can mitigate use after free bugs in Hare programs.

(P.S. I’m aware some people will absolutely hate this, but the point is that it works and is there if you need the extra precautions.)

Boehm-Demers-Weiser Garbage collector

I tried to use the Boehm-Demers-Weiser garbage collector in Hare as an experiment. It was very easy once I got past a minor issue in the toolchain that will almost certainly be resolved before Hare reaches 1.0.

How hard is it? Simply pass the add a garbage collection library before libc while linking, and your hare program has mitigated use after free bugs. (Provided your library was compiled with malloc override stubs).

It can be as easy as:

$ hare build -lgc

Obviously there are costs and trade offs, but afterall, the Boehm-Demers-Weiser collector has been deployed in a wide range of real world software you probably have used.

Writing my own Garbage Collector

I also tried to write a simple conservative garbage collector in Hare and integrate it into Hare as an optional runtime. To my delight and surprise, I managed to make a proof of concept that passes the Hare test suite.

Once that patch is applied to Hare you can enable garbage collection with:

$ hare build -T +gc

My design is very simple, using a hash table to track allocations and stop the world mark and sweep collection. I am still curious to see how well it performs in practice, but I think the concepts behind it are reasonable.

Conclusion

My opinion is that Hare is a fun, small and interesting language that provides many tools for memory safety if you care to look.

While the solutions may have weaknesses, in my opinion they still cover many use cases well, and I believe it is an oversimplification to say Hare is unsafe.

I also want to note the small scope of the language also made my experimentation easy and enjoyable, which I think is a powerful thing.

As always, thanks for reading :)