diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-07-15 11:55:51 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-15 11:55:51 -0700 |
commit | 87334dbccb2c00ab72e96d4b58cf128dfbf8f751 (patch) | |
tree | 72533d6368e39645e7d104e35e09ac5bcdc0a407 | |
parent | Merge pull request #2275 from RyanDwyer/transactionise-focus (diff) | |
parent | Add error handling for getting config file size (diff) | |
download | sway-87334dbccb2c00ab72e96d4b58cf128dfbf8f751.tar.gz sway-87334dbccb2c00ab72e96d4b58cf128dfbf8f751.tar.zst sway-87334dbccb2c00ab72e96d4b58cf128dfbf8f751.zip |
Merge pull request #2277 from ianyfan/config-read-fix
Fix config buffer overflow and logic
-rw-r--r-- | sway/config.c | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/sway/config.c b/sway/config.c index 636f5f57..2c051146 100644 --- a/sway/config.c +++ b/sway/config.c | |||
@@ -560,16 +560,21 @@ static char *expand_line(const char *block, const char *line, bool add_brace) { | |||
560 | 560 | ||
561 | bool read_config(FILE *file, struct sway_config *config) { | 561 | bool read_config(FILE *file, struct sway_config *config) { |
562 | bool reading_main_config = false; | 562 | bool reading_main_config = false; |
563 | char *this_config = NULL, *config_pos; | 563 | char *this_config = NULL; |
564 | long config_size = 0; | 564 | size_t config_size = 0; |
565 | if (config->current_config == NULL) { | 565 | if (config->current_config == NULL) { |
566 | reading_main_config = true; | 566 | reading_main_config = true; |
567 | 567 | ||
568 | fseek(file, 0, SEEK_END); | 568 | int ret_seek = fseek(file, 0, SEEK_END); |
569 | config_size = ftell(file); | 569 | long ret_tell = ftell(file); |
570 | if (ret_seek == -1 || ret_tell == -1) { | ||
571 | wlr_log(WLR_ERROR, "Unable to get size of config file"); | ||
572 | return false; | ||
573 | } | ||
574 | config_size = ret_tell; | ||
570 | rewind(file); | 575 | rewind(file); |
571 | 576 | ||
572 | config_pos = this_config = malloc(config_size + 1); | 577 | config->current_config = this_config = calloc(1, config_size + 1); |
573 | if (this_config == NULL) { | 578 | if (this_config == NULL) { |
574 | wlr_log(WLR_ERROR, "Unable to allocate buffer for config contents"); | 579 | wlr_log(WLR_ERROR, "Unable to allocate buffer for config contents"); |
575 | return false; | 580 | return false; |
@@ -580,6 +585,7 @@ bool read_config(FILE *file, struct sway_config *config) { | |||
580 | int line_number = 0; | 585 | int line_number = 0; |
581 | char *line; | 586 | char *line; |
582 | list_t *stack = create_list(); | 587 | list_t *stack = create_list(); |
588 | size_t read = 0; | ||
583 | while (!feof(file)) { | 589 | while (!feof(file)) { |
584 | char *block = stack->length ? stack->items[0] : NULL; | 590 | char *block = stack->length ? stack->items[0] : NULL; |
585 | line = read_line(file); | 591 | line = read_line(file); |
@@ -590,10 +596,21 @@ bool read_config(FILE *file, struct sway_config *config) { | |||
590 | wlr_log(WLR_DEBUG, "Read line %d: %s", line_number, line); | 596 | wlr_log(WLR_DEBUG, "Read line %d: %s", line_number, line); |
591 | 597 | ||
592 | if (reading_main_config) { | 598 | if (reading_main_config) { |
593 | size_t l = strlen(line); | 599 | size_t length = strlen(line); |
594 | memcpy(config_pos, line, l); // don't copy terminating character | 600 | |
595 | config_pos += l; | 601 | if (read + length > config_size) { |
596 | *config_pos++ = '\n'; | 602 | wlr_log(WLR_ERROR, "Config file changed during reading"); |
603 | list_foreach(stack, free); | ||
604 | list_free(stack); | ||
605 | free(line); | ||
606 | return false; | ||
607 | } | ||
608 | |||
609 | strcpy(this_config + read, line); | ||
610 | if (line_number != 1) { | ||
611 | this_config[read - 1] = '\n'; | ||
612 | } | ||
613 | read += length + 1; | ||
597 | } | 614 | } |
598 | 615 | ||
599 | line = strip_whitespace(line); | 616 | line = strip_whitespace(line); |
@@ -616,7 +633,6 @@ bool read_config(FILE *file, struct sway_config *config) { | |||
616 | list_foreach(stack, free); | 633 | list_foreach(stack, free); |
617 | list_free(stack); | 634 | list_free(stack); |
618 | free(line); | 635 | free(line); |
619 | free(this_config); | ||
620 | return false; | 636 | return false; |
621 | } | 637 | } |
622 | wlr_log(WLR_DEBUG, "Expanded line: %s", expanded); | 638 | wlr_log(WLR_DEBUG, "Expanded line: %s", expanded); |
@@ -677,10 +693,6 @@ bool read_config(FILE *file, struct sway_config *config) { | |||
677 | list_foreach(stack, free); | 693 | list_foreach(stack, free); |
678 | list_free(stack); | 694 | list_free(stack); |
679 | 695 | ||
680 | if (reading_main_config) { | ||
681 | this_config[config_size - 1] = '\0'; | ||
682 | config->current_config = this_config; | ||
683 | } | ||
684 | return success; | 696 | return success; |
685 | } | 697 | } |
686 | 698 | ||