fix(rdpdr): fix incorrect padding when parsing NDR strings (#1015)
Some checks failed
CI / Check formatting (push) Has been cancelled
CI / Check typos (push) Has been cancelled
Coverage / Coverage Report (push) Has been cancelled
Release crates / Open release PR (push) Has been cancelled
Release crates / Release crates (push) Has been cancelled
CI / Checks [linux] (push) Has been cancelled
CI / Checks [macos] (push) Has been cancelled
CI / Checks [windows] (push) Has been cancelled
CI / Fuzzing (push) Has been cancelled
CI / Web Client (push) Has been cancelled
CI / FFI (push) Has been cancelled
CI / Success (push) Has been cancelled

When parsing Network Data Representation (NDR) messages, we're supposed
to account for padding at the end of strings to remain aligned on a
4-byte boundary. The existing code doesn't seem to cover all cases, and
the resulting misalignment causes misleading errors when processing the
rest of the message.
This commit is contained in:
rhammonds-teleport 2025-10-09 13:25:08 -04:00 committed by GitHub
parent d24dbb1e2c
commit a0a3e750c9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -80,17 +80,21 @@ pub fn ptr_size(with_length: bool) -> usize {
/// offset fields prefixing the string, as well as any extra padding for a 4-byte aligned
/// NULL-terminated string.
pub fn read_string_from_cursor(cursor: &mut ReadCursor<'_>, charset: CharacterSet) -> DecodeResult<String> {
const ALIGNMENT: usize = 4;
ensure_size!(ctx: "ndr::read_string_from_cursor", in: cursor, size: size_of::<u32>() * 3);
let length = cursor.read_u32();
let _length = cursor.read_u32();
let _offset = cursor.read_u32();
let _length2 = cursor.read_u32();
let string = utils::read_string_from_cursor(cursor, charset, true)?;
// Skip padding for 4-byte aligned NULL-terminated string.
if length % 2 != 0 {
ensure_size!(ctx: "ndr::read_string_from_cursor", in: cursor, size: size_of::<u16>());
let _padding = cursor.read_u16();
let mut pad = cursor.pos();
let size = (pad + ALIGNMENT - 1) & !(ALIGNMENT - 1);
pad = size - pad;
if pad > 0 {
ensure_size!(ctx: "ndr::read_string_from_cursor", in: cursor, size: pad);
cursor.advance(pad);
}
Ok(string)