From 6b35ae81a38573dcc42a944ebd8c2e6317cf5ad3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yaroslav=20de=20la=20Pe=C3=B1a=20Smirnov?= Date: Mon, 8 Nov 2021 17:44:18 +0300 Subject: slicecpy: fix buffer overflow on sections shorter than 3 chars. --- Makefile | 47 ++++++++++++++++++++++++----------------------- src/parcini.c | 15 ++++++--------- src/tests/parcini.c | 38 ++++++++++++++++++++++++++++++++------ test.ini | 6 +++++- 4 files changed, 67 insertions(+), 39 deletions(-) diff --git a/Makefile b/Makefile index a21748b..6576a87 100644 --- a/Makefile +++ b/Makefile @@ -1,38 +1,39 @@ CC?=gcc -RM:=rm -rf -SRC_DIR:=src -OBJ_DIR:=obj +CFLAGS:=-std=c99 -O0 -g -Wall -DDEBUG + INC_DIRS=$(addprefix -iquote,include) -PARCINI_SOURCES:=$(wildcard $(SRC_DIR)/*.c) -PARCINI_OBJECTS:=$(PARCINI_SOURCES:%.c=$(OBJ_DIR)/%.o) -BUILD_DIR:=build +BUILDIR:=build +OBJDIR:=$(BUILDIR)/obj + +PARCINI_SRCS:=$(wildcard src/*.c) +PARCINI_OBJS:=$(PARCINI_SRCS:%.c=$(OBJDIR)/%.o) -test: CFLAGS := -std=c99 -O0 -g -Wall -DDEBUG -test: $(BUILD_DIR) tests/parcini +ifdef ASAN +CFLAGS+= -fsanitize=address -fno-omit-frame-pointer +endif -tests/%: $(OBJ_DIR)/src/tests/%.o $(PARCINI_OBJECTS) - $(CC) $(LDFLAGS) -o $(BUILD_DIR)/$@ $^ - $(BUILD_DIR)/$@ +test: +test: $(BUILDIR) tests/parcini + +tests/%: $(OBJDIR)/src/tests/%.o $(PARCINI_OBJS) + mkdir -p $(BUILDIR)/$(@D) + $(CC) $(CFLAGS) $(LDFLAGS) -o $(BUILDIR)/$@ $^ + $(BUILDIR)/$@ example: CFLAGS := -std=c99 -O2 -Wall -example: $(OBJ_DIR)/example/example.o $(PARCINI_OBJECTS) - $(CC) $(LDFLAGS) -o $(BUILD_DIR)/example/$@ $^ +example: $(OBJDIR)/example/example.o $(PARCINI_OBJS) + mkdir -p $(@D) + $(CC) $(LDFLAGS) -o $(BUILDIR)/example/$@ $^ -$(OBJ_DIR)/%.o: %.c +$(OBJDIR)/%.o: %.c + mkdir -p $(@D) $(CC) -c $(CFLAGS) $(INC_DIRS) -o $@ $< -$(BUILD_DIR): - mkdir -p $(BUILD_DIR)/tests - mkdir -p $(BUILD_DIR)/example - mkdir -p $(OBJ_DIR)/src/tests - mkdir -p $(OBJ_DIR)/example - clean: - $(RM) $(OBJ_DIR) - $(RM) $(BUILD_DIR) + rm -r $(BUILDIR) .PHONY: clean test -.PRECIOUS: $(OBJ_DIR)/tests/%.o $(OBJ_DIR)/%.o +.PRECIOUS: $(OBJDIR)/tests/%.o $(OBJDIR)/%.o diff --git a/src/parcini.c b/src/parcini.c index 8434685..89a9356 100644 --- a/src/parcini.c +++ b/src/parcini.c @@ -56,16 +56,13 @@ lskip(char **start) static char * slicecpy(char *start, char *end, char **dst, size_t *dstn) { - size_t srcn = end - start + 1; - if (*dst == NULL) { - *dst = malloc(srcn + 1); - } - if (*dstn < srcn) { - char *newptr = realloc(*dst, srcn + 1); + size_t srcn = end - start; + if (*dstn < srcn + 1) { + *dstn = srcn + 1; + char *newptr = realloc(*dst, *dstn); if (newptr == NULL) { return NULL; } - *dstn = srcn + 1; *dst = newptr; } for (size_t i = 0; i < srcn; i++) { @@ -132,7 +129,7 @@ parcini_parse_next_line(parcini_t *parser, struct parcini_line *parsed) if (cmnt && cmnt < end) { return PARCINI_SECTION_PARSE_ERROR; } - if (!slicecpy(start + 1, end - 1, &parser->last_section, + if (!slicecpy(start + 1, end, &parser->last_section, &parser->last_section_n)) { return PARCINI_MEMORY_ERROR; } @@ -231,7 +228,7 @@ parcini_init(FILE *stream) if (parser != NULL) { parser->stream = stream; parser->last_section = strdup(""); - parser->last_section_n = 2; + parser->last_section_n = 1; } return parser; diff --git a/src/tests/parcini.c b/src/tests/parcini.c index 90d5997..7511115 100644 --- a/src/tests/parcini.c +++ b/src/tests/parcini.c @@ -53,7 +53,7 @@ test_parcini_parse_file(void) res = parcini_parse_next_line(parser, &line); asserteq(res, PARCINI_SECTION); asserteq(line.lineno, 6); - asserteq(strcmp(line.section, "asection"), 0); + asserteq(strcmp(line.section, "s"), 0); asserteq(line.key, NULL); asserteq(line.value.type, PARCINI_VALUE_NONE); @@ -61,7 +61,7 @@ test_parcini_parse_file(void) res = parcini_parse_next_line(parser, &line); asserteq(res, PARCINI_KEYVALUE); asserteq(line.lineno, 7); - asserteq(strcmp(line.section, "asection"), 0); + asserteq(strcmp(line.section, "s"), 0); asserteq(strcmp(line.key, "skey"), 0); asserteq(line.value.type, PARCINI_VALUE_STRING); asserteq(strcmp(line.value.value.string, "ur 2 slow"), 0); @@ -90,7 +90,7 @@ test_parcini_parse_file(void) res = parcini_parse_next_line(parser, &line); asserteq(res, PARCINI_KEYVALUE); asserteq(line.lineno, 12); - asserteq(strcmp(line.section, "asection"), 0); + asserteq(strcmp(line.section, "s"), 0); asserteq(strcmp(line.key, "bool2"), 0); asserteq(line.value.type, PARCINI_VALUE_BOOLEAN); asserteq(line.value.value.boolean, true); @@ -99,7 +99,7 @@ test_parcini_parse_file(void) res = parcini_parse_next_line(parser, &line); asserteq(res, PARCINI_KEYVALUE); asserteq(line.lineno, 13); - asserteq(strcmp(line.section, "asection"), 0); + asserteq(strcmp(line.section, "s"), 0); asserteq(strcmp(line.key, "bool3"), 0); asserteq(line.value.type, PARCINI_VALUE_BOOLEAN); asserteq(line.value.value.boolean, false); @@ -108,7 +108,7 @@ test_parcini_parse_file(void) res = parcini_parse_next_line(parser, &line); asserteq(res, PARCINI_KEYVALUE); asserteq(line.lineno, 14); - asserteq(strcmp(line.section, "asection"), 0); + asserteq(strcmp(line.section, "s"), 0); asserteq(strcmp(line.key, "bool3"), 0); asserteq(line.value.type, PARCINI_VALUE_BOOLEAN); asserteq(line.value.value.boolean, true); @@ -125,8 +125,34 @@ test_parcini_parse_file(void) /* line 17 */ res = parcini_parse_next_line(parser, &line); - asserteq(res, PARCINI_SECTION_PARSE_ERROR); + asserteq(res, PARCINI_SECTION); asserteq(line.lineno, 17); + asserteq(strcmp(line.section, "se"), 0); + asserteq(line.key, NULL); + asserteq(line.value.type, PARCINI_VALUE_NONE); + + /* line 18 */ + res = parcini_parse_next_line(parser, &line); + asserteq(res, PARCINI_EMPTY_LINE); + asserteq(line.lineno, 18); + + /* line 19 */ + res = parcini_parse_next_line(parser, &line); + asserteq(res, PARCINI_SECTION_PARSE_ERROR); + asserteq(line.lineno, 19); + + /* line 20 */ + res = parcini_parse_next_line(parser, &line); + asserteq(res, PARCINI_EMPTY_LINE); + asserteq(line.lineno, 20); + + /* line 21 */ + res = parcini_parse_next_line(parser, &line); + asserteq(res, PARCINI_SECTION); + asserteq(line.lineno, 21); + asserteq(strcmp(line.section, "section"), 0); + asserteq(line.key, NULL); + asserteq(line.value.type, PARCINI_VALUE_NONE); /* EOF */ res = parcini_parse_next_line(parser, &line); diff --git a/test.ini b/test.ini index 6f16ce0..389b74b 100644 --- a/test.ini +++ b/test.ini @@ -3,7 +3,7 @@ key2= -1520 3=no #test one character keys # this is a comment -[asection] +[s] skey="ur 2 slow" #with comment bad=#this is not good bad2$#this is also bad @@ -14,4 +14,8 @@ bool3=false bool3 = true =false #another bad key +[se] + [bad section + +[section] -- cgit v1.2.3