mirror of
https://github.com/anchore/syft.git
synced 2026-11-02 07:26:34 +01:00
fix: propagate non-EOF errors out of safeCopy (#4807)
Signed-off-by: SAY-5 <SAY-5@users.noreply.github.com>
This commit is contained in:
+13
-1
@@ -12,8 +12,20 @@ const perFileReadLimit = 2 * GB
|
||||
// protect against decompression bomb attacks.
|
||||
func safeCopy(writer io.Writer, reader io.Reader) error {
|
||||
numBytes, err := io.Copy(writer, io.LimitReader(reader, perFileReadLimit))
|
||||
if numBytes >= perFileReadLimit || errors.Is(err, io.EOF) {
|
||||
if numBytes >= perFileReadLimit {
|
||||
return fmt.Errorf("zip read limit hit (potential decompression bomb attack)")
|
||||
}
|
||||
// Propagate decompression / read errors up to the caller. io.Copy
|
||||
// on the happy path returns (n, nil); the only way err is non-nil
|
||||
// here is that the underlying reader surfaced a real failure
|
||||
// ("flate: corrupt input before offset X" on a mangled ZIP entry,
|
||||
// a network-backed reader erroring mid-stream, etc.). The previous
|
||||
// implementation dropped that error and the caller stored a
|
||||
// partial / empty buffer as a "successful" extract, which silently
|
||||
// downgraded Java cataloger output and caused SBOM scanners to
|
||||
// miss known CVEs (#4806).
|
||||
if err != nil && !errors.Is(err, io.EOF) {
|
||||
return fmt.Errorf("failed to read archive entry: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user