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 [216.205.24.124]) by sourceware.org (Postfix) with ESMTP id 064EF385803F for ; Tue, 22 Jun 2021 08:16:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 064EF385803F Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-453-CtiZTSrnNHyy2rBaNTJpTQ-1; Tue, 22 Jun 2021 04:16:02 -0400 X-MC-Unique: CtiZTSrnNHyy2rBaNTJpTQ-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 1182A8030D6; Tue, 22 Jun 2021 08:16:01 +0000 (UTC) Received: from oldenburg.str.redhat.com (ovpn-112-211.ams2.redhat.com [10.36.112.211]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B77E75C1D1; Tue, 22 Jun 2021 08:15:57 +0000 (UTC) From: Florian Weimer To: John Mellor-Crummey Cc: Adhemerval Zanella , libc-alpha@sourceware.org, woodard@redhat.com Subject: Re: A collection of LD_AUDIT bugs that are important for tools (with better formatting for this list) References: <8A8FF420-8316-4A22-AC4D-DA1F2D5625A5@rice.edu> <2fc830b9-35da-9b94-369f-4df683078a5c@linaro.org> <8735tguubc.fsf@oldenburg.str.redhat.com> <5F849F6D-0BB7-4D6F-9FC8-9F73A4E012F3@rice.edu> Date: Tue, 22 Jun 2021 10:15:55 +0200 In-Reply-To: <5F849F6D-0BB7-4D6F-9FC8-9F73A4E012F3@rice.edu> (John Mellor-Crummey's message of "Mon, 21 Jun 2021 14:42:17 -0500") Message-ID: <87tulqe2mc.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.79 on 10.5.11.16 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-5.9 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, KAM_SHORT, KAM_STOCKGEN, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=no autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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: Tue, 22 Jun 2021 08:16:09 -0000 * John Mellor-Crummey: > On Jun 17, 2021, at 3:09 PM, Florian Weimer wrote: > >> The issue is that the la_symbind interface is not very good at >> communicating that PLT enter/exit hooks aren't available under these >> circumstances. =20 > > This is a separate issue from the one we reported. The issue we reported > was that la_symbind wasn=E2=80=99t called and LD_BIND_NOW was not used. It's kind of related. Our own example implementation looks like this: uintptr_t la_symbind (Elf_Sym *sym, unsigned int ndx, uintptr_t *refcook, =09 uintptr_t *defcook, unsigned int *flags, const char *symname) { if (!do_exit) *flags =3D LA_SYMB_NOPLTEXIT; return sym->st_value; } Let's assume that we start calling la_symbind in places where there is no support for enter/exit hooks. We could initialize *flags with LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT, but the code above would clear the LA_SYMB_NOPLTENTER flag in !do_exit mode. I want to increase LAV_CURRENT to 2 and call la_symbind in the BIND_NOW cases only if la_version returned a value greater than 1. This way, old audit modules (which are supposed to return LAV_CURRENT from in la_version) will continue to work because they do not see any unexpected la_symbind calls. Once we call la_symbind in contexts where no enter/exit hooks are available, we should initialize the flags to LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT (so that la_symbind can detect the situation), and report a dlopen/loader error if those flags are cleared by la_symbind. (With our example code, this would call pretty much all binding to fail, which is why I think we need the LAV_CURRENT change.) >> pthread_create interception becomes more difficult in glibc 2.34 because >> the pthread_create symbol is no longer interposable. > > I don=E2=80=99t understand why pthread_create will no longer be interposa= ble in 2.34. > We have a set of other functions that we also need to intercept, shown be= low: > > _Exit > _exit > execl > execle > execlp > execv > execve > execvp > exit > fork > pthread_create > pthread_exit > pthread_sigmask > sigaction > signal > sigprocmask > sigtimedwait > sigwait > sigwaitinfo > system > vfork > > If by "pthread_create symbol is no longer interposable", that means we > can=E2=80=99t insert a wrapper, then that is very bad for performance too= ls. Once we merge librt and libanl into libc (patches for that have been posted), mq_notify, the timer functions, and getaddrinfo_a will call pthread_create using a direct call that cannot be intercepted in this way. There is precedent for making things interposable/interceptable in the form of malloc but we are currently do not plan to do this for pthread_create. It would not be an ABI change as such, so we could introduce the indirect call as a later change based on user feedback. You can already see this non-interceptable thread creation behavior today (in glibc 2.33 and earlier) with thrd_create, which does not result in a pthread_create call, either, despite creating a new thread as if by pthread_create. It's also the reason why your list contains the exec* functions and system in addition to fork, vfork, and execve, even though system is implemented on top of those functions: the internal direct calls are invisible to auditors. But posix_spawn, posix_spawnp, popen are missing, too, so you will not trace all created processes. Starting with glibc 2.32, thread signal masks can also be manipulated using pthread_attr_setsigmask_np, and that might go unnoticed with your present sets of intercepts (although the mask change would be visible from a thread start routine wrapper injected via pthread_create). Going back to trheading, I find it a bit curious that you intercept pthread_create, but not pthread_join. How do you detect thread exit? I assume you are interested in that event, too. Merely wrapping the thread start routine is insufficient because there are other ways for a thread to exit besides returning from the start routine and calling pthread_exit (e.g., thread cancellation and unwinding). > Should we expect any problems for the other functions listed above in > addition to pthread_create? I don't think glibc 2.34 will bring any new problems in this area, but there are some pre-existing issues around posix_spawn, popen, pthread_attr_setsigmask_np. Thanks, Florian