aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/widget-zcat.c
diff options
context:
space:
mode:
authorDavid M. Syzdek <syzdek@bindlebinaries.com>2017-07-06 22:47:23 -0800
committerDavid M. Syzdek <syzdek@bindlebinaries.com>2017-07-06 22:47:23 -0800
commit95348ac7ee6f0df4d581e595797373376ea0c8a0 (patch)
tree561e1edee715c804f4dd300181dec892b431cbaf /src/widget-zcat.c
parent3105ad8747c54a49efb929d6e5b8ab6003db67a3 (diff)
downloadsecurecoreutils-95348ac7ee6f0df4d581e595797373376ea0c8a0.tar.gz
securecoreutils-95348ac7ee6f0df4d581e595797373376ea0c8a0.tar.bz2
securecoreutils-95348ac7ee6f0df4d581e595797373376ea0c8a0.tar.xz
securecoreutils-95348ac7ee6f0df4d581e595797373376ea0c8a0.zip
Fixing segfault in zcat when compressed LZMA data exceeds input buffer.
Diffstat (limited to 'src/widget-zcat.c')
-rw-r--r--src/widget-zcat.c65
1 files changed, 23 insertions, 42 deletions
diff --git a/src/widget-zcat.c b/src/widget-zcat.c
index d2d3afd..2bc3d9c 100644
--- a/src/widget-zcat.c
+++ b/src/widget-zcat.c
@@ -390,7 +390,8 @@ int scu_widget_zcat_lzma(scu_config * cnf)
390 lzma_action action; 390 lzma_action action;
391 uint8_t in[16384]; 391 uint8_t in[16384];
392 uint8_t out[16384]; 392 uint8_t out[16384];
393 size_t len; 393 ssize_t len;
394 int eof;
394 395
395 bzero(&strm, sizeof(strm)); 396 bzero(&strm, sizeof(strm));
396 action = LZMA_RUN; 397 action = LZMA_RUN;
@@ -412,23 +413,26 @@ int scu_widget_zcat_lzma(scu_config * cnf)
412 return(1); 413 return(1);
413 }; 414 };
414 415
415 416 ret = LZMA_OK;
416 while (action == LZMA_RUN) 417 eof = 0;
418 while (ret == LZMA_OK)
417 { 419 {
418 // read from compressed file 420 // read from compressed file if input buffer is empty
419 strm.next_in = in; 421 if ((strm.avail_in == 0) && (!(eof)))
420 if (strm.avail_in != sizeof(in))
421 { 422 {
422 if ((len = read(fd, &in[strm.avail_in], (sizeof(in) - strm.avail_in))) == -1) 423 if ((len = read(fd, in, sizeof(in))) == -1)
423 { 424 {
424 fprintf(stderr, "%s: %s: %s\n", cnf->prog_name, cnf->widget->name, strerror(errno)); 425 fprintf(stderr, "%s: %s: %s\n", cnf->prog_name, cnf->widget->name, strerror(errno));
425 close(fd); 426 close(fd);
426 return(1); 427 return(1);
427 }; 428 };
428 if (len == 0) 429 strm.next_in = in;
430 strm.avail_in = len;
431 if (len < (ssize_t)sizeof(in))
432 {
429 action = LZMA_FINISH; 433 action = LZMA_FINISH;
430 else 434 eof = 1;
431 strm.avail_in += len; 435 };
432 }; 436 };
433 437
434 // uncompress file 438 // uncompress file
@@ -442,45 +446,22 @@ int scu_widget_zcat_lzma(scu_config * cnf)
442 }; 446 };
443 }; 447 };
444 448
445 // print uncompressed data 449 // print uncompressed data if buffer is full or done inflating data
446 if (strm.avail_out == sizeof(out)) 450 if ((strm.avail_out == 0) || (ret == LZMA_STREAM_END))
447 continue;
448 if ((len = write(STDOUT_FILENO, out, (sizeof(out) - strm.avail_out))) == -1)
449 { 451 {
450 fprintf(stderr, "%s: %s: %s\n", cnf->prog_name, cnf->widget->name, strerror(errno)); 452 if ((len = write(STDOUT_FILENO, out, (sizeof(out) - strm.avail_out))) == -1)
451 close(fd);
452 return(1);
453 };
454 strm.avail_out += len;
455 };
456
457 close(fd);
458
459 // finish uncompressing data
460 while ( (ret != LZMA_OK) && (ret != LZMA_STREAM_END))
461 {
462 // uncompress remaining data in buffer
463 if ((ret = lzma_code(&strm, action)) != LZMA_OK)
464 {
465 if (ret != LZMA_STREAM_END)
466 { 453 {
467 scu_widget_zcat_lzma_perror(cnf, ret); 454 fprintf(stderr, "%s: %s: %s\n", cnf->prog_name, cnf->widget->name, strerror(errno));
455 close(fd);
468 return(1); 456 return(1);
469 }; 457 };
458 strm.avail_out = sizeof(out);
459 strm.next_out = out;
470 }; 460 };
471
472 // print uncompressed data
473 if (strm.avail_out == sizeof(out))
474 continue;
475 if ((len = write(STDOUT_FILENO, out, (sizeof(out) - strm.avail_out))) == -1)
476 {
477 fprintf(stderr, "%s: %s: %s\n", cnf->prog_name, cnf->widget->name, strerror(errno));
478 close(fd);
479 return(1);
480 };
481 strm.avail_out += len;
482 }; 461 };
483 462
463 close(fd);
464
484 return(0); 465 return(0);
485} 466}
486 467