Merge "debuggerd_fallback: print maps." into oc-mr1-dev
diff --git a/libnativeloader/include/nativeloader/native_loader.h b/libnativeloader/include/nativeloader/native_loader.h
index 99ae3a7..3563fc1 100644
--- a/libnativeloader/include/nativeloader/native_loader.h
+++ b/libnativeloader/include/nativeloader/native_loader.h
@@ -34,6 +34,7 @@
                                    int32_t target_sdk_version,
                                    jobject class_loader,
                                    bool is_shared,
+                                   bool is_for_vendor,
                                    jstring library_path,
                                    jstring permitted_path);
 
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index 7ccd7db..5d160ee 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -82,6 +82,11 @@
                                   "/etc/public.libraries.txt";
 static constexpr const char* kPublicNativeLibrariesVendorConfig =
                                   "/vendor/etc/public.libraries.txt";
+static constexpr const char* kLlndkNativeLibrariesSystemConfigPathFromRoot =
+                                  "/etc/llndk.libraries.txt";
+static constexpr const char* kVndkspNativeLibrariesSystemConfigPathFromRoot =
+                                  "/etc/vndksp.libraries.txt";
+
 
 // The device may be configured to have the vendor libraries loaded to a separate namespace.
 // For historical reasons this namespace was named sphal but effectively it is intended
@@ -89,6 +94,11 @@
 // vendor and system namespaces.
 static constexpr const char* kVendorNamespaceName = "sphal";
 
+static constexpr const char* kVndkNamespaceName = "vndk";
+
+static constexpr const char* kClassloaderNamespaceName = "classloader-namespace";
+static constexpr const char* kVendorClassloaderNamespaceName = "vendor-classloader-namespace";
+
 // (http://b/27588281) This is a workaround for apps using custom classloaders and calling
 // System.load() with an absolute path which is outside of the classloader library search path.
 // This list includes all directories app is allowed to access this way.
@@ -108,6 +118,7 @@
               uint32_t target_sdk_version,
               jobject class_loader,
               bool is_shared,
+              bool is_for_vendor,
               jstring java_library_path,
               jstring java_permitted_path,
               NativeLoaderNamespace* ns,
@@ -163,9 +174,39 @@
       is_native_bridge = NativeBridgeIsPathSupported(library_path.c_str());
     }
 
+    std::string system_exposed_libraries = system_public_libraries_;
+    const char* namespace_name = kClassloaderNamespaceName;
+    android_namespace_t* vndk_ns = nullptr;
+    if (is_for_vendor && !is_shared) {
+      LOG_FATAL_IF(is_native_bridge, "Unbundled vendor apk must not use translated architecture");
+
+      // For vendor apks, give access to the vendor lib even though
+      // they are treated as unbundled; the libs and apks are still bundled
+      // together in the vendor partition.
+#if defined(__LP64__)
+      std::string vendor_lib_path = "/vendor/lib64";
+#else
+      std::string vendor_lib_path = "/vendor/lib";
+#endif
+      library_path = library_path + ":" + vendor_lib_path.c_str();
+      permitted_path = permitted_path + ":" + vendor_lib_path.c_str();
+
+      // Also give access to LLNDK libraries since they are available to vendors
+      system_exposed_libraries = system_exposed_libraries + ":" + system_llndk_libraries_.c_str();
+
+      // Give access to VNDK-SP libraries from the 'vndk' namespace.
+      vndk_ns = android_get_exported_namespace(kVndkNamespaceName);
+      LOG_ALWAYS_FATAL_IF(vndk_ns == nullptr,
+                          "Cannot find \"%s\" namespace for vendor apks", kVndkNamespaceName);
+
+      // Different name is useful for debugging
+      namespace_name = kVendorClassloaderNamespaceName;
+      ALOGD("classloader namespace configured for unbundled vendor apk. library_path=%s", library_path.c_str());
+    }
+
     NativeLoaderNamespace native_loader_ns;
     if (!is_native_bridge) {
-      android_namespace_t* ns = android_create_namespace("classloader-namespace",
+      android_namespace_t* ns = android_create_namespace(namespace_name,
                                                          nullptr,
                                                          library_path.c_str(),
                                                          namespace_type,
@@ -181,11 +222,19 @@
       // which is expected behavior in this case.
       android_namespace_t* vendor_ns = android_get_exported_namespace(kVendorNamespaceName);
 
-      if (!android_link_namespaces(ns, nullptr, system_public_libraries_.c_str())) {
+      if (!android_link_namespaces(ns, nullptr, system_exposed_libraries.c_str())) {
         *error_msg = dlerror();
         return false;
       }
 
+      if (vndk_ns != nullptr && !system_vndksp_libraries_.empty()) {
+        // vendor apks are allowed to use VNDK-SP libraries.
+        if (!android_link_namespaces(ns, vndk_ns, system_vndksp_libraries_.c_str())) {
+          *error_msg = dlerror();
+          return false;
+        }
+      }
+
       if (!vendor_public_libraries_.empty()) {
         if (!android_link_namespaces(ns, vendor_ns, vendor_public_libraries_.c_str())) {
           *error_msg = dlerror();
@@ -195,7 +244,7 @@
 
       native_loader_ns = NativeLoaderNamespace(ns);
     } else {
-      native_bridge_namespace_t* ns = NativeBridgeCreateNamespace("classloader-namespace",
+      native_bridge_namespace_t* ns = NativeBridgeCreateNamespace(namespace_name,
                                                                   nullptr,
                                                                   library_path.c_str(),
                                                                   namespace_type,
@@ -209,7 +258,7 @@
 
       native_bridge_namespace_t* vendor_ns = NativeBridgeGetVendorNamespace();
 
-      if (!NativeBridgeLinkNamespaces(ns, nullptr, system_public_libraries_.c_str())) {
+      if (!NativeBridgeLinkNamespaces(ns, nullptr, system_exposed_libraries.c_str())) {
         *error_msg = NativeBridgeGetError();
         return false;
       }
@@ -259,6 +308,10 @@
     std::string root_dir = android_root_env != nullptr ? android_root_env : "/system";
     std::string public_native_libraries_system_config =
             root_dir + kPublicNativeLibrariesSystemConfigPathFromRoot;
+    std::string llndk_native_libraries_system_config =
+            root_dir + kLlndkNativeLibrariesSystemConfigPathFromRoot;
+    std::string vndksp_native_libraries_system_config =
+            root_dir + kVndkspNativeLibrariesSystemConfigPathFromRoot;
 
     std::string error_msg;
     LOG_ALWAYS_FATAL_IF(!ReadConfig(public_native_libraries_system_config, &sonames, &error_msg),
@@ -294,6 +347,14 @@
     system_public_libraries_ = base::Join(sonames, ':');
 
     sonames.clear();
+    ReadConfig(kLlndkNativeLibrariesSystemConfigPathFromRoot, &sonames);
+    system_llndk_libraries_ = base::Join(sonames, ':');
+
+    sonames.clear();
+    ReadConfig(kVndkspNativeLibrariesSystemConfigPathFromRoot, &sonames);
+    system_vndksp_libraries_ = base::Join(sonames, ':');
+
+    sonames.clear();
     // This file is optional, quietly ignore if the file does not exist.
     ReadConfig(kPublicNativeLibrariesVendorConfig, &sonames);
 
@@ -404,6 +465,8 @@
   std::vector<std::pair<jweak, NativeLoaderNamespace>> namespaces_;
   std::string system_public_libraries_;
   std::string vendor_public_libraries_;
+  std::string system_llndk_libraries_;
+  std::string system_vndksp_libraries_;
 
   DISALLOW_COPY_AND_ASSIGN(LibraryNamespaces);
 };
@@ -430,6 +493,7 @@
                                    int32_t target_sdk_version,
                                    jobject class_loader,
                                    bool is_shared,
+                                   bool is_for_vendor,
                                    jstring library_path,
                                    jstring permitted_path) {
 #if defined(__ANDROID__)
@@ -441,6 +505,7 @@
                                       target_sdk_version,
                                       class_loader,
                                       is_shared,
+                                      is_for_vendor,
                                       library_path,
                                       permitted_path,
                                       &ns,
@@ -449,7 +514,7 @@
     return env->NewStringUTF(error_msg.c_str());
   }
 #else
-  UNUSED(env, target_sdk_version, class_loader, is_shared,
+  UNUSED(env, target_sdk_version, class_loader, is_shared, is_for_vendor,
          library_path, permitted_path);
 #endif
   return nullptr;
@@ -478,7 +543,8 @@
     if (!g_namespaces->Create(env,
                               target_sdk_version,
                               class_loader,
-                              false,
+                              false /* is_shared */,
+                              false /* is_for_vendor */,
                               library_path,
                               nullptr,
                               &ns,
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index e4b2f7b..3377716 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -258,3 +258,45 @@
 LOCAL_MODULE_STEM := $(LOCAL_MODULE)
 include $(BUILD_PREBUILT)
 endif
+
+#######################################
+# llndk.libraries.txt
+include $(CLEAR_VARS)
+LOCAL_MODULE := llndk.libraries.txt
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
+LOCAL_MODULE_STEM := $(LOCAL_MODULE)
+include $(BUILD_SYSTEM)/base_rules.mk
+llndk_md5 = $(word 1, $(shell echo $(LLNDK_LIBRARIES) | $(MD5SUM)))
+llndk_dep = $(intermediates)/$(llndk_md5).dep
+$(llndk_dep):
+	$(hide) mkdir -p $(dir $@) && rm -rf $(dir $@)*.dep && touch $@
+
+$(LOCAL_BUILT_MODULE): PRIVATE_LLNDK_LIBRARIES := $(LLNDK_LIBRARIES)
+$(LOCAL_BUILT_MODULE): $(llndk_dep)
+	@echo "Generate: $@"
+	@mkdir -p $(dir $@)
+	$(hide) echo -n > $@
+	$(hide) $(foreach lib,$(PRIVATE_LLNDK_LIBRARIES), \
+		echo $(lib).so >> $@;)
+
+#######################################
+# vndksp.libraries.txt
+include $(CLEAR_VARS)
+LOCAL_MODULE := vndksp.libraries.txt
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
+LOCAL_MODULE_STEM := $(LOCAL_MODULE)
+include $(BUILD_SYSTEM)/base_rules.mk
+vndksp_md5 = $(word 1, $(shell echo $(LLNDK_LIBRARIES) | $(MD5SUM)))
+vndksp_dep = $(intermediates)/$(vndksp_md5).dep
+$(vndksp_dep):
+	$(hide) mkdir -p $(dir $@) && rm -rf $(dir $@)*.dep && touch $@
+
+$(LOCAL_BUILT_MODULE): PRIVATE_VNDK_SAMEPROCESS_LIBRARIES := $(VNDK_SAMEPROCESS_LIBRARIES)
+$(LOCAL_BUILT_MODULE): $(vndksp_dep)
+	@echo "Generate: $@"
+	@mkdir -p $(dir $@)
+	$(hide) echo -n > $@
+	$(hide) $(foreach lib,$(PRIVATE_VNDK_SAMEPROCESS_LIBRARIES), \
+		echo $(lib).so >> $@;)
diff --git a/rootdir/etc/ld.config.txt.in b/rootdir/etc/ld.config.txt.in
index e741a34..af37287 100644
--- a/rootdir/etc/ld.config.txt.in
+++ b/rootdir/etc/ld.config.txt.in
@@ -27,16 +27,12 @@
 # can't be loaded in this namespace.
 ###############################################################################
 namespace.default.isolated = true
-# TODO(b/63553457): remove /vendor/lib from the search path. For now, this is
-# required since the classloader namespace for vendor apks should have access
-# vendor libraries in the directory. These search paths are copied to the search
-# paths of the classloader namespace.
-namespace.default.search.paths = /system/${LIB}:/vendor/${LIB}
+namespace.default.search.paths = /system/${LIB}
 # /vendor/app, /vendor/framework were added since libart should be able to dlopen
 # the odex files from the directory.
 namespace.default.permitted.paths = /system/${LIB}/drm:/system/${LIB}/hw:/system/framework:/system/app:/system/priv-app:/vendor/app:/vendor/framework:/oem/app:/data:/mnt/expand
 
-namespace.default.asan.search.paths = /data/asan/system/${LIB}:/system/${LIB}:/data/asan/vendor/${LIB}:/vendor/${LIB}
+namespace.default.asan.search.paths = /data/asan/system/${LIB}:/system/${LIB}
 namespace.default.asan.permitted.paths = /data:/system/${LIB}/drm:/system/${LIB}/hw:/system/framework:/system/app:/system/priv-app:/vendor/app:/vendor/framework:/oem/app:/mnt/expand
 
 ###############################################################################
@@ -99,6 +95,7 @@
 # This namespace is exclusively for vndk-sp libs.
 ###############################################################################
 namespace.vndk.isolated = true
+namespace.vndk.visible = true
 namespace.vndk.search.paths = /vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp
 namespace.vndk.permitted.paths = /vendor/${LIB}/hw:/vendor/${LIB}/egl
 
diff --git a/sdcard/sdcard.cpp b/sdcard/sdcard.cpp
index c342cf8..2bbb906 100644
--- a/sdcard/sdcard.cpp
+++ b/sdcard/sdcard.cpp
@@ -317,17 +317,31 @@
     LOG(FATAL) << "terminated prematurely";
 }
 
-static bool sdcardfs_setup(const std::string& source_path, const std::string& dest_path, uid_t fsuid,
-                        gid_t fsgid, bool multi_user, userid_t userid, gid_t gid, mode_t mask) {
-    std::string opts = android::base::StringPrintf("fsuid=%d,fsgid=%d,%smask=%d,userid=%d,gid=%d",
-            fsuid, fsgid, multi_user?"multiuser,":"", mask, userid, gid);
+static bool sdcardfs_setup(const std::string& source_path, const std::string& dest_path,
+                           uid_t fsuid, gid_t fsgid, bool multi_user, userid_t userid, gid_t gid,
+                           mode_t mask, bool derive_gid) {
+    std::string opts = android::base::StringPrintf(
+        "fsuid=%d,fsgid=%d,%s%smask=%d,userid=%d,gid=%d", fsuid, fsgid,
+        multi_user ? "multiuser," : "", derive_gid ? "derive_gid," : "", mask, userid, gid);
 
     if (mount(source_path.c_str(), dest_path.c_str(), "sdcardfs",
               MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opts.c_str()) == -1) {
-        PLOG(ERROR) << "failed to mount sdcardfs filesystem";
-        return false;
+        if (derive_gid) {
+            PLOG(ERROR) << "trying to mount sdcardfs filesystem without derive_gid";
+            /* Maybe this isn't supported on this kernel. Try without. */
+            opts = android::base::StringPrintf("fsuid=%d,fsgid=%d,%smask=%d,userid=%d,gid=%d",
+                                               fsuid, fsgid, multi_user ? "multiuser," : "", mask,
+                                               userid, gid);
+            if (mount(source_path.c_str(), dest_path.c_str(), "sdcardfs",
+                      MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opts.c_str()) == -1) {
+                PLOG(ERROR) << "failed to mount sdcardfs filesystem";
+                return false;
+            }
+        } else {
+            PLOG(ERROR) << "failed to mount sdcardfs filesystem";
+            return false;
+        }
     }
-
     return true;
 }
 
@@ -353,7 +367,8 @@
 }
 
 static void run_sdcardfs(const std::string& source_path, const std::string& label, uid_t uid,
-        gid_t gid, userid_t userid, bool multi_user, bool full_write) {
+                         gid_t gid, userid_t userid, bool multi_user, bool full_write,
+                         bool derive_gid) {
     std::string dest_path_default = "/mnt/runtime/default/" + label;
     std::string dest_path_read = "/mnt/runtime/read/" + label;
     std::string dest_path_write = "/mnt/runtime/write/" + label;
@@ -363,10 +378,10 @@
         // Multi-user storage is fully isolated per user, so "other"
         // permissions are completely masked off.
         if (!sdcardfs_setup(source_path, dest_path_default, uid, gid, multi_user, userid,
-                                                      AID_SDCARD_RW, 0006)
-                || !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, AID_EVERYBODY, 0027)
-                || !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write,
-                                                      AID_EVERYBODY, full_write ? 0007 : 0027)) {
+                            AID_SDCARD_RW, 0006, derive_gid) ||
+            !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, AID_EVERYBODY, 0027) ||
+            !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write, AID_EVERYBODY,
+                                         full_write ? 0007 : 0027)) {
             LOG(FATAL) << "failed to sdcardfs_setup";
         }
     } else {
@@ -374,11 +389,11 @@
         // the Android directories are masked off to a single user
         // deep inside attr_from_stat().
         if (!sdcardfs_setup(source_path, dest_path_default, uid, gid, multi_user, userid,
-                                                      AID_SDCARD_RW, 0006)
-                || !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read,
-                                                      AID_EVERYBODY, full_write ? 0027 : 0022)
-                || !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write,
-                                                      AID_EVERYBODY, full_write ? 0007 : 0022)) {
+                            AID_SDCARD_RW, 0006, derive_gid) ||
+            !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, AID_EVERYBODY,
+                                         full_write ? 0027 : 0022) ||
+            !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write, AID_EVERYBODY,
+                                         full_write ? 0007 : 0022)) {
             LOG(FATAL) << "failed to sdcardfs_setup";
         }
     }
@@ -435,7 +450,8 @@
                << "    -g: specify GID to run as"
                << "    -U: specify user ID that owns device"
                << "    -m: source_path is multi-user"
-               << "    -w: runtime write mount has full write access";
+               << "    -w: runtime write mount has full write access"
+               << "    -P  preserve owners on the lower file system";
     return 1;
 }
 
@@ -447,12 +463,13 @@
     userid_t userid = 0;
     bool multi_user = false;
     bool full_write = false;
+    bool derive_gid = false;
     int i;
     struct rlimit rlim;
     int fs_version;
 
     int opt;
-    while ((opt = getopt(argc, argv, "u:g:U:mw")) != -1) {
+    while ((opt = getopt(argc, argv, "u:g:U:mwG")) != -1) {
         switch (opt) {
             case 'u':
                 uid = strtoul(optarg, NULL, 10);
@@ -469,6 +486,9 @@
             case 'w':
                 full_write = true;
                 break;
+            case 'G':
+                derive_gid = true;
+                break;
             case '?':
             default:
                 return usage();
@@ -512,7 +532,7 @@
     }
 
     if (should_use_sdcardfs()) {
-        run_sdcardfs(source_path, label, uid, gid, userid, multi_user, full_write);
+        run_sdcardfs(source_path, label, uid, gid, userid, multi_user, full_write, derive_gid);
     } else {
         run(source_path, label, uid, gid, userid, multi_user, full_write);
     }