I’m working with Sway v0.65.2, which was at some point vulnerable to EncodeBufferAppend overflows. I’m having a hard time understanding how Sway encoding works, both conceptually and in practice. For example, the following test (which now fails since the issue has been patched) includes logic I don’t fully grasp — particularly why 8 is subtracted, and how it was possible to write into the red zone. I need to understand the security implications, scenarios. Any insights would be greatly appreciated.
ok_bytes_bigger_than_3064
#[test]
fn ok_bytes_bigger_than_3064() {
let mut v: Bytes = Bytes::new();
// We allocate 1024 bytes initially, this is throw away because
// it is not big enough for the buffer.
// Then we used to double the buffer to 2048.
// Then we write an `u64` with the length of the buffer.
// Then we write the buffer itself.
// (1024 + 2048) - 8 = 3064
// Thus, we need a buffer with 3065 bytes to write into the red zone
let mut a = 4000;
while a > 0 {
v.push(2u8);
a -= 1;
}
// This red zone should not be overwritten
let red_zone = asm(size: 1024) {
aloc size;
hp: raw_ptr
};
red_zone.write(0x1111111111111111);
assert(red_zone.read::<u64>() == 0xFFFFFFFFFFFFFFFF);
let _ = encode(v);
assert(red_zone.read::<u64>() == 0xFFFFFFFFFFFFFFFF);
}