From patchwork Fri Dec 9 15:44:44 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Jackson X-Patchwork-Id: 9468491 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 2ACAF60586 for ; Fri, 9 Dec 2016 15:47:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1CD5628448 for ; Fri, 9 Dec 2016 15:47:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 117F62861D; Fri, 9 Dec 2016 15:47:48 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6BFD628448 for ; Fri, 9 Dec 2016 15:47:47 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cFNMG-0003J5-CO; Fri, 09 Dec 2016 15:45:12 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cFNMF-0003IG-N6 for xen-devel@lists.xensource.com; Fri, 09 Dec 2016 15:45:11 +0000 Received: from [193.109.254.147] by server-10.bemta-6.messagelabs.com id 0F/51-28971-681DA485; Fri, 09 Dec 2016 15:45:10 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprDIsWRWlGSWpSXmKPExsXitHSDvW7bRa8 IgyPTZSzuTXnP7sDosb1vF3sAYxRrZl5SfkUCa0b7jNiCj6YVrzo/sjYwTlLvYuTkkBDwl9jT cosRwvaQuH72BBOIzSagK9G05S8biC0ioCxxvOkLaxcjFwezwHMmiW09K8CKhAWCJNrObGcBs VkEVCTaZnQzg9i8Ap4SpxZcgxoqJ3H++E+wOKeAl8TMRTdYQWwhgXqJz4ub2LsYOYBsNYm56+ MhWgUlTs58AjaSWUBC4uCLF8wQYywlvq1/yjyBkX8WkrJZSMoWMDKtYtQoTi0qSy3SNTTSSyr KTM8oyU3MzNE1NDDTy00tLk5MT81JTCrWS87P3cQIDDUGINjBeHljwCFGSQ4mJVHeYiavCCG+ pPyUyozE4oz4otKc1OJDjDIcHEoSvJkXgHKCRanpqRVpmTnAoIdJS3DwKInwioGkeYsLEnOLM 9MhUqcYFaXEeRNAEgIgiYzSPLg2WKRdYpSVEuZlBDpEiKcgtSg3swRV/hWjOAejkjCvIsgUns y8Erjpr4AWMwEtnnfDHWRxSSJCSqqB0W97nXp4dpXErFcl4UfnJryaxuO1qyTubFjvEaeyDyX 6cqxX+4PFprB77/v06t2HU5FbXcO7Gq89OH96qs5Zle5qg38fWW2UbNWn7+pz+O51I2FB4eU/ 8xLafqUw/OeS8km15M5ekZi5UWlW7PSm6fav7qVM5LW0j8irUXDKNg3fW2Raq/pBiaU4I9FQi 7moOBEAEgkc+68CAAA= X-Env-Sender: prvs=1440ad286=Ian.Jackson@citrix.com X-Msg-Ref: server-4.tower-27.messagelabs.com!1481298308!75780974!2 X-Originating-IP: [66.165.176.63] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni42MyA9PiAzMDYwNDg=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 9.1.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 54415 invoked from network); 9 Dec 2016 15:45:10 -0000 Received: from smtp02.citrix.com (HELO SMTP02.CITRIX.COM) (66.165.176.63) by server-4.tower-27.messagelabs.com with RC4-SHA encrypted SMTP; 9 Dec 2016 15:45:10 -0000 X-IronPort-AV: E=Sophos;i="5.33,324,1477958400"; d="scan'208";a="402787247" X-CrossPremisesHeadersFilteredBySendConnector: FTLPEX02AMS01.citrite.net From: Ian Jackson To: Date: Fri, 9 Dec 2016 15:44:44 +0000 Message-ID: <1481298289-13546-4-git-send-email-ian.jackson@eu.citrix.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1481298289-13546-1-git-send-email-ian.jackson@eu.citrix.com> References: <22602.39819.815607.194639@mariner.uk.xensource.com> <1481298289-13546-1-git-send-email-ian.jackson@eu.citrix.com> MIME-Version: 1.0 X-OrganizationHeadersPreserved: FTLPEX02AMS01.citrite.net Cc: Stefano Stabellini , Wei Liu , George Dunlap , Andrew Cooper , Tim Deegan , Jan Beulich , Ian Jackson Subject: [Xen-devel] [PATCH 3/8] libelf: loop safety: Call elf_iter_ok[_counted] in every loop X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP In every `for' or `while' loop, either call elf_iter_ok, or explain why it's not necessary. This is part of comprehensive defence against out of control loops. Signed-off-by: Ian Jackson --- xen/common/libelf/libelf-dominfo.c | 22 +++++++++++++--------- xen/common/libelf/libelf-loader.c | 8 ++++---- xen/common/libelf/libelf-tools.c | 6 +++--- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/xen/common/libelf/libelf-dominfo.c b/xen/common/libelf/libelf-dominfo.c index 7f4a6a0..b139e32 100644 --- a/xen/common/libelf/libelf-dominfo.c +++ b/xen/common/libelf/libelf-dominfo.c @@ -43,10 +43,13 @@ elf_errorstatus elf_xen_parse_features(struct elf_binary *elf, if ( features == NULL ) return 0; - for ( pos = 0; features[pos] != '\0'; pos += len ) + for ( pos = 0; + elf_iter_ok_counted(elf, sizeof(feature)) && + features[pos] != '\0'; + pos += len ) { elf_memset_unchecked(feature, 0, sizeof(feature)); - for ( len = 0;; len++ ) + for ( len = 0;; len++ ) /* can't do more than sizeof(feature) */ { if ( len >= sizeof(feature)-1 ) break; @@ -60,7 +63,7 @@ elf_errorstatus elf_xen_parse_features(struct elf_binary *elf, feature[len] = features[pos + len]; } - for ( i = 0; i < elf_xen_features; i++ ) + for ( i = 0; elf_iter_ok(elf) && i < elf_xen_features; i++ ) { if ( !elf_xen_feature_names[i] ) continue; @@ -236,7 +239,7 @@ static unsigned elf_xen_parse_notes(struct elf_binary *elf, parms->elf_note_start = start; parms->elf_note_end = end; for ( note = ELF_MAKE_HANDLE(elf_note, parms->elf_note_start); - ELF_HANDLE_PTRVAL(note) < parms->elf_note_end; + elf_iter_ok(elf) && ELF_HANDLE_PTRVAL(note) < parms->elf_note_end; note = elf_note_next(elf, note) ) { #ifdef __XEN__ @@ -273,11 +276,12 @@ elf_errorstatus elf_xen_parse_guest_info(struct elf_binary *elf, h = parms->guest_info; #define STAR(h) (elf_access_unsigned(elf, (h), 0, 1)) - while ( STAR(h) ) + while ( elf_iter_ok_counted(elf, sizeof(name) + sizeof(value)) && + STAR(h) ) { elf_memset_unchecked(name, 0, sizeof(name)); elf_memset_unchecked(value, 0, sizeof(value)); - for ( len = 0;; len++, h++ ) + for ( len = 0;; len++, h++ ) /* covered by iter_ok_counted above */ { if ( len >= sizeof(name)-1 ) break; @@ -291,7 +295,7 @@ elf_errorstatus elf_xen_parse_guest_info(struct elf_binary *elf, if ( STAR(h) == '=' ) { h++; - for ( len = 0;; len++, h++ ) + for ( len = 0;; len++, h++ ) /* covered by iter_ok_counted */ { if ( len >= sizeof(value)-1 ) break; @@ -504,7 +508,7 @@ elf_errorstatus elf_xen_parse(struct elf_binary *elf, /* Find and parse elf notes. */ count = elf_phdr_count(elf); - for ( i = 0; i < count; i++ ) + for ( i = 0; elf_iter_ok(elf) && i < count; i++ ) { phdr = elf_phdr_by_index(elf, i); if ( !elf_access_ok(elf, ELF_HANDLE_PTRVAL(phdr), 1) ) @@ -537,7 +541,7 @@ elf_errorstatus elf_xen_parse(struct elf_binary *elf, if ( xen_elfnotes == 0 ) { count = elf_shdr_count(elf); - for ( i = 1; i < count; i++ ) + for ( i = 1; elf_iter_ok(elf) && i < count; i++ ) { shdr = elf_shdr_by_index(elf, i); if ( !elf_access_ok(elf, ELF_HANDLE_PTRVAL(shdr), 1) ) diff --git a/xen/common/libelf/libelf-loader.c b/xen/common/libelf/libelf-loader.c index 00479af..68c9021 100644 --- a/xen/common/libelf/libelf-loader.c +++ b/xen/common/libelf/libelf-loader.c @@ -85,7 +85,7 @@ elf_errorstatus elf_init(struct elf_binary *elf, const char *image_input, size_t /* Find symbol table and symbol string table. */ count = elf_shdr_count(elf); - for ( i = 1; i < count; i++ ) + for ( i = 1; elf_iter_ok(elf) && i < count; i++ ) { shdr = elf_shdr_by_index(elf, i); if ( !elf_access_ok(elf, ELF_HANDLE_PTRVAL(shdr), 1) ) @@ -425,7 +425,7 @@ do { \ * NB: this _must_ be done one by one, and taking the bitness into account, * so that the guest can treat this as an array of type Elf{32/64}_Shdr. */ - for ( i = 0; i < ELF_BSDSYM_SECTIONS; i++ ) + for ( i = 0; elf_iter_ok(elf) && i < ELF_BSDSYM_SECTIONS; i++ ) { rc = elf_load_image(elf, header_base + header_size + shdr_size * i, ELF_REALPTR2PTRVAL(&header.elf_header.section[i]), @@ -453,7 +453,7 @@ void elf_parse_binary(struct elf_binary *elf) unsigned i, count; count = elf_phdr_count(elf); - for ( i = 0; i < count; i++ ) + for ( i = 0; elf_iter_ok(elf) && i < count; i++ ) { phdr = elf_phdr_by_index(elf, i); if ( !elf_access_ok(elf, ELF_HANDLE_PTRVAL(phdr), 1) ) @@ -490,7 +490,7 @@ elf_errorstatus elf_load_binary(struct elf_binary *elf) uint64_t remain_allow_copy = (uint64_t)elf->dest_size * 2; count = elf_phdr_count(elf); - for ( i = 0; i < count; i++ ) + for ( i = 0; elf_iter_ok(elf) && i < count; i++ ) { phdr = elf_phdr_by_index(elf, i); if ( !elf_access_ok(elf, ELF_HANDLE_PTRVAL(phdr), 1) ) diff --git a/xen/common/libelf/libelf-tools.c b/xen/common/libelf/libelf-tools.c index a9edb6a..56dab63 100644 --- a/xen/common/libelf/libelf-tools.c +++ b/xen/common/libelf/libelf-tools.c @@ -153,7 +153,7 @@ ELF_HANDLE_DECL(elf_shdr) elf_shdr_by_name(struct elf_binary *elf, const char *n ELF_HANDLE_DECL(elf_shdr) shdr; const char *sname; - for ( i = 1; i < count; i++ ) + for ( i = 1; elf_iter_ok(elf) && i < count; i++ ) { shdr = elf_shdr_by_index(elf, i); if ( !elf_access_ok(elf, ELF_HANDLE_PTRVAL(shdr), 1) ) @@ -214,7 +214,7 @@ const char *elf_strval(struct elf_binary *elf, elf_ptrval start) if ( !elf_access_unsigned(elf, start, length, 1) ) /* ok */ return ELF_UNSAFE_PTR(start); - if ( length >= ELF_MAX_STRING_LENGTH ) + if ( !elf_iter_ok(elf) || length >= ELF_MAX_STRING_LENGTH ) { elf_mark_broken(elf, "excessively long string"); return NULL; @@ -262,7 +262,7 @@ ELF_HANDLE_DECL(elf_sym) elf_sym_by_name(struct elf_binary *elf, const char *sym uint64_t info, name; const char *sym_name; - for ( ; ptr < end; ptr += elf_size(elf, sym) ) + for ( ; elf_iter_ok(elf) && ptr < end; ptr += elf_size(elf, sym) ) { sym = ELF_MAKE_HANDLE(elf_sym, ptr); info = elf_uval(elf, sym, st_info);