From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gnu.wildebeest.org (gnu.wildebeest.org [45.83.234.184]) by sourceware.org (Postfix) with ESMTPS id 9795F3858418 for ; Sat, 30 Dec 2023 17:41:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9795F3858418 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=klomp.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=klomp.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 9795F3858418 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=45.83.234.184 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1703958064; cv=none; b=c6tVJe7YyclPlifgNespRByZ2m3kyDGDRaL0HTc8CHI2ICN+DC/0zBOY6fzdMSe0zmY34u4qJSi0AdcJwZ5Zfhwy8hnrg87df4Z7wy14fhSD7Phxz6ebTUqeFP95gwgaE68+56vBL629AQI5yJee2iJDRKLnGR0MTyufncd8N7c= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1703958064; c=relaxed/simple; bh=w0wLbWN/x5sakGxQHtmDHXxV9XoC27npwbuTzlHyh/s=; h=Date:From:To:Subject:Message-ID:MIME-Version; b=uPFxzboTZ2117eu+oZOpvqA2N7Yz3CNdINLb88dOAyp1ReIWdORW5jtN8+VFiSsvMgoX45Ml5Cbrw8pXnMGl9CyUEbALmq6YhOvDbZjFuEYII6hJNkV5qiRLL+9tIKcIfrzHUOy6HMfqh86VaQjNZ/eLFptlnsKfeLie8ZsJ6R8= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by gnu.wildebeest.org (Postfix, from userid 1000) id A2976302BB42; Sat, 30 Dec 2023 18:41:01 +0100 (CET) Date: Sat, 30 Dec 2023 18:41:01 +0100 From: Mark Wielaard To: Daniel Xu Cc: elfutils-devel@sourceware.org Subject: Re: Noop round trip through elf_update() causes segfaults Message-ID: <20231230174101.GC9034@gnu.wildebeest.org> References: <43591825-18a6-4dbd-b27c-fa96d150dc31@app.fastmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <43591825-18a6-4dbd-b27c-fa96d150dc31@app.fastmail.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,JMQ_SPF_NEUTRAL,KAM_DMARC_STATUS,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Hi Daniel, On Wed, Dec 27, 2023 at 08:40:09PM -0600, Daniel Xu wrote: > I was working on code that adds an ELF section containing custom > metadata to ELF binaries when I started getting odd segfaults > in the added-to binary. > > I've managed to create a minimal reproducer with a couple interesting > discoveries. The reproducer is available here: > > https://github.com/danobi/elf-segfault > > Basically it does a noop round trip between elf_begin() and elf_update(). > But the resulting binary, when run, outputs: > > $ ./testprog_copy > fish: Job 1, './testprog_copy' terminated by signal SIGSEGV (Address boundary error) > > Furthermore, I built and ran tests/addsections.c [0] against my testbinary > and I still get: > > $ ./testprog_copy_elfutils > fish: Job 1, './testprog_copy_elfutils' terminated by signal SIGSEGV (Address boundary error) > > I've also tried linking against upstream libelf built from source > with the same results. > > This leads me to believe I'm doing something very wrong or > I'm hitting a bug. You aren't doing something very wrong, but libelf does something you aren't expecting. When you are calling elf_update () it will rearrange the elf sections making sure there are no unnecessary gaps between the sections in the file, that alignment is correct, etc. libelf only cares about the section headers. It doesn't know/care about the program headers. The program headers describe how the segments have to be loaded at runtime. Since some data has moved around the program data isn't loaded correctly anymore which causes the crash. To prevent libelf from doing this, and take responsibility of how the sections are layed out yourself you have to call: elf_flagelf (elf, ELF_C_SET, ELF_F_LAYOUT); Before calling elf_update. Note that in that case you are responsible for setting/updating the sh_offset fields of the Shdrs yourself. See for example the elfutils src/elfcompress.c program to see what it does in case the Elf file has program headers. Hope that helps, Mark