Message ID | 20231010134300.53830-3-mark@klomp.org |
---|---|
State | Superseded |
Delegated to: | Aaron Merey |
Headers |
Return-Path: <elfutils-devel-bounces+patchwork=sourceware.org@sourceware.org> 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 AC846385CC8A for <patchwork@sourceware.org>; Tue, 10 Oct 2023 13:43:41 +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 9908B3858C2A for <elfutils-devel@sourceware.org>; Tue, 10 Oct 2023 13:43:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9908B3858C2A Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=klomp.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=klomp.org Received: from r6.localdomain (82-217-174-174.cable.dynamic.v4.ziggo.nl [82.217.174.174]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id 582DB301BC1A; Tue, 10 Oct 2023 15:43:34 +0200 (CEST) Received: by r6.localdomain (Postfix, from userid 1000) id 17BB434032D; Tue, 10 Oct 2023 15:43:34 +0200 (CEST) From: Mark Wielaard <mark@klomp.org> To: elfutils-devel@sourceware.org Cc: hsm2@rice.edu, Mark Wielaard <mark@klomp.org> Subject: [PATCH 03/16] libelf: Fix deadlock in __libelf_readall Date: Tue, 10 Oct 2023 15:42:47 +0200 Message-ID: <20231010134300.53830-3-mark@klomp.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231010134300.53830-1-mark@klomp.org> References: <301fac87e83ebbbd677750579ae9a3429b461bdf.camel@klomp.org> <20231010134300.53830-1-mark@klomp.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-3033.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, RCVD_IN_BARRACUDACENTRAL, SPF_HELO_NONE, SPF_PASS, TXREP 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 <elfutils-devel.sourceware.org> List-Unsubscribe: <https://sourceware.org/mailman/options/elfutils-devel>, <mailto:elfutils-devel-request@sourceware.org?subject=unsubscribe> List-Archive: <https://sourceware.org/pipermail/elfutils-devel/> List-Post: <mailto:elfutils-devel@sourceware.org> List-Help: <mailto:elfutils-devel-request@sourceware.org?subject=help> List-Subscribe: <https://sourceware.org/mailman/listinfo/elfutils-devel>, <mailto:elfutils-devel-request@sourceware.org?subject=subscribe> Errors-To: elfutils-devel-bounces+patchwork=sourceware.org@sourceware.org |
Series |
[01/16] lib: Add new once_define and once macros to eu-config.h
|
|
Commit Message
Mark Wielaard
Oct. 10, 2023, 1:42 p.m. UTC
From: Heather McIntyre <hsm2@rice.edu> * libelf/elf_readall.c (__libelf_readall): Move rwlock_unlock before libelf_acquire_all. Signed-off-by: Heather S. McIntyre <hsm2@rice.edu> Signed-off-by: Mark Wielaard <mark@klomp.org> --- libelf/elf_readall.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
Comments
Hi Heather, On Tue, 2023-10-10 at 15:42 +0200, Mark Wielaard wrote: > From: Heather McIntyre <hsm2@rice.edu> > > * libelf/elf_readall.c (__libelf_readall): Move rwlock_unlock > before libelf_acquire_all. > > Signed-off-by: Heather S. McIntyre <hsm2@rice.edu> > Signed-off-by: Mark Wielaard <mark@klomp.org> > --- > libelf/elf_readall.c | 5 ++--- > 1 file changed, 2 insertions(+), 3 deletions(-) > > diff --git a/libelf/elf_readall.c b/libelf/elf_readall.c > index d0f9a28c..2d62d447 100644 > --- a/libelf/elf_readall.c > +++ b/libelf/elf_readall.c > @@ -84,6 +84,7 @@ __libelf_readall (Elf *elf) > > /* If this is an archive and we have derived descriptors get the > locks for all of them. */ > + rwlock_unlock(elf->lock); // lock will be reacquired next line > libelf_acquire_all (elf); > > if (elf->maximum_size == ~((size_t) 0)) > @@ -141,10 +142,8 @@ __libelf_readall (Elf *elf) > __libelf_seterrno (ELF_E_NOMEM); > > /* Free the locks on the children. */ > - libelf_release_all (elf); > + libelf_release_all (elf); // lock is released > } > > - rwlock_unlock (elf->lock); > - > return (char *) elf->map_address; > } I think this is wrong when this if statement, at the start of the block, fails: /* If the file is not mmap'ed and not previously loaded, do it now. */ if (elf->map_address == NULL) So if elf->map_address != NULL we now never call rwlock_unlock (elf->lock). One way to simplify this locking might be to rewrite libelf_acquire_all and libelf_release_all to libelf_acquire_all_children and libelf_release_all_children (which would only be called with the elf- >lock already acquired). __libelf_readall is the only caller of these functions. Cheers, Mark
You are right that if elf->map_address != NULL then the acquired wrlock is not unlocked. The rwlock_unlock that was there initially was removed due to deadlocking when returning from inside the if statement, but this was not correct. However, adding ‘else rwlock_unlock (elf->lock)’ at the end of the if statement fixes this issue. I rewrote libelf_acquire_all and libelf_release_all as per your suggestion. Now, libelf_acquire_all_children does not acquire the lock again for the current elf object, but it does acquire locks for all children. Similarly, libelf_release_all_children releases the locks for all children under the acquired elf->lock. In libelf_readall, the elf->lock for the current elf object is released after the call to libelf_release_all_children before returning from the function. All tests are still passing after I made these changes. I will push the changes after I am done testing other fixes since I want to ensure that everything works together cohesively. On Tue, Oct 10, 2023 at 10:06 AM Mark Wielaard <mark@klomp.org> wrote: > Hi Heather, > > On Tue, 2023-10-10 at 15:42 +0200, Mark Wielaard wrote: > > From: Heather McIntyre <hsm2@rice.edu> > > > > * libelf/elf_readall.c (__libelf_readall): Move rwlock_unlock > > before libelf_acquire_all. > > > > Signed-off-by: Heather S. McIntyre <hsm2@rice.edu> > > Signed-off-by: Mark Wielaard <mark@klomp.org> > > --- > > libelf/elf_readall.c | 5 ++--- > > 1 file changed, 2 insertions(+), 3 deletions(-) > > > > diff --git a/libelf/elf_readall.c b/libelf/elf_readall.c > > index d0f9a28c..2d62d447 100644 > > --- a/libelf/elf_readall.c > > +++ b/libelf/elf_readall.c > > @@ -84,6 +84,7 @@ __libelf_readall (Elf *elf) > > > > /* If this is an archive and we have derived descriptors get the > > locks for all of them. */ > > + rwlock_unlock(elf->lock); // lock will be reacquired next line > > libelf_acquire_all (elf); > > > > if (elf->maximum_size == ~((size_t) 0)) > > @@ -141,10 +142,8 @@ __libelf_readall (Elf *elf) > > __libelf_seterrno (ELF_E_NOMEM); > > > > /* Free the locks on the children. */ > > - libelf_release_all (elf); > > + libelf_release_all (elf); // lock is released > > } > > > > - rwlock_unlock (elf->lock); > > - > > return (char *) elf->map_address; > > } > > I think this is wrong when this if statement, at the start of the > block, fails: > > /* If the file is not mmap'ed and not previously loaded, do it now. */ > if (elf->map_address == NULL) > > So if elf->map_address != NULL we now never call > rwlock_unlock (elf->lock). > > One way to simplify this locking might be to rewrite libelf_acquire_all > and libelf_release_all to libelf_acquire_all_children and > libelf_release_all_children (which would only be called with the elf- > >lock already acquired). > > __libelf_readall is the only caller of these functions. > > Cheers, > > Mark >
Hi Heather, On Tue, 2023-10-17 at 14:11 -0500, Heather McIntyre wrote: > I will push the changes after I am done testing other fixes > since I want to ensure that everything works together cohesively. Please let us know if we can help update your patches. I realize we have been patching some of the code you are also working on. So if things don't apply anymore and you need help to figure out how to adjust your patches please just ask. Also please don't feel everything needs to be perfect and work together completely. If you have parts ready that are independently useful please just submit those parts and we can integrate them early. Thanks, Mark
diff --git a/libelf/elf_readall.c b/libelf/elf_readall.c index d0f9a28c..2d62d447 100644 --- a/libelf/elf_readall.c +++ b/libelf/elf_readall.c @@ -84,6 +84,7 @@ __libelf_readall (Elf *elf) /* If this is an archive and we have derived descriptors get the locks for all of them. */ + rwlock_unlock(elf->lock); // lock will be reacquired next line libelf_acquire_all (elf); if (elf->maximum_size == ~((size_t) 0)) @@ -141,10 +142,8 @@ __libelf_readall (Elf *elf) __libelf_seterrno (ELF_E_NOMEM); /* Free the locks on the children. */ - libelf_release_all (elf); + libelf_release_all (elf); // lock is released } - rwlock_unlock (elf->lock); - return (char *) elf->map_address; }