From patchwork Tue Dec 16 07:00:05 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yousong Zhou X-Patchwork-Id: 422456 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from arrakis.dune.hu (arrakis.dune.hu [78.24.191.176]) (using TLSv1.1 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 751C7140079 for ; Thu, 18 Dec 2014 13:54:36 +1100 (AEDT) Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id 5D7F428BBF0; Thu, 18 Dec 2014 03:51:51 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on arrakis.dune.hu X-Spam-Level: X-Spam-Status: No, score=-0.9 required=5.0 tests=BAYES_00, DATE_IN_PAST_24_48, FREEMAIL_FROM,T_DKIM_INVALID autolearn=no version=3.3.2 Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id 9BAC628BBA5 for ; Thu, 18 Dec 2014 03:51:29 +0100 (CET) X-policyd-weight: using cached result; rate: -8.5 Received: from mail-pd0-f178.google.com (mail-pd0-f178.google.com [209.85.192.178]) by arrakis.dune.hu (Postfix) with ESMTPS for ; Thu, 18 Dec 2014 03:51:27 +0100 (CET) Received: by mail-pd0-f178.google.com with SMTP id r10so418953pdi.23 for ; Wed, 17 Dec 2014 18:53:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=YQ9Cd6EdP2o2jBkrxxilLF0qoGFOCcapabqVeCIT2Hw=; b=GUWU2G1ygk+7WwISpmTRPEdOXN88KAtlmHVZ/+RQaAXKbbsFs4qf3W6eHxmPionXXf km0Ys9qdryo4Zme/RzfkQLtuKjECOAsJBp5wQ+3qPZzJbkWCt2GjRkXC+pf3DasxrgtH iJZ0fwP+GJx2szth1JJmL/VO6OhmnT66Rkh6uuayeXP1ny8XHLrD2qoJGK9t4SYRCsQx wKPgiaNx/6W4ibYn4MV5bqUWo6CDXU5FgSEpOr3dkh2Wy79kIg86uAexivtPwbLgcB0v /I1DlMuwUsvpa+remN+6JZcE7vLiAA+no4sqB4f2/27ihRH0s8VDvVLt2JuipjrjNR3x nKCQ== X-Received: by 10.66.218.42 with SMTP id pd10mr73457822pac.151.1418871194200; Wed, 17 Dec 2014 18:53:14 -0800 (PST) Received: from debian.lan ([103.29.140.56]) by mx.google.com with ESMTPSA id oy7sm5104495pbc.88.2014.12.17.18.53.10 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 17 Dec 2014 18:53:12 -0800 (PST) From: Yousong Zhou To: nbd@openwrt.org Date: Tue, 16 Dec 2014 15:00:05 +0800 Message-Id: <1418713218-16300-4-git-send-email-yszhou4tech@gmail.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1418713218-16300-1-git-send-email-yszhou4tech@gmail.com> References: <1418713218-16300-1-git-send-email-yszhou4tech@gmail.com> Cc: openwrt-devel@lists.openwrt.org Subject: [OpenWrt-Devel] [PATCH v2 03/16] file: fix use-after-free bug. X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: openwrt-devel-bounces@lists.openwrt.org Sender: "openwrt-devel" 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 --- 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);