1 // SPDX-License-Identifier: 0BSD 2 3 /////////////////////////////////////////////////////////////////////////////// 4 // 5 /// \file index_decoder.c 6 /// \brief Decodes the Index field 7 // 8 // Author: Lasse Collin 9 // 10 /////////////////////////////////////////////////////////////////////////////// 11 12 #include "index_decoder.h" 13 #include "check.h" 14 15 16 typedef struct { 17 enum { 18 SEQ_INDICATOR, 19 SEQ_COUNT, 20 SEQ_MEMUSAGE, 21 SEQ_UNPADDED, 22 SEQ_UNCOMPRESSED, 23 SEQ_PADDING_INIT, 24 SEQ_PADDING, 25 SEQ_CRC32, 26 } sequence; 27 28 /// Memory usage limit 29 uint64_t memlimit; 30 31 // Memory used for lzma_index once it has been allocated. 32 // Before that, this holds a tiny value. 33 uint64_t memused; 34 35 /// Target Index 36 lzma_index *index; 37 38 /// Pointer give by the application, which is set after 39 /// successful decoding. 40 lzma_index **index_ptr; 41 42 /// If Number of Records contains a value higher than this, 43 /// the Index is immediately considered to be corrupt. 44 /// This prevents us from allocating a large amount of memory 45 /// when we know that the Index isn't big. 46 lzma_vli number_of_records_max; 47 48 /// Number of Records left to decode. 49 lzma_vli count; 50 51 /// The most recent Unpadded Size field 52 lzma_vli unpadded_size; 53 54 /// The most recent Uncompressed Size field 55 lzma_vli uncompressed_size; 56 57 /// Position in integers 58 size_t pos; 59 60 /// CRC32 of the List of Records field 61 uint32_t crc32; 62 } lzma_index_coder; 63 64 65 static lzma_ret 66 index_decode(void *coder_ptr, const lzma_allocator *allocator, 67 const uint8_t *restrict in, size_t *restrict in_pos, 68 size_t in_size, 69 uint8_t *restrict out lzma_attribute((__unused__)), 70 size_t *restrict out_pos lzma_attribute((__unused__)), 71 size_t out_size lzma_attribute((__unused__)), 72 lzma_action action lzma_attribute((__unused__))) 73 { 74 lzma_index_coder *coder = coder_ptr; 75 76 // Similar optimization as in index_encoder.c 77 const size_t in_start = *in_pos; 78 lzma_ret ret = LZMA_OK; 79 80 while (*in_pos < in_size) 81 switch (coder->sequence) { 82 case SEQ_INDICATOR: 83 // Return LZMA_DATA_ERROR instead of e.g. LZMA_PROG_ERROR or 84 // LZMA_FORMAT_ERROR, because a typical usage case for Index 85 // decoder is when parsing the Stream backwards. If seeking 86 // backward from the Stream Footer gives us something that 87 // doesn't begin with Index Indicator, the file is considered 88 // corrupt, not "programming error" or "unrecognized file 89 // format". One could argue that the application should 90 // verify the Index Indicator before trying to decode the 91 // Index, but well, I suppose it is simpler this way. 92 if (in[(*in_pos)++] != INDEX_INDICATOR) 93 return LZMA_DATA_ERROR; 94 95 coder->sequence = SEQ_COUNT; 96 break; 97 98 case SEQ_COUNT: 99 ret = lzma_vli_decode(&coder->count, &coder->pos, 100 in, in_pos, in_size); 101 if (ret != LZMA_STREAM_END) 102 goto out; 103 104 // Reject Number of Records values that are clearly invalid. 105 if (coder->count > coder->number_of_records_max) 106 return LZMA_DATA_ERROR; 107 108 coder->pos = 0; 109 coder->sequence = SEQ_MEMUSAGE; 110 FALLTHROUGH; 111 112 case SEQ_MEMUSAGE: 113 coder->memused = lzma_index_memusage(1, coder->count); 114 115 // We sanity-checked coder->count in SEQ_COUNT, which 116 // guarantees that lzma_index_memusage() won't fail. 117 assert(coder->memused != UINT64_MAX); 118 119 if (coder->memused > coder->memlimit) { 120 ret = LZMA_MEMLIMIT_ERROR; 121 goto out; 122 } 123 124 // Tell the Index handling code how many Records this 125 // Index has to allow it to allocate memory more efficiently. 126 // If the Record count is so high that memory allocation would 127 // fail later, return LZMA_MEM_ERROR now. 128 if (lzma_index_prealloc(coder->index, coder->count)) 129 return LZMA_MEM_ERROR; 130 131 ret = LZMA_OK; 132 coder->sequence = coder->count == 0 133 ? SEQ_PADDING_INIT : SEQ_UNPADDED; 134 break; 135 136 case SEQ_UNPADDED: 137 case SEQ_UNCOMPRESSED: { 138 lzma_vli *size = coder->sequence == SEQ_UNPADDED 139 ? &coder->unpadded_size 140 : &coder->uncompressed_size; 141 142 ret = lzma_vli_decode(size, &coder->pos, 143 in, in_pos, in_size); 144 if (ret != LZMA_STREAM_END) 145 goto out; 146 147 ret = LZMA_OK; 148 coder->pos = 0; 149 150 if (coder->sequence == SEQ_UNPADDED) { 151 // Validate that encoded Unpadded Size isn't too small 152 // or too big. 153 if (coder->unpadded_size < UNPADDED_SIZE_MIN 154 || coder->unpadded_size 155 > UNPADDED_SIZE_MAX) 156 return LZMA_DATA_ERROR; 157 158 coder->sequence = SEQ_UNCOMPRESSED; 159 } else { 160 // Add the decoded Record to the Index. 161 return_if_error(lzma_index_append( 162 coder->index, allocator, 163 coder->unpadded_size, 164 coder->uncompressed_size)); 165 166 // Check if this was the last Record. 167 coder->sequence = --coder->count == 0 168 ? SEQ_PADDING_INIT 169 : SEQ_UNPADDED; 170 } 171 172 break; 173 } 174 175 case SEQ_PADDING_INIT: 176 coder->pos = lzma_index_padding_size(coder->index); 177 coder->sequence = SEQ_PADDING; 178 FALLTHROUGH; 179 180 case SEQ_PADDING: 181 if (coder->pos > 0) { 182 --coder->pos; 183 if (in[(*in_pos)++] != 0x00) 184 return LZMA_DATA_ERROR; 185 186 break; 187 } 188 189 // Finish the CRC32 calculation. 190 coder->crc32 = lzma_crc32(in + in_start, 191 *in_pos - in_start, coder->crc32); 192 193 coder->sequence = SEQ_CRC32; 194 FALLTHROUGH; 195 196 case SEQ_CRC32: 197 do { 198 if (*in_pos == in_size) 199 return LZMA_OK; 200 201 if (((coder->crc32 >> (coder->pos * 8)) & 0xFF) 202 != in[(*in_pos)++]) { 203 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION 204 return LZMA_DATA_ERROR; 205 #endif 206 } 207 208 } while (++coder->pos < 4); 209 210 // Decoding was successful, now we can let the application 211 // see the decoded Index. 212 *coder->index_ptr = coder->index; 213 214 // Make index NULL so we don't free it unintentionally. 215 coder->index = NULL; 216 217 return LZMA_STREAM_END; 218 219 default: 220 assert(0); 221 return LZMA_PROG_ERROR; 222 } 223 224 out: 225 // Update the CRC32. 226 // 227 // Avoid null pointer + 0 (undefined behavior) in "in + in_start". 228 // In such a case we had no input and thus in_used == 0. 229 { 230 const size_t in_used = *in_pos - in_start; 231 if (in_used > 0) 232 coder->crc32 = lzma_crc32(in + in_start, 233 in_used, coder->crc32); 234 } 235 236 return ret; 237 } 238 239 240 static void 241 index_decoder_end(void *coder_ptr, const lzma_allocator *allocator) 242 { 243 lzma_index_coder *coder = coder_ptr; 244 lzma_index_end(coder->index, allocator); 245 lzma_free(coder, allocator); 246 return; 247 } 248 249 250 static lzma_ret 251 index_decoder_memconfig(void *coder_ptr, uint64_t *memusage, 252 uint64_t *old_memlimit, uint64_t new_memlimit) 253 { 254 lzma_index_coder *coder = coder_ptr; 255 256 // Index decoder is special in sense that the returned memusage 257 // doesn't include the memory usage of the decoder itself; only 258 // the resulting lzma_index is counted. 259 *memusage = coder->memused; 260 *old_memlimit = coder->memlimit; 261 262 if (new_memlimit != 0) { 263 if (new_memlimit < *memusage) 264 return LZMA_MEMLIMIT_ERROR; 265 266 coder->memlimit = new_memlimit; 267 } 268 269 return LZMA_OK; 270 } 271 272 273 static lzma_ret 274 index_decoder_reset(lzma_index_coder *coder, const lzma_allocator *allocator, 275 lzma_index **i, uint64_t memlimit, uint64_t input_size_max) 276 { 277 // Remember the pointer given by the application. We will set it 278 // to point to the decoded Index only if decoding is successful. 279 // Before that, keep it NULL so that applications can always safely 280 // pass it to lzma_index_end() no matter did decoding succeed or not. 281 coder->index_ptr = i; 282 *i = NULL; 283 284 // We always allocate a new lzma_index. 285 coder->index = lzma_index_init(allocator); 286 if (coder->index == NULL) 287 return LZMA_MEM_ERROR; 288 289 // Approximate how many Records the Index may contain at most when 290 // we know that the Index won't be larger than input_size_max bytes. 291 // Each Record must consume at least two bytes. The CRC32 etc. 292 // consume a few bytes too, but we don't need an exact value. 293 // 294 // file_info.c knows Backward Size and passes it to us. When we have 295 // no information, input_size_max equals LZMA_BACKWARD_SIZE_MAX. 296 coder->number_of_records_max = input_size_max / 2; 297 298 // Initialize the rest. 299 coder->sequence = SEQ_INDICATOR; 300 coder->memlimit = my_max(1, memlimit); 301 coder->memused = 1; // If _memconfig() is called before SEQ_MEMUSAGE. 302 coder->pos = 0; 303 coder->crc32 = 0; 304 305 return LZMA_OK; 306 } 307 308 309 extern lzma_ret 310 lzma_index_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator, 311 lzma_index **i, uint64_t memlimit, uint64_t input_size_max) 312 { 313 lzma_next_coder_init(&lzma_index_decoder_init, next, allocator); 314 315 if (i == NULL) 316 return LZMA_PROG_ERROR; 317 318 lzma_index_coder *coder = next->coder; 319 if (coder == NULL) { 320 coder = lzma_alloc(sizeof(lzma_index_coder), allocator); 321 if (coder == NULL) 322 return LZMA_MEM_ERROR; 323 324 next->coder = coder; 325 next->code = &index_decode; 326 next->end = &index_decoder_end; 327 next->memconfig = &index_decoder_memconfig; 328 coder->index = NULL; 329 } else { 330 lzma_index_end(coder->index, allocator); 331 } 332 333 return index_decoder_reset( 334 coder, allocator, i, memlimit, input_size_max); 335 } 336 337 338 extern LZMA_API(lzma_ret) 339 lzma_index_decoder(lzma_stream *strm, lzma_index **i, uint64_t memlimit) 340 { 341 // If i isn't NULL, *i must always be initialized due to 342 // the wording in the API docs. This way it is initialized 343 // if we return LZMA_PROG_ERROR due to strm == NULL. 344 if (i != NULL) 345 *i = NULL; 346 347 lzma_next_strm_init(lzma_index_decoder_init, strm, i, memlimit, 348 LZMA_BACKWARD_SIZE_MAX); 349 350 strm->internal->supported_actions[LZMA_RUN] = true; 351 strm->internal->supported_actions[LZMA_FINISH] = true; 352 353 return LZMA_OK; 354 } 355 356 357 extern LZMA_API(lzma_ret) 358 lzma_index_buffer_decode(lzma_index **i, uint64_t *memlimit, 359 const lzma_allocator *allocator, 360 const uint8_t *in, size_t *in_pos, size_t in_size) 361 { 362 // If i isn't NULL, *i must always be initialized due to 363 // the wording in the API docs. 364 if (i != NULL) 365 *i = NULL; 366 367 // Sanity checks 368 if (i == NULL || memlimit == NULL 369 || in == NULL || in_pos == NULL || *in_pos > in_size) 370 return LZMA_PROG_ERROR; 371 372 // Initialize the decoder. 373 lzma_index_coder coder; 374 const uint64_t input_size_max = in_size - *in_pos; 375 return_if_error(index_decoder_reset(&coder, allocator, i, *memlimit, 376 my_min(input_size_max, LZMA_BACKWARD_SIZE_MAX))); 377 378 // Store the input start position so that we can restore it in case 379 // of an error. 380 const size_t in_start = *in_pos; 381 382 // Do the actual decoding. 383 lzma_ret ret = index_decode(&coder, allocator, in, in_pos, in_size, 384 NULL, NULL, 0, LZMA_RUN); 385 386 if (ret == LZMA_STREAM_END) { 387 ret = LZMA_OK; 388 } else { 389 // Something went wrong, free the Index structure and restore 390 // the input position. 391 lzma_index_end(coder.index, allocator); 392 *in_pos = in_start; 393 394 if (ret == LZMA_OK) { 395 // The input is truncated or otherwise corrupt. 396 // Use LZMA_DATA_ERROR instead of LZMA_BUF_ERROR 397 // like lzma_vli_decode() does in single-call mode. 398 ret = LZMA_DATA_ERROR; 399 400 } else if (ret == LZMA_MEMLIMIT_ERROR) { 401 // Tell the caller how much memory would have 402 // been needed. 403 *memlimit = coder.memused; 404 } 405 } 406 407 return ret; 408 } 409