From patchwork Thu Aug 29 13:47:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Wielaard X-Patchwork-Id: 96697 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4388B3860C3B for ; Thu, 29 Aug 2024 13:48:16 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from gnu.wildebeest.org (gnu.wildebeest.org [45.83.234.184]) by sourceware.org (Postfix) with ESMTPS id 1FF20385F01D for ; Thu, 29 Aug 2024 13:47:58 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 1FF20385F01D 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 1FF20385F01D 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=1724939288; cv=none; b=T3FZV+18R7zUcb7dhbnA7IB4ouVl4b3/PYpqXRWj9iD2bCCwccG4nz6eXfF7jT1lhlUhlxnDUZdfjSaFQDXcIhNe4KcU9GQ3c1tu5KjkdnMo5cNUZ0pyBQu4AxQXYRNyeslyjQA9vNV+5OSG8dCrJ07T42VsALcBANSSPkoY4+w= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1724939288; c=relaxed/simple; bh=NQGefqXyoQ+Jh43rklFoGkEgCsTrolUKrapm7lnXc/s=; h=Date:From:To:Subject:Message-ID:MIME-Version; b=KjdhRa1zWuXCBDPhx/4NoAlu5/W49rETnLbauG/njvJTffzHtgen5cZFyibVr8NG4D8GvvXeqgbAlNkv2Ee9bglwbk6znwyk8kwGVAj6tukIcKiLsqm9dcmhdYfF25Fn6aMg1W+3hLcjvjvBedFkAjz8UYwuI0Ya9yn6J3IGFg8= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by gnu.wildebeest.org (Postfix, from userid 1000) id 2246F3000432; Thu, 29 Aug 2024 15:47:57 +0200 (CEST) Date: Thu, 29 Aug 2024 15:47:57 +0200 From: Mark Wielaard To: elfutils-devel@sourceware.org Cc: Derek Bruening , John Mellor-Crummey Subject: elf_memory again, readonly or readwrite... Message-ID: <20240829134757.GC4864@gnu.wildebeest.org> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-Spam-Status: No, score=-8.7 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: elfutils-devel-bounces~patchwork=sourceware.org@sourceware.org Hi, So we changed elf_memory so it pretends the in-memory Elf image is read with ELF_C_READ_MMAP. This helps when calling elf_memory on read-only memory which still wants to change some things about the Elf like uncompress some sections (which changes the section header). With ELF_C_READ_MMAP libelf will make a copy of the section headers, so any changes aren't written to the memory image (because that would crash if the underlying memory is read-only). But that breaks another use case where elf_memory is used on rw memory and then the section headers are updated using libelf and it is expected those in-memory section headers reflect the changes. The problem of course is the elf_memory function doesn't take a "mode" argument. So we have to guess. And make one or the other usage unusable. I think we should assume the memory is read/write and at least header updates are written back to the memory image. But that when only just reading the image then nothing is changed and written back to the image. This does mean that when explicitly uncompressing sections you have to make sure the image is writable (because that updates the shdrs). Is that bad/unreasonable? Derek, would it make your use case impossible? John, what kind of Shdr changes are you expecting to get written back to the memory image. Are there any issues that cannot be worked around by always using the Shdr copy given back from (g)elf[32|64]_shdr? The patch I am thinking of is attached. Cheers, Mark diff --git a/libelf/elf_memory.c b/libelf/elf_memory.c index 13d77cb71b39..1df49d732dd9 100644 --- a/libelf/elf_memory.c +++ b/libelf/elf_memory.c @@ -46,5 +46,6 @@ elf_memory (char *image, size_t size) return NULL; } - return __libelf_read_mmaped_file (-1, image, 0, size, ELF_C_READ_MMAP, NULL); + return __libelf_read_mmaped_file (-1, image, 0, size, + ELF_C_READ_MMAP_PRIVATE, NULL); } diff --git a/tests/elfgetzdata.c b/tests/elfgetzdata.c index 0af6c223a06b..a50275fea1a7 100644 --- a/tests/elfgetzdata.c +++ b/tests/elfgetzdata.c @@ -69,7 +69,8 @@ main (int argc, char *argv[]) else { assert (do_mem); - // We mmap the memory ourselves, explicitly PROT_READ only + // We mmap the memory ourselves, explicitly PROT_READ | PROT_WRITE + // elf_memory needs writable memory when using elf_compress. struct stat st; if (fstat (fd, &st) != 0) { @@ -79,7 +80,8 @@ main (int argc, char *argv[]) continue; } map_size = st.st_size; - map_address = mmap (NULL, map_size, PROT_READ, MAP_PRIVATE, fd, 0); + map_address = mmap (NULL, map_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE, fd, 0); if (map_address == MAP_FAILED) { printf ("%s cannot mmap %s\n", argv[cnt], strerror (errno));