changeset 11250:ea87f0d32643

6906238 s10brand: procs forked by native procs use S10 binaries and native libraries
author jv227347 <Jordan.Vaughan@Sun.com>
date Fri, 04 Dec 2009 09:32:33 -0800
parents 6c30f7dfc97b
children ff36d9f84a57
files usr/src/lib/brand/solaris10/s10_npreload/common/s10_npreload.c
diffstat 1 files changed, 44 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/lib/brand/solaris10/s10_npreload/common/s10_npreload.c	Fri Dec 04 09:22:59 2009 -0700
+++ b/usr/src/lib/brand/solaris10/s10_npreload/common/s10_npreload.c	Fri Dec 04 09:32:33 2009 -0800
@@ -27,23 +27,58 @@
 #pragma init(init)
 
 #include <s10_brand.h>
+#include <stdlib.h>
 #include <sys/syscall.h>
 
 /*
- * This is a library that is LD_PRELOADed into native binaries.
- * All it does is one brand operation.  B_S10_NATIVE.  This brand
- * operation checks that this is actually a native binary, and then
- * if so changes the executable name so that it is no longer ld.sol.1.
- * Instead it changes it to be the name of the real native executable
- * that we're runnning.  This allows things like pgrep to work as
- * expected.  Note, that this brand opration only changes the process
- * name wrt the kernel.  From the processes perspective, the first
+ * This is a library that is LD_PRELOADed into native processes.
+ * Its primary function is to perform one brand operation, B_S10_NATIVE,
+ * which checks that this is actually a native process.  If it is, then
+ * the operation changes the executable name so that it is no longer
+ * ld.sol.1.  Instead it changes it to be the name of the real native
+ * executable that we're runnning.  This allows things like pgrep to work
+ * as expected.  Note that this brand operation only changes the process
+ * name wrt the kernel.  From the process' perspective, the first
  * argument and AT_SUN_EXECNAME are still ld.so.1.
+ *
+ * The library also unsets the LD_LIBRARY_PATH_* and LD_PRELOAD_*
+ * environment variables created by the brand's native wrapper scripts
+ * (e.g., s10_isaexec_wrapper) in order to ensure that execve(2) and its
+ * ilk, which brand the calling process, do not cause ld.so.1 to link native
+ * libraries to the resulting process.  The native wrapper scripts make
+ * LD_LIBRARY_PATH_* point to library directories (e.g., /usr/lib) prefixed
+ * with "/.SUNWnative" in order to make native processes link with native
+ * libraries.  However, if a native process running within a branded zone
+ * executes exec(2), then the new process becomes branded.  Therefore, if this
+ * library were to not unset the LD_LIBRARY_PATH_* environment variables, then
+ * if a native process were to invoke an exec(2) function, then the resulting
+ * process would be branded and linked with native libraries.
+ * LD_PRELOAD_*, which the native wrapper scripts set to "s10_npreload.so.1"
+ * (the name of this library), must be cleared as well because
+ * s10_npreload.so.1 is only preloaded into native processes and can only be
+ * accessed via the /.SUNWnative library paths.
+ *
+ * NOTE: This trick won't work if another library that invokes an exec(2)
+ * function in its initialization function is initialized before this library.
+ * Such a problem won't happen if the brand only replaces binaries shipped with
+ * Solaris (e.g., ifconfig(1M)) with their native counterparts because most (if
+ * not all) Solaris system libraries don't exec(2) within their initialization
+ * functions.
  */
-
 void
 init(void)
 {
 	sysret_t rval;
+
 	(void) __systemcall(&rval, SYS_brand, B_S10_NATIVE);
+
+	/*
+	 * We can safely use unsetenv(3C) to clear LD_LIBRARY_PATH_* and
+	 * LD_PRELOAD_* because ld.so.1 caches their values before this
+	 * library is initialized.
+	 */
+	(void) unsetenv("LD_LIBRARY_PATH_32");
+	(void) unsetenv("LD_LIBRARY_PATH_64");
+	(void) unsetenv("LD_PRELOAD_32");
+	(void) unsetenv("LD_PRELOAD_64");
 }