From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 68A4B395BC55 for ; Fri, 27 May 2022 11:04:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 68A4B395BC55 Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-440-zTBPFSQFNNe3BsQOB9DmAA-1; Fri, 27 May 2022 07:03:52 -0400 X-MC-Unique: zTBPFSQFNNe3BsQOB9DmAA-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id ABD0A1C05AE7; Fri, 27 May 2022 11:03:51 +0000 (UTC) Received: from oldenburg.str.redhat.com (unknown [10.39.192.71]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D2B341121315; Fri, 27 May 2022 11:03:50 +0000 (UTC) From: Florian Weimer To: Fangrui Song Cc: libc-alpha@sourceware.org Subject: Re: [PATCH] dlsym: Make RTLD_NEXT prefer default version definition [#BZ #14932] References: <20220520083507.2368165-1-maskray@google.com> Date: Fri, 27 May 2022 13:03:48 +0200 In-Reply-To: <20220520083507.2368165-1-maskray@google.com> (Fangrui Song's message of "Fri, 20 May 2022 01:35:07 -0700") Message-ID: <87k0a7fd9n.fsf@oldenburg.str.redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain X-Spam-Status: No, score=-11.4 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_NONE, 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: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 27 May 2022 11:04:09 -0000 I've been looking at this for a while. We currently have this code in elf/dl-lookup.c: /* No specific version is selected. There are two ways we can got here: - a binary which does not include versioning information is loaded - dlsym() instead of dlvsym() is used to get a symbol which might exist in more than one form If the library does not provide symbol version information there is no problem at all: we simply use the symbol if it is defined. These two lookups need to be handled differently if the library defines versions. In the case of the old unversioned application the oldest (default) version should be used. In case of a dlsym() call the latest and public interface should be returned. */ if (verstab != NULL) { if ((verstab[symidx] & 0x7fff) >= ((flags & DL_LOOKUP_RETURN_NEWEST) ? 2 : 3)) { /* Don't accept hidden symbols. */ if ((verstab[symidx] & 0x8000) == 0 && (*num_versions)++ == 0) /* No version so far. */ *versioned_sym = sym; return NULL; } } The numbers 2 and 3 look suspicious. The condition involving num_versions ensures that we only store the first matching symbol in *versioned_sym. But the skipped version indices are not special. Indices are not specific to individual symbols, so it is no clear that index 2 is special and contains the oldest possible version for that particular symbol, and the next index will have the latest version. Aligning dlvsym with dlsym still makes sense, so I suggest to proceed with this patch. But I think there are more bugs in this area. > diff --git a/elf/nextmod3.c b/elf/nextmod3.c > new file mode 100644 > index 0000000000..96608a65c0 > --- /dev/null > +++ b/elf/nextmod3.c > @@ -0,0 +1,19 @@ > +int > +foo_v1 (int a) > +{ > + return 1; > +} > +asm (".symver foo_v1, foo@v1"); > + > +int > +foo_v2 (int a) > +{ > + return 2; > +} > +asm (".symver foo_v2, foo@v2"); > + > +int > +foo (int a) > +{ > + return 3; > +} Please set foo@@v3 explicitly. > diff --git a/elf/nextmod3.map b/elf/nextmod3.map > new file mode 100644 > index 0000000000..0a8e4e4ee3 > --- /dev/null > +++ b/elf/nextmod3.map > @@ -0,0 +1,3 @@ > +v1 { }; > +v2 { }; > +v3 { foo; }; These versions are not ordered. Maybe use this instead? v1 { }; v2 { } v1; v3 { foo; } v2; Thanks, Florian