public inbox for libc-help@sourceware.org
 help / color / mirror / Atom feed
From: "Wendeborn, Jonathan" <Jonathan.Wendeborn@bruker.com>
To: "libc-help@sourceware.org" <libc-help@sourceware.org>
Subject: dlopen: Segfault due to overwriting .so file after it was loaded and loading it again
Date: Fri, 20 Nov 2020 06:52:35 +0000	[thread overview]
Message-ID: <11e3703d900d48149d0f81ae7682480f@bruexc101.brumgt.local> (raw)

Hi,

I am a C++ developer but usually programming and debugging on Windows (so please excuse any wrong terms). Now I'm compiling my program on Linux (gcc 9.3.0 on Debian Bullseye with Boost 1.70) for the first time and get a Segfault in my unit tests.
Luckily I was able to write a reproducer and boil it down to my code overwriting the .so file after having it loaded (and unloaded):

#include <boost/filesystem/operations.hpp>
#include <boost/dll/shared_library.hpp>
#include <iostream>

void doit() {
    boost::filesystem::copy_file("~/project/target/references/bin/libSomething.so", "~/project/build/bin/ linux-x86_64-gcc9-debug/ libSomething.so", boost::filesystem::copy_option::overwrite_if_exists);

    boost::dll::shared_library l;
    std::cout << "pre load" << std::endl;
    l.load("./libSomething.so");
    std::cout << "loaded" << std::endl;
}
int main() {
    doit();
    doit();
    return 0;
}

Output :


The destructor ~shared_library() calls dlclose(), but I suspect the library stays loaded. Overwriting the file creates a new file node and my program wants to load the same library again (at the same location but with a different file node/handle).
This works on Windows because the library is really unloaded after ~shared_library() (otherwise copy_file() would fail as Windows does not support overwriting files in use anyway).

I did debug into dlopen() and think the error gets visible in dl_lookup_x(): In there the strtab and symtab pointers don't have valid pointers the second time, i.e. they have the quite small value from the beginning of elf_get_dynamic_info() (l.51), the l_addr offset from the second part of elf_get_dynamic_info() wasn't added (l.104).
Sure I'm going to rewrite my tests (I'm going to not copy the files at all anymore) but I thought this could be of interest for you.

Best regards,
Jonathan


             reply	other threads:[~2020-11-20  6:52 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-20  6:52 Wendeborn, Jonathan [this message]
2020-11-20  7:17 ` Konstantin Kharlamov
2020-11-20  8:01   ` AW: " Wendeborn, Jonathan
2020-11-20  8:15     ` Konstantin Kharlamov
2020-11-20  9:47       ` AW: " Wendeborn, Jonathan
2020-11-20 10:20         ` Konstantin Kharlamov
2020-11-20 11:33 ` Florian Weimer
2020-11-20 12:45   ` AW: " Wendeborn, Jonathan
2020-11-20 12:48     ` Florian Weimer
2020-11-20 12:59       ` AW: " Wendeborn, Jonathan
2020-12-04 10:39 Wendeborn, Jonathan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=11e3703d900d48149d0f81ae7682480f@bruexc101.brumgt.local \
    --to=jonathan.wendeborn@bruker.com \
    --cc=libc-help@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).