From owner-freebsd-hackers@FreeBSD.ORG Fri Aug 24 16:23:52 2012 Return-Path: Delivered-To: hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 682EC1065670 for ; Fri, 24 Aug 2012 16:23:52 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from mail.zoral.com.ua (mx0.zoral.com.ua [91.193.166.200]) by mx1.freebsd.org (Postfix) with ESMTP id A72A38FC14 for ; Fri, 24 Aug 2012 16:23:50 +0000 (UTC) Received: from skuns.kiev.zoral.com.ua (localhost [127.0.0.1]) by mail.zoral.com.ua (8.14.2/8.14.2) with ESMTP id q7OGNoFS095292; Fri, 24 Aug 2012 19:23:50 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: from deviant.kiev.zoral.com.ua (kostik@localhost [127.0.0.1]) by deviant.kiev.zoral.com.ua (8.14.5/8.14.5) with ESMTP id q7OGNcx2024683; Fri, 24 Aug 2012 19:23:38 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: (from kostik@localhost) by deviant.kiev.zoral.com.ua (8.14.5/8.14.5/Submit) id q7OGNc1D024682; Fri, 24 Aug 2012 19:23:38 +0300 (EEST) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: deviant.kiev.zoral.com.ua: kostik set sender to kostikbel@gmail.com using -f Date: Fri, 24 Aug 2012 19:23:38 +0300 From: Konstantin Belousov To: John Hein Message-ID: <20120824162338.GV33100@deviant.kiev.zoral.com.ua> References: <20535.39682.330250.337503@gromit.timing.com> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="g++0NlQhRgFs6nMu" Content-Disposition: inline In-Reply-To: <20535.39682.330250.337503@gromit.timing.com> User-Agent: Mutt/1.4.2.3i X-Virus-Scanned: clamav-milter 0.95.2 at skuns.kiev.zoral.com.ua X-Virus-Status: Clean X-Spam-Status: No, score=-4.0 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00 autolearn=ham version=3.2.5 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on skuns.kiev.zoral.com.ua Cc: hackers@freebsd.org Subject: Re: LD_PRELOADed code before or after exec - different behavior after 6.x X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 24 Aug 2012 16:23:52 -0000 --g++0NlQhRgFs6nMu Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Fri, Aug 24, 2012 at 09:17:22AM -0600, John Hein wrote: >=20 > head sl.cc pe.c > =3D=3D> sl.cc <=3D=3D > #include > #include > class C > { > public: > C(){ > printf("C\n"); > unsetenv("XXX"); > } > }; > static C c; >=20 > =3D=3D> pe.c <=3D=3D > #include > #include > int > main() > { > char *p=3Dgetenv("XXX"); > if (p !=3D NULL) > printf("XXX=3D%s\n",p); > return 0; > } >=20 >=20 > % g++ -fpic -shared sl.cc -o sl.so > % gcc pe.c -o pe >=20 > 7.x & 8.x ... > % sh -c 'XXX=3D1 LD_PRELOAD=3D$(pwd)/sl.so pe' > C > XXX=3D1 >=20 > 6.x & 4.x ... > % sh -c 'XXX=3D1 LD_PRELOAD=3D$(pwd)/sl.so pe' > C >=20 >=20 > In 6.x and earlier (fedora 16, too), the unsetenv clears the XXX env > var apparently in time to affect the exec'd process. In 8.x & 9.x, it > seems the environment is set and passed to the exec'd process and the > LD_PRELOADed code does not affect that despite its best efforts. >=20 > It seems to me that 6.x behavior is more correct, but I'm seeking > opinions before contemplating if / how to put together a fix. >=20 I suppose that this is a fallback from the POSIXification of putenv(). The libc image of the environment block is now referenced through the environ var. Since csu always reinitialize the environ, effect of the changes made by preloaded dso is cleared. At the end of the message is the patch for HEAD which seems to fix the issue. It is not applicable to stable/9 or 8. You could try to change lib/csu//crt1.c to replace unconditional environ =3D env; assignment with if (environ =3D=3D NULL) environ =3D env; =2E Unfortunately, because csu is linked to the binary, you have to relink the binary after applying the patch and rebuilding the world. In other words, old binaries cannot be fixed. Committing this requires secteam@ review, AFAIR. diff --git a/lib/csu/amd64/crt1.c b/lib/csu/amd64/crt1.c index f33aad6..3740e73 100644 --- a/lib/csu/amd64/crt1.c +++ b/lib/csu/amd64/crt1.c @@ -61,9 +61,7 @@ _start(char **ap, void (*cleanup)(void)) argc =3D *(long *)(void *)ap; argv =3D ap + 1; env =3D ap + 2 + argc; - environ =3D env; - if (argc > 0 && argv[0] !=3D NULL) - handle_progname(argv[0]); + handle_argv(argc, argv, env); =20 if (&_DYNAMIC !=3D NULL) atexit(cleanup); diff --git a/lib/csu/arm/crt1.c b/lib/csu/arm/crt1.c index 127c28d..e3529b8 100644 --- a/lib/csu/arm/crt1.c +++ b/lib/csu/arm/crt1.c @@ -98,10 +98,7 @@ __start(int argc, char **argv, char **env, struct ps_str= ings *ps_strings, const struct Struct_Obj_Entry *obj __unused, void (*cleanup)(void)) { =20 - environ =3D env; - - if (argc > 0 && argv[0] !=3D NULL) - handle_progname(argv[0]); + handle_argv(argc, argv, env); =20 if (ps_strings !=3D (struct ps_strings *)0) __ps_strings =3D ps_strings; diff --git a/lib/csu/common/ignore_init.c b/lib/csu/common/ignore_init.c index e3d2441..89b3734 100644 --- a/lib/csu/common/ignore_init.c +++ b/lib/csu/common/ignore_init.c @@ -87,14 +87,18 @@ handle_static_init(int argc, char **argv, char **env) } =20 static inline void -handle_progname(const char *v) +handle_argv(int argc, char *argv[], char **env) { const char *s; =20 - __progname =3D v; - for (s =3D __progname; *s !=3D '\0'; s++) { - if (*s =3D=3D '/') - __progname =3D s + 1; + if (environ =3D=3D NULL) + environ =3D env; + if (argc > 0 && argv[0] !=3D NULL) { + __progname =3D argv[0]; + for (s =3D __progname; *s !=3D '\0'; s++) { + if (*s =3D=3D '/') + __progname =3D s + 1; + } } } =20 diff --git a/lib/csu/i386-elf/crt1_c.c b/lib/csu/i386-elf/crt1_c.c index 3249069..65de04c 100644 --- a/lib/csu/i386-elf/crt1_c.c +++ b/lib/csu/i386-elf/crt1_c.c @@ -61,10 +61,7 @@ _start1(fptr cleanup, int argc, char *argv[]) char **env; =20 env =3D argv + argc + 1; - environ =3D env; - if (argc > 0 && argv[0] !=3D NULL) - handle_progname(argv[0]); - + handle_argv(argc, argv, env); if (&_DYNAMIC !=3D NULL) atexit(cleanup); else diff --git a/lib/csu/mips/crt1.c b/lib/csu/mips/crt1.c index 1968f06..95348b7 100644 --- a/lib/csu/mips/crt1.c +++ b/lib/csu/mips/crt1.c @@ -71,9 +71,7 @@ __start(char **ap, argc =3D * (long *) ap; argv =3D ap + 1; env =3D ap + 2 + argc; - environ =3D env; - if (argc > 0 && argv[0] !=3D NULL) - handle_progname(argv[0]); + handle_argv(argc, argv, env); =20 if (&_DYNAMIC !=3D NULL) atexit(cleanup); diff --git a/lib/csu/powerpc/crt1.c b/lib/csu/powerpc/crt1.c index c3be90d..d1a3ea0 100644 --- a/lib/csu/powerpc/crt1.c +++ b/lib/csu/powerpc/crt1.c @@ -81,10 +81,8 @@ _start(int argc, char **argv, char **env, struct ps_strings *ps_strings) { =20 - environ =3D env; =20 - if (argc > 0 && argv[0] !=3D NULL) - handle_progname(argv[0]); + handle_argv(argc, argv, env); =20 if (ps_strings !=3D (struct ps_strings *)0) __ps_strings =3D ps_strings; diff --git a/lib/csu/powerpc64/crt1.c b/lib/csu/powerpc64/crt1.c index a7c3581..35c5a6e 100644 --- a/lib/csu/powerpc64/crt1.c +++ b/lib/csu/powerpc64/crt1.c @@ -81,10 +81,7 @@ _start(int argc, char **argv, char **env, struct ps_strings *ps_strings) { =20 - environ =3D env; - - if (argc > 0 && argv[0] !=3D NULL) - handle_progname(argv[0]); + handle_argv(argc, argv, env); =20 if (ps_strings !=3D (struct ps_strings *)0) __ps_strings =3D ps_strings; diff --git a/lib/csu/sparc64/crt1.c b/lib/csu/sparc64/crt1.c index 3b3ecc2..e11ae39 100644 --- a/lib/csu/sparc64/crt1.c +++ b/lib/csu/sparc64/crt1.c @@ -85,9 +85,7 @@ _start(char **ap, void (*cleanup)(void), struct Struct_Ob= j_Entry *obj __unused, argc =3D *(long *)(void *)ap; argv =3D ap + 1; env =3D ap + 2 + argc; - environ =3D env; - if (argc > 0 && argv[0] !=3D NULL) - handle_progname(argv[0]); + handle_argv(argc, argv, env); =20 if (&_DYNAMIC !=3D NULL) atexit(cleanup); --g++0NlQhRgFs6nMu Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (FreeBSD) iEYEARECAAYFAlA3qokACgkQC3+MBN1Mb4jvugCg8+h+yBeBn1WMoX+ROt3xMnrj mw4AoJKR5l7q1Po2kYbjZTlKycHKd7Pn =XOqT -----END PGP SIGNATURE----- --g++0NlQhRgFs6nMu--