diff --git a/bits/dlfcn.h b/bits/dlfcn.h
index 9170059323..ef079709f9 100644
--- a/bits/dlfcn.h
+++ b/bits/dlfcn.h
@@ -32,6 +32,9 @@
    visible as if the object were linked directly into the program.  */
 #define RTLD_GLOBAL	0x00100
 
+/* Suppress RTLD_SHARED and/or DF_1_UNIQUE.  */
+#define RTLD_ISOLATE 0x00040
+
 /* If the following bit is set in the MODE argument to dlmopen
    then the target object is loaded into the main namespace (if
    it is not already there) and a shallow copy (proxy) is placed
diff --git a/elf/dl-load.c b/elf/dl-load.c
index e0eced6dd2..bf86d3c7f9 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -1000,7 +1000,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
   /* DSOs in the main namespace which are flagged DT_GNU_UNIQUE should only
      be opened into the main namespace. Other namespaces should only get
      proxies.  */
-  if (__glibc_unlikely (nsid != LM_ID_BASE))
+  if (__glibc_unlikely ((nsid != LM_ID_BASE) && !(mode & RTLD_ISOLATE)))
     {
       /* Check base ns to see if the name matched another already loaded.  */
       for (l = GL(dl_ns)[LM_ID_BASE]._ns_loaded; l != NULL; l = l->l_next)
@@ -1092,7 +1092,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
 
   /* We need to check for DT_GNU_UNIQUE before we start
      initialising any namespace dependent metatada.  */
-  if (nsid != LM_ID_BASE)
+  if (__glibc_unlikely ((nsid != LM_ID_BASE) && !(mode & RTLD_ISOLATE)))
     {
       /* Target DSO is flagged as unique: Make sure it gets loaded into
          the base namespace. It is up to our caller to generate a proxy in
@@ -2083,6 +2083,7 @@ _dl_map_object (struct link_map *loader, const char *name,
 
   assert (nsid >= 0);
   assert (nsid < GL(dl_nns));
+  assert (!((mode & RTLD_ISOLATE) && (mode & RTLD_SHARED)));
 
 #ifdef SHARED
   /* Only need to do proxy checks if `nsid' is not LM_ID_BASE.  */
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 43597a510e..67d5825510 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -477,9 +477,16 @@ dl_open_worker (void *a)
   int mode = args->mode;
   struct link_map *call_map = NULL;
   struct link_map *preloaded = NULL;
-  int want_proxy = mode & RTLD_SHARED;
+  int want_proxy = 0;
+  int dl_isolate = mode & RTLD_ISOLATE;
   Lmid_t proxy_ns = LM_ID_BASE;
 
+  /* Isolation means we should suppress all inter-namespace sharing.  */
+  if (dl_isolate)
+      mode &= ~RTLD_SHARED;
+  else
+      want_proxy = mode & RTLD_SHARED;
+
   /* Determine the caller's map if necessary.  This is needed in case
      we have a DST, when we don't know the namespace ID we have to put
      the new object in, or when the file name has no path in which
@@ -526,6 +533,7 @@ dl_open_worker (void *a)
      want_proxy.
      NOTE: RTLD_ISOLATE in the mode suppresses this behaviour.  */
   if (__glibc_unlikely (args->nsid != LM_ID_BASE) &&
+      __glibc_likely (!dl_isolate) &&
       __glibc_likely (!want_proxy))
     {
       preloaded = _dl_find_dso (file, LM_ID_BASE);
@@ -636,7 +644,8 @@ dl_open_worker (void *a)
 
   /* Load that object's dependencies.  */
   _dl_map_object_deps (new, NULL, 0, 0,
-		       mode & (__RTLD_DLOPEN | RTLD_DEEPBIND | __RTLD_AUDIT));
+		       mode & (__RTLD_DLOPEN | RTLD_DEEPBIND | __RTLD_AUDIT |
+		               RTLD_ISOLATE));
 
   /* So far, so good.  Now check the versions.  */
   for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i)
diff --git a/elf/rtld.c b/elf/rtld.c
index 553cfbd1b7..be08786419 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -616,7 +616,7 @@ dlmopen_doit (void *a)
   struct dlmopen_args *args = (struct dlmopen_args *) a;
   args->map = _dl_open (args->fname,
 			(RTLD_LAZY | __RTLD_DLOPEN | __RTLD_AUDIT
-			 | __RTLD_SECURE),
+			 | __RTLD_SECURE | RTLD_ISOLATE),
 			dl_main, LM_ID_NEWLM, _dl_argc, _dl_argv,
 			__environ);
 }
diff --git a/sysdeps/mips/bits/dlfcn.h b/sysdeps/mips/bits/dlfcn.h
index fc33fd184e..372dcf4097 100644
--- a/sysdeps/mips/bits/dlfcn.h
+++ b/sysdeps/mips/bits/dlfcn.h
@@ -39,6 +39,9 @@
    share a single instance of a DSO.  */
 #define RTLD_SHARED 0x00020
 
+/* Suppress RTLD_SHARED and/or DF_1_UNIQUE.  */
+#define RTLD_ISOLATE 0x00040
+
 /* Unix98 demands the following flag which is the inverse to RTLD_GLOBAL.
    The implementation does this by default and so we can define the
    value to zero.  */
