From patchwork Mon Jun 20 16:20:07 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Riku Voipio X-Patchwork-Id: 101145 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 4E343B6F80 for ; Tue, 21 Jun 2011 02:37:10 +1000 (EST) Received: from localhost ([::1]:39752 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QYhTG-0006qh-LI for incoming@patchwork.ozlabs.org; Mon, 20 Jun 2011 12:37:06 -0400 Received: from eggs.gnu.org ([140.186.70.92]:58505) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QYhDR-0003UD-Fg for qemu-devel@nongnu.org; Mon, 20 Jun 2011 12:20:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QYhDL-0008Ll-OA for qemu-devel@nongnu.org; Mon, 20 Jun 2011 12:20:45 -0400 Received: from afflict.kos.to ([92.243.29.197]:34614) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QYhDL-0008Jt-7J for qemu-devel@nongnu.org; Mon, 20 Jun 2011 12:20:39 -0400 Received: from kos.to (a88-115-163-181.elisa-laajakaista.fi [88.115.163.181]) (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by afflict.kos.to (Postfix) with ESMTPSA id 28D9D2668F; Mon, 20 Jun 2011 16:20:30 +0000 (UTC) Received: by kos.to (sSMTP sendmail emulation); Mon, 20 Jun 2011 19:20:29 +0300 From: riku.voipio@iki.fi To: qemu-devel@nongnu.org Date: Mon, 20 Jun 2011 19:20:07 +0300 Message-Id: <8a89625471221eac9e59330f03fa6bb2d3154ea5.1308583801.git.riku.voipio@iki.fi> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: References: MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 92.243.29.197 Cc: =?UTF-8?q?C=C3=A9dric=20VINCENT?= Subject: [Qemu-devel] [PATCH 02/18] linux-user: Fix the load of ELF files that have no "useful" symbol 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 From: Cédric VINCENT This patch fixes a "double free()" due to "realloc(syms, 0)" in the loader when the ELF file has no "useful" symbol, as with the following example (compiled with "sh4-linux-gcc -nostdlib"): .text .align 1 .global _start _start: mov #1, r3 trapa #40 // syscall(__NR_exit) nop The bug appears when the log (option "-d") is enabled. Signed-off-by: Cédric VINCENT Signed-off-by: Yves JANIN Signed-off-by: Riku Voipio --- linux-user/elfload.c | 34 +++++++++++++++++++--------------- 1 files changed, 19 insertions(+), 15 deletions(-) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index dcfeb7a..a4aabd5 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1643,9 +1643,9 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias) { int i, shnum, nsyms, sym_idx = 0, str_idx = 0; struct elf_shdr *shdr; - char *strings; - struct syminfo *s; - struct elf_sym *syms, *new_syms; + char *strings = NULL; + struct syminfo *s = NULL; + struct elf_sym *new_syms, *syms = NULL; shnum = hdr->e_shnum; i = shnum * sizeof(struct elf_shdr); @@ -1670,24 +1670,19 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias) /* Now know where the strtab and symtab are. Snarf them. */ s = malloc(sizeof(*s)); if (!s) { - return; + goto give_up; } i = shdr[str_idx].sh_size; s->disas_strtab = strings = malloc(i); if (!strings || pread(fd, strings, i, shdr[str_idx].sh_offset) != i) { - free(s); - free(strings); - return; + goto give_up; } i = shdr[sym_idx].sh_size; syms = malloc(i); if (!syms || pread(fd, syms, i, shdr[sym_idx].sh_offset) != i) { - free(s); - free(strings); - free(syms); - return; + goto give_up; } nsyms = i / sizeof(struct elf_sym); @@ -1710,16 +1705,18 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias) } } + /* No "useful" symbol. */ + if (nsyms == 0) { + goto give_up; + } + /* Attempt to free the storage associated with the local symbols that we threw away. Whether or not this has any effect on the memory allocation depends on the malloc implementation and how many symbols we managed to discard. */ new_syms = realloc(syms, nsyms * sizeof(*syms)); if (new_syms == NULL) { - free(s); - free(syms); - free(strings); - return; + goto give_up; } syms = new_syms; @@ -1734,6 +1731,13 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias) s->lookup_symbol = lookup_symbolxx; s->next = syminfos; syminfos = s; + + return; + +give_up: + free(s); + free(strings); + free(syms); } int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,