#281 buffer overrun in rdp_send_available()->rdp_out_unistr()

open
nobody
Internals (36)
5
2012-11-29
2008-10-20
Dan Astoorian
No

I've traced a segmentation fault back to a buffer overrun in rdp.c.

rdp_out_unistr() in rdp.c does:
memset(pout, 0, len + 4);

This appears to be two bytes too many: only len+2 bytes should be needed to convert the input string (the len parameter seems to be twice the length of the unterminated input string, so the output should be 2*len bytes for the string plus 2 bytes for the terminating NULL character).

I've found some conditions under which this overrun will cause a crash, although it's not straightforward to reproduce. The following conditions were necessary (but not sufficient) to produce a crash under RHEL 4.7 x86:

- enough printers need to be specified on the rdesktop command line that rdp_send_available() needs the entire channel buffer (i.e., it's grown by the "s = channel_init(rdpdr_channel, announcedata_size());" in rdp_send_available());

- there must be no cached printer blob for the last printer specified (otherwise, the overwritten bytes will have been allocated for the blob).

Under these conditions, the rdp_out_unistr() will write past the end of the stream buffer allocated in rdp_send_available(); this may or may not produce a crash during a subsequent free() or realloc() depending on how the memory was allocated/aligned.

Changing len+4 to len+2 in the memset at rdp.c:179 appears to fix the symptom.

Discussion