Commit cdf7d43
authored
* Add decompression-bomb cap to LERC and JPEG 2000 codecs (#1625)
The deflate, zstd, lz4, and packbits wrappers all received a pre-decode
output-size cap in #1533 so a crafted TIFF tile cannot expand to many
GB before the post-decode size check fires. LERC and JPEG 2000 were
missed: lerc_decompress_with_mask and jpeg2000_decompress called the
underlying lerc.decode / glymur.Jp2k[:] with no bound, so the existing
size check in _decode_strip_or_tile ran only after the full buffer had
already been materialised by the external library.
LERC compresses constant-value blocks at >700,000:1, so a 94-byte blob
can request 64 MiB of host memory. A 1 KB on-disk LERC tile can ask
for several GB before the reader rejects it. JPEG 2000 has similar
amplification potential through codestream-declared dimensions.
Fix: query each codestream's declared dimensions before decoding.
- LERC: lerc.getLercBlobInfo(blob) returns nCols, nRows, nBands, and
dataType from the header without decoding. Compute the projected
output bytes and raise ValueError when it exceeds the same
expected_size * 1.05 + 1 cap used by every other codec.
- JPEG 2000: glymur.Jp2k(file).shape parses only the SIZ marker, so
inspecting it before [:] is cheap.
Pillow's JPEG decoder already has Image.MAX_IMAGE_PIXELS and raises
DecompressionBombError, so no wrapper-level cap is needed there.
Plumb expected_size through the decompress() dispatcher,
_decode_strip_or_tile's LERC branch, and the _gpu_decode CPU
fallbacks for both codecs.
Tests cover bomb-rejection and legitimate round-trips at the codec
level for both LERC and JPEG 2000, plus the existing zero-expected-size
backward-compat path.
Found by /sweep-security on the geotiff module.
* Address review: harden JPEG 2000 / LERC bomb pre-checks
Copilot review on #1629 flagged four issues. Fixes:
- np.prod overflow (JPEG 2000): replace ``int(np.prod(shape))`` with
``math.prod(int(d) for d in shape)``. ``np.prod`` multiplies in
fixed-width intp and can wrap to a small or negative value on
attacker-declared dimensions (SIZ marker uses uint32 fields, so a
malformed tile can declare shape whose product exceeds int64),
silently under-counting the declared size and bypassing the cap.
``math.prod`` uses Python arbitrary-precision ints.
- Fail-closed on unreadable SIZ marker (JPEG 2000): previously, an
exception from ``jp2.shape`` or ``jp2.dtype`` disabled the cap and
fell through to ``jp2[:]`` (the bomb path). ``getattr(jp2, 'dtype',
np.uint8)`` also defaulted to the smallest dtype, undercounting
declared bytes. Now both failure modes raise ValueError before any
pixel decoding runs. Added test_jpeg2000_unreadable_shape_fails_closed
to lock it in (monkeypatches Jp2k.shape to raise; asserts jp2[:] is
never invoked).
- LERC errCode not checked: ``lerc.getLercBlobInfo`` returns
``(errCode, ...)`` and when errCode != 0 the remaining fields can be
garbage. ``_check_lerc_bomb`` now returns early in that case so the
canonical error comes from ``lerc.decode``, not from a spurious
declared-size computation.
- Unused ``import os`` in test_jpeg2000_bomb_raises (flake8 F401):
removed.
1 parent c294578 commit cdf7d43
5 files changed
Lines changed: 282 additions & 11 deletions
File tree
- .claude
- xrspatial/geotiff
- tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
21 | | - | |
| 21 | + | |
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1112 | 1112 | | |
1113 | 1113 | | |
1114 | 1114 | | |
1115 | | - | |
1116 | | - | |
| 1115 | + | |
| 1116 | + | |
| 1117 | + | |
| 1118 | + | |
| 1119 | + | |
| 1120 | + | |
| 1121 | + | |
| 1122 | + | |
| 1123 | + | |
| 1124 | + | |
| 1125 | + | |
1117 | 1126 | | |
1118 | 1127 | | |
1119 | 1128 | | |
1120 | 1129 | | |
| 1130 | + | |
1121 | 1131 | | |
1122 | 1132 | | |
1123 | 1133 | | |
| |||
1126 | 1136 | | |
1127 | 1137 | | |
1128 | 1138 | | |
| 1139 | + | |
| 1140 | + | |
| 1141 | + | |
| 1142 | + | |
| 1143 | + | |
| 1144 | + | |
| 1145 | + | |
| 1146 | + | |
| 1147 | + | |
| 1148 | + | |
| 1149 | + | |
| 1150 | + | |
| 1151 | + | |
| 1152 | + | |
| 1153 | + | |
| 1154 | + | |
| 1155 | + | |
| 1156 | + | |
| 1157 | + | |
| 1158 | + | |
| 1159 | + | |
| 1160 | + | |
| 1161 | + | |
| 1162 | + | |
| 1163 | + | |
| 1164 | + | |
| 1165 | + | |
| 1166 | + | |
| 1167 | + | |
| 1168 | + | |
| 1169 | + | |
| 1170 | + | |
| 1171 | + | |
| 1172 | + | |
| 1173 | + | |
1129 | 1174 | | |
1130 | 1175 | | |
1131 | 1176 | | |
| |||
1174 | 1219 | | |
1175 | 1220 | | |
1176 | 1221 | | |
| 1222 | + | |
| 1223 | + | |
| 1224 | + | |
| 1225 | + | |
| 1226 | + | |
| 1227 | + | |
| 1228 | + | |
| 1229 | + | |
| 1230 | + | |
| 1231 | + | |
| 1232 | + | |
| 1233 | + | |
| 1234 | + | |
| 1235 | + | |
| 1236 | + | |
| 1237 | + | |
| 1238 | + | |
| 1239 | + | |
| 1240 | + | |
| 1241 | + | |
| 1242 | + | |
| 1243 | + | |
| 1244 | + | |
| 1245 | + | |
| 1246 | + | |
| 1247 | + | |
| 1248 | + | |
| 1249 | + | |
| 1250 | + | |
| 1251 | + | |
| 1252 | + | |
| 1253 | + | |
| 1254 | + | |
| 1255 | + | |
| 1256 | + | |
| 1257 | + | |
| 1258 | + | |
| 1259 | + | |
| 1260 | + | |
| 1261 | + | |
| 1262 | + | |
| 1263 | + | |
| 1264 | + | |
| 1265 | + | |
| 1266 | + | |
| 1267 | + | |
| 1268 | + | |
| 1269 | + | |
| 1270 | + | |
| 1271 | + | |
| 1272 | + | |
| 1273 | + | |
| 1274 | + | |
| 1275 | + | |
1177 | 1276 | | |
1178 | | - | |
| 1277 | + | |
1179 | 1278 | | |
1180 | 1279 | | |
1181 | 1280 | | |
1182 | 1281 | | |
1183 | 1282 | | |
1184 | 1283 | | |
1185 | 1284 | | |
| 1285 | + | |
| 1286 | + | |
| 1287 | + | |
| 1288 | + | |
| 1289 | + | |
1186 | 1290 | | |
1187 | | - | |
| 1291 | + | |
| 1292 | + | |
1188 | 1293 | | |
1189 | 1294 | | |
1190 | 1295 | | |
1191 | | - | |
| 1296 | + | |
1192 | 1297 | | |
1193 | 1298 | | |
1194 | 1299 | | |
| |||
1198 | 1303 | | |
1199 | 1304 | | |
1200 | 1305 | | |
| 1306 | + | |
| 1307 | + | |
| 1308 | + | |
| 1309 | + | |
| 1310 | + | |
| 1311 | + | |
| 1312 | + | |
| 1313 | + | |
| 1314 | + | |
1201 | 1315 | | |
1202 | 1316 | | |
1203 | 1317 | | |
1204 | 1318 | | |
1205 | 1319 | | |
| 1320 | + | |
1206 | 1321 | | |
1207 | 1322 | | |
1208 | 1323 | | |
| |||
1355 | 1470 | | |
1356 | 1471 | | |
1357 | 1472 | | |
1358 | | - | |
| 1473 | + | |
| 1474 | + | |
| 1475 | + | |
1359 | 1476 | | |
1360 | 1477 | | |
1361 | 1478 | | |
1362 | 1479 | | |
1363 | 1480 | | |
1364 | | - | |
| 1481 | + | |
| 1482 | + | |
| 1483 | + | |
1365 | 1484 | | |
1366 | 1485 | | |
1367 | 1486 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1933 | 1933 | | |
1934 | 1934 | | |
1935 | 1935 | | |
1936 | | - | |
| 1936 | + | |
| 1937 | + | |
| 1938 | + | |
1937 | 1939 | | |
1938 | 1940 | | |
1939 | 1941 | | |
| |||
1953 | 1955 | | |
1954 | 1956 | | |
1955 | 1957 | | |
1956 | | - | |
| 1958 | + | |
| 1959 | + | |
1957 | 1960 | | |
1958 | 1961 | | |
1959 | 1962 | | |
| |||
0 commit comments