Repository navigation
[io] validate decompressed size against point layout in readBodyBinary - #6491
Conversation
|
There is a relatively similar check in line 576: if (uncompressed_size != cloud.data.size ())It even triggers in the new test you added: |
|
Good point, it's the same condition. readHeader already rejects WIDTH x HEIGHT != POINTS, so cloud.data.size() is point_step * width * height, and the only way that differs from fsize * width * height is a So I dropped my check and turned the warning at line 576 into an error that returns -1. The new test still passes, it just fails at that earlier point now, and the rest of test_io is green. |
pcl::PCDReader::readBodyBinary reads the uncompressed size of a binary_compressed PCD straight from the body header and uses it to size the decompression buffer and cloud.data. Nothing enforces that size against the point layout: when it differs from the cloud.data size computed from the header fields, the reader only warns and then resizes cloud.data to the file-supplied value. The planar unpack loop right below walks width * height points with fsize bytes per point, so a file that advertises an uncompressed size smaller than fsize * width * height sends the plane pointers past the end of the decompressed buffer and the copy past the end of cloud.data. I hit it while fuzzing the compressed reader: a 100-point XYZ cloud whose body claims 12 bytes drives the second plane pointer 288 bytes past the 12-byte buffer, which AddressSanitizer flags as a heap-buffer-overflow read, with the matching write landing outside the shrunk cloud.data. A valid writer always stores fsize * width * height here, which is exactly what cloud.data was sized to from the header, so the existing mismatch check now returns -1 instead of warning and resizing. The added test in test/io/test_io.cpp feeds readBodyBinary a short self-consistent compressed block and expects it to return -1 rather than overflow.