summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-07-15 11:55:51 -0700
committerLibravatar GitHub <noreply@github.com>2018-07-15 11:55:51 -0700
commit87334dbccb2c00ab72e96d4b58cf128dfbf8f751 (patch)
tree72533d6368e39645e7d104e35e09ac5bcdc0a407
parentMerge pull request #2275 from RyanDwyer/transactionise-focus (diff)
parentAdd error handling for getting config file size (diff)
downloadsway-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.c40
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
561bool read_config(FILE *file, struct sway_config *config) { 561bool 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