[OpenWrt-Devel] [PATCH v2 03/16] file: fix use-after-free bug.

Yousong Zhou yszhou4tech at gmail.com
Tue Dec 16 02:00:05 EST 2014


Currently, it's possible that pointers returned by next_arg() could be
invalidated by another call to next_arg() due to uci_realloc().

Signed-off-by: Yousong Zhou <yszhou4tech at gmail.com>
---
 file.c |   41 +++++++++++++++++++++++++++++------------
 1 file changed, 29 insertions(+), 12 deletions(-)

diff --git a/file.c b/file.c
index 63ca919..1d2718a 100644
--- a/file.c
+++ b/file.c
@@ -239,7 +239,7 @@ done:
 /*
  * extract the next argument from the command line
  */
-static char *next_arg(struct uci_context *ctx, bool required, bool name)
+static int next_arg(struct uci_context *ctx, bool required, bool name)
 {
 	struct uci_parse_context *pctx = ctx->pctx;
 	int val, ptr;
@@ -262,11 +262,13 @@ static char *next_arg(struct uci_context *ctx, bool required, bool name)
 		uci_parse_error(ctx, "invalid character in name field");
 
 done:
-	return pctx_str(pctx, val);
+	return val;
 }
 
 int uci_parse_argument(struct uci_context *ctx, FILE *stream, char **str, char **result)
 {
+	int ofs_result;
+
 	UCI_HANDLE_ERR(ctx);
 	UCI_ASSERT(ctx, str != NULL);
 	UCI_ASSERT(ctx, result != NULL);
@@ -286,7 +288,10 @@ int uci_parse_argument(struct uci_context *ctx, FILE *stream, char **str, char *
 		UCI_ASSERT(ctx, ctx->pctx->pos == *str - ctx->pctx->buf);
 	}
 
-	*result = next_arg(ctx, false, false);
+	/*FIXME do we need to skip empty lines? */
+	ofs_result = next_arg(ctx, false, false);
+	*result = pctx_str(ctx->pctx, ofs_result);
+	*str = pctx_cur_str(ctx->pctx);
 
 	return 0;
 }
@@ -335,9 +340,11 @@ fill_package:
 static void assert_eol(struct uci_context *ctx)
 {
 	char *tmp;
+	int ofs_tmp;
 
 	skip_whitespace(ctx);
-	tmp = next_arg(ctx, false, false);
+	ofs_tmp = next_arg(ctx, false, false);
+	tmp = pctx_str(ctx->pctx, ofs_tmp);
 	if (*tmp && (ctx->flags & UCI_FLAG_STRICT))
 		uci_parse_error(ctx, "too many arguments");
 }
@@ -383,12 +390,14 @@ static void uci_switch_config(struct uci_context *ctx)
 static void uci_parse_package(struct uci_context *ctx, bool single)
 {
 	struct uci_parse_context *pctx = ctx->pctx;
-	char *name = NULL;
+	int ofs_name;
+	char *name;
 
 	/* command string null-terminated by strtok */
 	pctx->pos += strlen(pctx_cur_str(pctx)) + 1;
 
-	name = next_arg(ctx, true, true);
+	ofs_name = next_arg(ctx, true, true);
+	name = pctx_str(pctx, ofs_name);
 	assert_eol(ctx);
 	if (single)
 		return;
@@ -405,8 +414,9 @@ static void uci_parse_config(struct uci_context *ctx)
 	struct uci_parse_context *pctx = ctx->pctx;
 	struct uci_element *e;
 	struct uci_ptr ptr;
-	char *name = NULL;
-	char *type = NULL;
+	int ofs_name, ofs_type;
+	char *name;
+	char *type;
 
 	uci_fixup_section(ctx, ctx->pctx->section);
 	if (!ctx->pctx->package) {
@@ -419,10 +429,14 @@ static void uci_parse_config(struct uci_context *ctx)
 	/* command string null-terminated by strtok */
 	pctx->pos += strlen(pctx_cur_str(pctx)) + 1;
 
-	type = next_arg(ctx, true, false);
+	ofs_type = next_arg(ctx, true, false);
+	type = pctx_str(pctx, ofs_type);
 	if (!uci_validate_type(type))
 		uci_parse_error(ctx, "invalid character in type field");
-	name = next_arg(ctx, false, true);
+
+	ofs_name = next_arg(ctx, false, true);
+	type = pctx_str(pctx, ofs_type);
+	name = pctx_str(pctx, ofs_name);
 	assert_eol(ctx);
 
 	if (!name || !name[0]) {
@@ -450,6 +464,7 @@ static void uci_parse_option(struct uci_context *ctx, bool list)
 	struct uci_parse_context *pctx = ctx->pctx;
 	struct uci_element *e;
 	struct uci_ptr ptr;
+	int ofs_name, ofs_value;
 	char *name = NULL;
 	char *value = NULL;
 
@@ -459,8 +474,10 @@ static void uci_parse_option(struct uci_context *ctx, bool list)
 	/* command string null-terminated by strtok */
 	pctx->pos += strlen(pctx_cur_str(pctx)) + 1;
 
-	name = next_arg(ctx, true, true);
-	value = next_arg(ctx, false, false);
+	ofs_name = next_arg(ctx, true, true);
+	ofs_value = next_arg(ctx, false, false);
+	name = pctx_str(pctx, ofs_name);
+	value = pctx_str(pctx, ofs_value);
 	assert_eol(ctx);
 
 	uci_fill_ptr(ctx, &ptr, &pctx->section->e);
-- 
1.7.10.4
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list