Skip to content

Commit a0a3e75

Browse files
fix(rdpdr): fix incorrect padding when parsing NDR strings (#1015)
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.
1 parent d24dbb1 commit a0a3e75

File tree

1 file changed

+8
-4
lines changed
  • crates/ironrdp-rdpdr/src/pdu/esc

1 file changed

+8
-4
lines changed

crates/ironrdp-rdpdr/src/pdu/esc/ndr.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,21 @@ pub fn ptr_size(with_length: bool) -> usize {
8080
/// offset fields prefixing the string, as well as any extra padding for a 4-byte aligned
8181
/// NULL-terminated string.
8282
pub fn read_string_from_cursor(cursor: &mut ReadCursor<'_>, charset: CharacterSet) -> DecodeResult<String> {
83+
const ALIGNMENT: usize = 4;
8384
ensure_size!(ctx: "ndr::read_string_from_cursor", in: cursor, size: size_of::<u32>() * 3);
84-
let length = cursor.read_u32();
85+
let _length = cursor.read_u32();
8586
let _offset = cursor.read_u32();
8687
let _length2 = cursor.read_u32();
8788

8889
let string = utils::read_string_from_cursor(cursor, charset, true)?;
8990

9091
// Skip padding for 4-byte aligned NULL-terminated string.
91-
if length % 2 != 0 {
92-
ensure_size!(ctx: "ndr::read_string_from_cursor", in: cursor, size: size_of::<u16>());
93-
let _padding = cursor.read_u16();
92+
let mut pad = cursor.pos();
93+
let size = (pad + ALIGNMENT - 1) & !(ALIGNMENT - 1);
94+
pad = size - pad;
95+
if pad > 0 {
96+
ensure_size!(ctx: "ndr::read_string_from_cursor", in: cursor, size: pad);
97+
cursor.advance(pad);
9498
}
9599

96100
Ok(string)

0 commit comments

Comments
 (0)