EncodeBufferAppend overflows

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);
}
1 Like