From owner-svn-src-head@freebsd.org Tue Sep 3 14:06:53 2019 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id E680ADD0D6; Tue, 3 Sep 2019 14:06:52 +0000 (UTC) (envelope-from yuripv@freebsd.org) Received: from freefall.freebsd.org (freefall.freebsd.org [96.47.72.132]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "freefall.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 46N7zw1xPYz4Q08; Tue, 3 Sep 2019 14:06:52 +0000 (UTC) (envelope-from yuripv@freebsd.org) Received: by freefall.freebsd.org (Postfix, from userid 1452) id 945231ACAF; Tue, 3 Sep 2019 14:06:19 +0000 (UTC) X-Original-To: yuripv@localmail.freebsd.org Delivered-To: yuripv@localmail.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [96.47.72.80]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (Client CN "mx1.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by freefall.freebsd.org (Postfix) with ESMTPS id 00F3464CD; Mon, 15 Apr 2019 13:03:14 +0000 (UTC) (envelope-from owner-src-committers@freebsd.org) Received: from freefall.freebsd.org (freefall.freebsd.org [96.47.72.132]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "freefall.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 60D09804F4; Mon, 15 Apr 2019 13:03:14 +0000 (UTC) (envelope-from owner-src-committers@freebsd.org) Received: by freefall.freebsd.org (Postfix, from userid 538) id 251876463; Mon, 15 Apr 2019 13:03:14 +0000 (UTC) Delivered-To: src-committers@localmail.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [96.47.72.80]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (Client CN "mx1.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by freefall.freebsd.org (Postfix) with ESMTPS id 6B6786461 for ; Mon, 15 Apr 2019 13:03:11 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 14BF4804EE; Mon, 15 Apr 2019 13:03:11 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id DCB448626; Mon, 15 Apr 2019 13:03:10 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x3FD3A5U031076; Mon, 15 Apr 2019 13:03:10 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x3FD3As2031072; Mon, 15 Apr 2019 13:03:10 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201904151303.x3FD3As2031072@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r346225 - in head: lib/libc/stdlib libexec/rtld-elf X-SVN-Group: head X-SVN-Commit-Author: kib X-SVN-Commit-Paths: in head: lib/libc/stdlib libexec/rtld-elf X-SVN-Commit-Revision: 346225 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk X-Loop: FreeBSD.org Sender: owner-src-committers@freebsd.org X-Rspamd-Queue-Id: 60D09804F4 X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.97 / 15.00]; local_wl_from(0.00)[freebsd.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.999,0]; NEURAL_HAM_SHORT(-0.97)[-0.970,0]; ASN(0.00)[asn:11403, ipnet:96.47.64.0/20, country:US]; NEURAL_HAM_LONG(-1.00)[-1.000,0] Status: O X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Date: Tue, 03 Sep 2019 14:06:54 -0000 X-Original-Date: Mon, 15 Apr 2019 13:03:10 +0000 (UTC) X-List-Received-Date: Tue, 03 Sep 2019 14:06:54 -0000 Author: kib Date: Mon Apr 15 13:03:09 2019 New Revision: 346225 URL: https://svnweb.freebsd.org/changeset/base/346225 Log: Fix order of destructors between main binary and libraries. Since inits for the main binary are run from rtld (for some time), the rtld_exit atexit(3) handler, which is passed from rtld to the program entry and installed by csu, is installed after any atexit(3) handlers installed by main binary constructors. This means that rtld_exit() is fired before main binary handlers. Typical C++ static constructors are executed from init (either binary or libs) but use atexit(3) to ensure that destructors are called in the right order, independent of the linking order. Also, C++ libraries finalizers call __cxa_finalize(3) to flush library' atexit(3) entries. Since atexit(3) entry is cleared after being run, this would be mostly innocent, except that, atexit(rtld_exit) done after main binary constructors, makes destructors from libraries executed before destructors for main. Fix by reordering atexit(rtld_exit) before inits for main binary, same as it happened when inits were called by csu. Do it using new private libc symbol with pre-defined ABI. Reported. tested, and reviewed by: kan Sponsored by: The FreeBSD Foundation MFC after: 1 week Modified: head/lib/libc/stdlib/Symbol.map head/lib/libc/stdlib/atexit.c head/libexec/rtld-elf/rtld.c Modified: head/lib/libc/stdlib/Symbol.map ============================================================================== --- head/lib/libc/stdlib/Symbol.map Mon Apr 15 12:24:19 2019 (r346224) +++ head/lib/libc/stdlib/Symbol.map Mon Apr 15 13:03:09 2019 (r346225) @@ -129,4 +129,5 @@ FBSDprivate_1.0 { _system; __libc_system; __cxa_thread_call_dtors; + __libc_atexit; }; Modified: head/lib/libc/stdlib/atexit.c ============================================================================== --- head/lib/libc/stdlib/atexit.c Mon Apr 15 12:24:19 2019 (r346224) +++ head/lib/libc/stdlib/atexit.c Mon Apr 15 13:03:09 2019 (r346225) @@ -142,6 +142,7 @@ atexit(void (*func)(void)) error = atexit_register(&fn); return (error); } +__weak_reference(atexit, __libc_atexit); /** * Register a block to be performed at exit. Modified: head/libexec/rtld-elf/rtld.c ============================================================================== --- head/libexec/rtld-elf/rtld.c Mon Apr 15 12:24:19 2019 (r346224) +++ head/libexec/rtld-elf/rtld.c Mon Apr 15 13:03:09 2019 (r346225) @@ -151,6 +151,7 @@ static int rtld_dirname(const char *, char *); static int rtld_dirname_abs(const char *, char *); static void *rtld_dlopen(const char *name, int fd, int mode); static void rtld_exit(void); +static void rtld_nop_exit(void); static char *search_library_path(const char *, const char *, const char *, int *); static char *search_library_pathfds(const char *, const char *, int *); @@ -295,6 +296,8 @@ const char *ld_path_rtld = _PATH_RTLD; const char *ld_standard_library_path = STANDARD_LIBRARY_PATH; const char *ld_env_prefix = LD_; +static void (*rtld_exit_ptr)(void); + /* * Fill in a DoneList with an allocation large enough to hold all of * the currently-loaded objects. Keep this as a macro since it calls @@ -756,6 +759,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entr *ld_bind_now != '\0', SYMLOOK_EARLY, &lockstate) == -1) rtld_die(); + rtld_exit_ptr = rtld_exit; if (obj_main->crt_no_init) preinit_main(); objlist_call_init(&initlist, &lockstate); @@ -778,7 +782,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entr dbg("transferring control to program entry point = %p", obj_main->entry); /* Return the exit procedure and the program entry point. */ - *exit_proc = rtld_exit; + *exit_proc = rtld_exit_ptr; *objp = obj_main; return (func_ptr_type) obj_main->entry; } @@ -2662,6 +2666,7 @@ objlist_call_init(Objlist *list, RtldLockState *lockst Obj_Entry *obj; char *saved_msg; Elf_Addr *init_addr; + void (*reg)(void (*)(void)); int index; /* @@ -2690,7 +2695,16 @@ objlist_call_init(Objlist *list, RtldLockState *lockst */ elm->obj->init_done = true; hold_object(elm->obj); + reg = NULL; + if (elm->obj == obj_main && obj_main->crt_no_init) { + reg = (void (*)(void (*)(void)))get_program_var_addr( + "__libc_atexit", lockstate); + } lock_release(rtld_bind_lock, lockstate); + if (reg != NULL) { + reg(rtld_exit); + rtld_exit_ptr = rtld_nop_exit; + } /* * It is legal to have both DT_INIT and DT_INIT_ARRAY defined. @@ -3002,6 +3016,11 @@ rtld_exit(void) if (!libmap_disable) lm_fini(); lock_release(rtld_bind_lock, &lockstate); +} + +static void +rtld_nop_exit(void) +{ } /*