Problem

..is known, let me summarize briefly.

Uninstalling packages providing libraries, without checking reverse runtime 
dependencies of those packages leaves their dependencies unsatisfied (packages 
with broken executables and/or shared libs).
Some package managers try their best not to remove said libraries, yet 
allowing packages to be removed.
Those orphaned libraries cause problems[1] as build systems of some other 
packages being (re)installed afterwards pick them up and abuse those orphaned 
libraries. (we don't like orphans abused, we prefer them... "gone").

Solution

Now, I suppose there are some ideas how to make orphaned libraries not go in a 
way. Basically then need to be available for system, but hidden for "emerge".

There is opt-out suggestion[2], unfortunately it does not provide any info how 
exactly it's supposed to be achieved. As far as portage/pkgcore is concerned, 
maybe - as Brian Harring suggested - sandbox could be used to somehow "hide" 
preserved libraries or preserved library directory from ebuild environment 
(preserved library directory a'ka "purgatory" - libs could be moved there when 
considered orphaned).

Opt-in suggestion is as follows:
1. Use some library path (read by ld loader from environment) and export it 
globally to environment pointing it to preserved library directory.
2. During "emerge", unset environment variable corresponding to said preserved 
library directory - orphans are no longer located.
Attached patch for glibc (2.11, but should apply to any other glibc around) 
and uClibc (this one is not tested but should work as well) that makes ld 
loader aware of LD_GENTOO_PRESERVED_LIBRARY_PATH variable.

(LD_LIBRARY_PATH would work as well, but it's being used widely so cannot be 
safely mangled.. on the second though it can - one could filter out preserved 
library paths from it during "emerge").

Thoughts?

1. https://bugs.gentoo.org/show_bug.cgi?id=240323
2. https://bugs.gentoo.org/show_bug.cgi?id=307391

-- 
regards
MM
diff -ru ../glibc-2.11/elf/rtld.c ./elf/rtld.c
--- ../glibc-2.11/elf/rtld.c	2009-10-30 18:17:08.000000000 +0100
+++ ./elf/rtld.c	2010-04-03 10:51:46.468906521 +0200
@@ -874,6 +874,8 @@
 
 /* The library search path.  */
 static const char *library_path attribute_relro;
+/* Gentoo preserved library path.  */
+static const char *preserved_library_path attribute_relro;
 /* The list preloaded objects.  */
 static const char *preloadlist attribute_relro;
 /* Nonzero if information about versions has to be printed.  */
@@ -1385,7 +1387,18 @@
 
   /* Initialize the data structures for the search paths for shared
      objects.  */
-  _dl_init_paths (library_path);
+  char *llp = alloca ((library_path != NULL ? strlen (library_path) : 0) +
+    (preserved_library_path != NULL ? strlen (preserved_library_path) : 0) + 2);
+  *llp = '\0';
+  if (library_path != NULL)
+    {
+      strcat (llp, library_path);
+      if (preserved_library_path != NULL)
+        strcat (llp, ":");
+    }
+  if (preserved_library_path != NULL)
+    strcat (llp, preserved_library_path);
+  _dl_init_paths (llp);
 
   /* Initialize _r_debug.  */
   struct r_debug *r = _dl_debug_initialize (GL(dl_rtld_map).l_addr,
@@ -2648,6 +2661,16 @@
 	    mode = trace;
 	  break;
 
+	case 29:
+	  /* Read Gentoo preserved library path from env here. Watch out for
+	     possible future 'case' additions in this switch as well as in
+	     EXTRA_LD_ENVVARS defined in sysdeps/<arch>/dl-librecon.h.
+	     LD_GENTOO_PRESERVED_LIBRARY_PATH is blacklisted for SUID
+	     programs in sysdeps/generic/unsecvars.h.  */
+	  if (memcmp (envline, "GENTOO_PRESERVED_LIBRARY_PATH", 29) == 0)
+	    preserved_library_path = &envline[30];
+	  break;
+
 	  /* We might have some extra environment variable to handle.  This
 	     is tricky due to the pre-processing of the length of the name
 	     in the switch statement here.  The code here assumes that added
diff -ru ../glibc-2.11/sysdeps/generic/unsecvars.h ./sysdeps/generic/unsecvars.h
--- ../glibc-2.11/sysdeps/generic/unsecvars.h	2009-10-30 18:17:08.000000000 +0100
+++ ./sysdeps/generic/unsecvars.h	2010-04-03 10:48:07.192280437 +0200
@@ -10,6 +10,7 @@
   "LD_DEBUG_OUTPUT\0"							      \
   "LD_DYNAMIC_WEAK\0"							      \
   "LD_LIBRARY_PATH\0"							      \
+  "LD_GENTOO_PRESERVED_LIBRARY_PATH\0"					      \
   "LD_ORIGIN_PATH\0"							      \
   "LD_PRELOAD\0"							      \
   "LD_PROFILE\0"							      \
diff -ru ../uClibc-0.9.30.1/ldso/include/dl-hash.h ./ldso/include/dl-hash.h
--- ../uClibc-0.9.30.1/ldso/include/dl-hash.h	2008-11-03 16:41:17.000000000 +0100
+++ ./ldso/include/dl-hash.h	2010-04-03 11:23:44.026291507 +0200
@@ -132,6 +132,7 @@
 extern int _dl_linux_dynamic_link(void);
 
 extern char * _dl_library_path;
+extern char * preserved_library_path;
 extern char * _dl_not_lazy;
 
 static __inline__ int _dl_symbol(char * name)
diff -ru ../uClibc-0.9.30.1/ldso/include/ldso.h ./ldso/include/ldso.h
--- ../uClibc-0.9.30.1/ldso/include/ldso.h	2008-05-30 16:35:31.000000000 +0200
+++ ./ldso/include/ldso.h	2010-04-03 11:24:24.256679689 +0200
@@ -47,6 +47,7 @@
 
 /* Global variables used within the shared library loader */
 extern char *_dl_library_path;         /* Where we look for libraries */
+extern char *preserved_library_path;   /* Gentoo preserved library path */
 extern char *_dl_preload;              /* Things to be loaded before the libs */
 extern char *_dl_ldsopath;             /* Where the shared lib loader was found */
 extern const char *_dl_progname;       /* The name of the executable being run */
diff -ru ../uClibc-0.9.30.1/ldso/include/unsecvars.h ./ldso/include/unsecvars.h
--- ../uClibc-0.9.30.1/ldso/include/unsecvars.h	2008-01-09 07:59:58.000000000 +0100
+++ ./ldso/include/unsecvars.h	2010-04-03 11:29:03.513616705 +0200
@@ -14,6 +14,7 @@
 #define UNSECURE_ENVVARS \
 	"LD_PRELOAD\0" \
 	"LD_LIBRARY_PATH\0" \
+	"LD_GENTOO_PRESERVED_LIBRARY_PATH\0" \
 	"LD_DEBUG\0" \
 	"LD_DEBUG_OUTPUT\0" \
 	"LD_TRACE_LOADED_OBJECTS\0" \
diff -ru ../uClibc-0.9.30.1/ldso/ldso/dl-elf.c ./ldso/ldso/dl-elf.c
--- ../uClibc-0.9.30.1/ldso/ldso/dl-elf.c	2008-11-18 15:01:35.000000000 +0100
+++ ./ldso/ldso/dl-elf.c	2010-04-03 11:32:37.518900167 +0200
@@ -244,6 +244,12 @@
 			return tpnt1;
 		}
 	}
+	/* Lookup Gentoo preserved library path */
+	if (preserved_library_path) {
+		_dl_if_debug_dprint("\tsearching LD_GENTOO_PRESERVED_LIBRARY_PATH='%s'\n", preserved_library_path);
+		if ((tpnt1 = search_for_named_library(libname, secure, preserved_library_path, rpnt)) != NULL)
+			return tpnt1;
+	}
 
 	/*
 	 * The ABI specifies that RUNPATH is searched after LD_LIBRARY_PATH.
diff -ru ../uClibc-0.9.30.1/ldso/ldso/ldso.c ./ldso/ldso/ldso.c
--- ../uClibc-0.9.30.1/ldso/ldso/ldso.c	2009-02-23 09:38:23.000000000 +0100
+++ ./ldso/ldso/ldso.c	2010-04-03 11:34:00.513996158 +0200
@@ -43,6 +43,7 @@
 
 /* Global variables used within the shared library loader */
 char *_dl_library_path         = 0;	/* Where we look for libraries */
+char *preserved_library_path   = 0;	/* Gentoo preserved library path */
 char *_dl_preload              = 0;	/* Things to be loaded before the libs */
 char *_dl_ldsopath             = 0;	/* Location of the shared lib loader */
 int _dl_secure                 = 1;	/* Are we dealing with setuid stuff? */
@@ -204,6 +205,7 @@
 		_dl_secure = 0;
 		_dl_preload = _dl_getenv("LD_PRELOAD", envp);
 		_dl_library_path = _dl_getenv("LD_LIBRARY_PATH", envp);
+		preserved_library_path = _dl_getenv("LD_GENTOO_PRESERVED_LIBRARY_PATH", envp);
 	} else {
 		static const char unsecure_envvars[] =
 #ifdef EXTRA_UNSECURE_ENVVARS
@@ -221,6 +223,7 @@
 		} while (*nextp != '\0');
 		_dl_preload = NULL;
 		_dl_library_path = NULL;
+		preserved_library_path = NULL;
 		/* SUID binaries can be exploited if they do LAZY relocation. */
 		unlazy = RTLD_NOW;
 	}
diff -ru ../uClibc-0.9.30.1/ldso/libdl/libdl.c ./ldso/libdl/libdl.c
--- ../uClibc-0.9.30.1/ldso/libdl/libdl.c	2008-10-29 14:34:35.000000000 +0100
+++ ./ldso/libdl/libdl.c	2010-04-03 11:23:18.998879057 +0200
@@ -90,6 +90,7 @@
 void *(*_dl_malloc_function)(size_t);
 void (*_dl_free_function) (void *p);
 char *_dl_library_path         = 0;         /* Where we look for libraries */
+char *preserved_library_path   = 0;         /* Gentoo preserved library path */
 char *_dl_ldsopath             = 0;         /* Location of the shared lib loader */
 int _dl_errno                  = 0;         /* We can't use the real errno in ldso */
 size_t _dl_pagesize            = PAGE_SIZE; /* Store the page size for use later */
@@ -232,6 +233,7 @@
 #ifndef SHARED
 	/* When statically linked, the _dl_library_path is not yet initialized */
 	_dl_library_path = getenv("LD_LIBRARY_PATH");
+	preserved_library_path = getenv("LD_GENTOO_PRESERVED_LIBRARY_PATH");
 #endif
 
 	/* Try to load the specified library */

Reply via email to