From patchwork Fri Jul 22 11:33:27 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Fergeau X-Patchwork-Id: 106260 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 5CE77B6F77 for ; Fri, 22 Jul 2011 21:34:33 +1000 (EST) Received: from localhost ([::1]:60255 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QkDzr-00085o-59 for incoming@patchwork.ozlabs.org; Fri, 22 Jul 2011 07:34:23 -0400 Received: from eggs.gnu.org ([140.186.70.92]:39845) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QkDz6-0005jV-GB for qemu-devel@nongnu.org; Fri, 22 Jul 2011 07:33:40 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QkDz5-000095-GC for qemu-devel@nongnu.org; Fri, 22 Jul 2011 07:33:36 -0400 Received: from mx1.redhat.com ([209.132.183.28]:36532) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QkDz5-00008y-8D for qemu-devel@nongnu.org; Fri, 22 Jul 2011 07:33:35 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p6MBXYQk012470 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 22 Jul 2011 07:33:34 -0400 Received: from localhost.localdomain (ovpn-116-27.ams2.redhat.com [10.36.116.27]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p6MBXUcr005459 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Fri, 22 Jul 2011 07:33:33 -0400 From: Christophe Fergeau To: qemu-devel@nongnu.org Date: Fri, 22 Jul 2011 13:33:27 +0200 Message-Id: <1311334410-28559-2-git-send-email-cfergeau@redhat.com> In-Reply-To: <1311334410-28559-1-git-send-email-cfergeau@redhat.com> References: <1311334410-28559-1-git-send-email-cfergeau@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCHv3 1/4] libcacard: fix soft=... parsing in vcard_emul_options X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org The previous parser had copy and paste errors when computing vname_length and type_params_length, "name" was used instead of respectively vname and type_params. This led to length that could be bigger than the input string, and to access out of the array bounds when trying to copy these strings. valgrind rightfully complained about this. It also didn't handle empty fields correctly, Signed-off-by: Christophe Fergeau Reviewed-by: Alon Levy --- libcacard/vcard_emul_nss.c | 45 +++++++++++++++++++++++++++---------------- 1 files changed, 28 insertions(+), 17 deletions(-) diff --git a/libcacard/vcard_emul_nss.c b/libcacard/vcard_emul_nss.c index 184252f..9271f58 100644 --- a/libcacard/vcard_emul_nss.c +++ b/libcacard/vcard_emul_nss.c @@ -980,8 +980,6 @@ vcard_emul_options(const char *args) { int reader_count = 0; VCardEmulOptions *opts; - char type_str[100]; - int type_len; /* Allow the future use of allocating the options structure on the fly */ memcpy(&options, &default_options, sizeof(options)); @@ -996,18 +994,24 @@ vcard_emul_options(const char *args) * cert_2,cert_3...) */ if (strncmp(args, "soft=", 5) == 0) { const char *name; + size_t name_length; const char *vname; + size_t vname_length; const char *type_params; + size_t type_params_length; + char type_str[100]; VCardEmulType type; - int name_length, vname_length, type_params_length, count, i; + int count, i; VirtualReaderOptions *vreaderOpt = NULL; args = strip(args + 5); if (*args != '(') { continue; } + args = strip(args+1); + name = args; - args = strpbrk(args + 1, ",)"); + args = strpbrk(args, ",)"); if (*args == 0) { break; } @@ -1015,10 +1019,11 @@ vcard_emul_options(const char *args) args++; continue; } + name_length = args - name; args = strip(args+1); - name_length = args - name - 2; + vname = args; - args = strpbrk(args + 1, ",)"); + args = strpbrk(args, ",)"); if (*args == 0) { break; } @@ -1026,13 +1031,10 @@ vcard_emul_options(const char *args) args++; continue; } - vname_length = args - name - 2; + vname_length = args - vname; args = strip(args+1); - type_len = strpbrk(args, ",)") - args; - assert(sizeof(type_str) > type_len); - strncpy(type_str, args, type_len); - type_str[type_len] = 0; - type = vcard_emul_type_from_string(type_str); + + type_params = args; args = strpbrk(args, ",)"); if (*args == 0) { break; @@ -1041,9 +1043,16 @@ vcard_emul_options(const char *args) args++; continue; } + type_params_length = args - type_params; args = strip(args+1); + + type_params_length = MIN(type_params_length, sizeof(type_str)-1); + strncpy(type_str, type_params, type_params_length); + type_str[type_params_length] = 0; + type = vcard_emul_type_from_string(type_str); + type_params = args; - args = strpbrk(args + 1, ",)"); + args = strpbrk(args, ",)"); if (*args == 0) { break; } @@ -1051,8 +1060,9 @@ vcard_emul_options(const char *args) args++; continue; } - type_params_length = args - name; + type_params_length = args - type_params; args = strip(args+1); + if (*args == 0) { break; } @@ -1072,13 +1082,14 @@ vcard_emul_options(const char *args) vreaderOpt->card_type = type; vreaderOpt->type_params = copy_string(type_params, type_params_length); - count = count_tokens(args, ',', ')'); + count = count_tokens(args, ',', ')') + 1; vreaderOpt->cert_count = count; vreaderOpt->cert_name = (char **)qemu_malloc(count*sizeof(char *)); for (i = 0; i < count; i++) { - const char *cert = args + 1; - args = strpbrk(args + 1, ",)"); + const char *cert = args; + args = strpbrk(args, ",)"); vreaderOpt->cert_name[i] = copy_string(cert, args - cert); + args = strip(args+1); } if (*args == ')') { args++;