Fix: prevent heap corruption ("double free or corruption") during LAZ chunking#693
Open
ivancsicsmarkus wants to merge 2 commits into
Open
Fix: prevent heap corruption ("double free or corruption") during LAZ chunking#693ivancsicsmarkus wants to merge 2 commits into
ivancsicsmarkus wants to merge 2 commits into
Conversation
The LAZ chunker's extra-attribute path computed an `attributeOffset` by summing the sizes of every standard attribute in the *input* layout, then used that as the destination offset for memcpy'ing extras into the chunk's *output* buffer. Whenever --attributes filters the output to a subset, the input and output layouts diverge: format 2 places its first extra at input offset 27 but at output offset 20 when only intensity+rgb are kept. memcpy-ing 4 bytes at offset+27 into a 24-byte-stride per-point slot clobbers the next point's slot, eventually triggering a SIGSEGV in the worker thread that surfaces only as exit(123) after the "=== CREATING CHUNKS" header is printed. Drop the input-layout sum and use the output offset that was already being computed at line 595 (outputAttributes.getOffset(name)) — the same mechanism every standard-attribute handler in the same function uses. sourceOffset (input-side, advances per input attribute) is unchanged. Repro: any LAZ with extra-bytes attributes processed with --attributes filtering to a subset that includes the extra. Verified fixed against a laspy-written LAZ with a float32 'Deviation' extra dim, format 2. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix: prevent heap corruption ("double free or corruption") during LAZ chunking
Problem
Certain LAZ files cause PotreeConverter to crash with
double free or corruption (!prev)during the chunking phase. The root cause is a combination of unchecked error paths and missing bounds validation that allow heap metadata to be silently corrupted.Root causes
Unchecked laszip return values —
laszip_open_reader,laszip_seek_point, andlaszip_read_pointreturn error codes that were never checked. For LAZ files with missing or corrupt chunk tables, seeking fails silently and subsequent reads return garbage coordinates. These garbage values produce wrong bucket counts, causingBuffer::writeto overflow past its allocated size and corrupt heap metadata.Missing lower-bound grid index clamping — Grid index computation used
std::minto clamp the upper bound but had no lower bound protection. Floating point precision loss during the integer quantization round-trip could produce slightly negative normalized coordinates, resulting in negative array indices and out-of-bounds memory access.Non-returning sanity checks — The
numBytes < 0sanity checks in bothcountPointsInCellsanddistributePointslogged an error but continued execution, allowingmallocwith a bad size followed by writes to a null/stale buffer.Missing LAS 1.4 point formats —
formatToExtraIndexwas missing point data formats 8, 9, and 10, causingexit(123)inside thread pool workers for files using these common LAS 1.4 formats.Data race on shared counter — A
static int64_tcounter was shared across threads without synchronization.Changes
Converter/src/chunker_countsort_laszip.cpp:laszip_open_reader,laszip_seek_point, andlaszip_read_point; skip/return cleanly on failurestd::minwithstd::clampfor grid index computation (clamp to[0, gridSize-1])returnafter negativenumBytessanity checksformatToExtraIndexpointsProcessedcounterstd::atomic<int64_t>Converter/modules/unsuck/unsuck.hpp:Buffer::writeto prevent heap corruption on overflowTesting
Tested with a LAZ file that consistently crashed on the previous version. Conversion now completes successfully with
--encoding BROTLI.chunking-crashing.laz.zip