logoalt Hacker News

lyu07282today at 1:27 PM0 repliesview on HN

They listed some of the memory bugs they had in the blog post, I just looked at three of them, the first one was this:

> heap-use-after-free crash in node:zlib when calling .reset() on a zlib, Brotli, or Zstd stream while an async .write() is still in progress on the threadpool

https://github.com/spaceraccoon/vulnerability-spoiler-alert/...

If you look at the fix you can see its all in their zig codebase:

https://github.com/oven-sh/bun/commit/621c4016218bb782e05907...

What is kind of funny is that nodejs also had a basically identical bug with an almost identical fix:

https://github.com/spaceraccoon/vulnerability-spoiler-alert/... https://github.com/nodejs/node/commit/53bcd114b10021c4a883b0...

But now the interesting question, how does the code look like in Rust?

https://github.com/oven-sh/bun/blob/8f1a9540fdff25410506de76...

It has the same guard in place as the zig and c++ versions, the rust code also just calls into the zlib bindings after the "write in progress" check.

So in this case at least the same exact use-after-free would've happened and they don't win anything from the rust port.

Another one was this:

> crash and out-of-bounds read in Buffer#copy and Buffer#fill when a valueOf callback detaches or resizes the underlying ArrayBuffer during argument coercion

I think ths is the fix:

https://github.com/oven-sh/bun/commit/79522ab6c579736dc239fa...

But the bug here is in C++ bindings, Rust wouldn't have helped here either.

Last one:

> double-free crash in the CSS parser when background-clip had vendor prefixes and multi-layer backgrounds

Fix: https://github.com/oven-sh/bun/commit/912970c98437e418a95b6b...

Code side-by-side:

Rust: https://github.com/oven-sh/bun/blob/8f1a9540fdff25410506de76...

Zig: https://github.com/oven-sh/bun/blob/912970c98437e418a95b6b5b...

I can't judge the Zig code, perhaps someone could say if this was a "beginner" mistake.

But this is at least one case where Rust would've helped, although even that is a bit complicated considering stuff like bun_ptr:

    // Lifetime-erasure helpers (RUST_PATTERNS.md §6/§18) — re-exported here so
    // crates that already depend on `bun_collections` (logger, css, js_parser,
    // crash_handler, watcher, http_types) can route the borrowck-dodge through
    // one centralised `unsafe fn` instead of open-coding the lifetime cast.
    pub use bun_ptr::{RawSlice, detach_lifetime, detach_ref};
Which is a bit concerning?