Merge "Rename base/ to android-base/."
diff --git a/adb/adb_auth_client.cpp b/adb/adb_auth_client.cpp
index 463b496..c4ffc85 100644
--- a/adb/adb_auth_client.cpp
+++ b/adb/adb_auth_client.cpp
@@ -228,13 +228,13 @@
 
 static void adb_auth_listener(int fd, unsigned events, void *data)
 {
-    struct sockaddr addr;
+    sockaddr_storage addr;
     socklen_t alen;
     int s;
 
     alen = sizeof(addr);
 
-    s = adb_socket_accept(fd, &addr, &alen);
+    s = adb_socket_accept(fd, reinterpret_cast<sockaddr*>(&addr), &alen);
     if (s < 0) {
         D("Failed to accept: errno=%d", errno);
         return;
diff --git a/adb/adb_listeners.cpp b/adb/adb_listeners.cpp
index d7b892c..e8c2338 100644
--- a/adb/adb_listeners.cpp
+++ b/adb/adb_listeners.cpp
@@ -34,9 +34,10 @@
 
 static void ss_listener_event_func(int _fd, unsigned ev, void *_l) {
     if (ev & FDE_READ) {
-        struct sockaddr addr;
-        socklen_t alen = sizeof(addr);
-        int fd = adb_socket_accept(_fd, &addr, &alen);
+        sockaddr_storage ss;
+        sockaddr* addrp = reinterpret_cast<sockaddr*>(&ss);
+        socklen_t alen = sizeof(ss);
+        int fd = adb_socket_accept(_fd, addrp, &alen);
         if (fd < 0) return;
 
         int rcv_buf_size = CHUNK_SIZE;
@@ -58,12 +59,13 @@
     asocket *s;
 
     if (ev & FDE_READ) {
-        struct sockaddr addr;
+        sockaddr_storage ss;
+        sockaddr* addrp = reinterpret_cast<sockaddr*>(&ss);
         socklen_t alen;
         int fd;
 
-        alen = sizeof(addr);
-        fd = adb_socket_accept(_fd, &addr, &alen);
+        alen = sizeof(ss);
+        fd = adb_socket_accept(_fd, addrp, &alen);
         if (fd < 0) {
             return;
         }
@@ -79,7 +81,7 @@
     }
 }
 
-static void  free_listener(alistener*  l)
+static void free_listener(alistener*  l)
 {
     if (l->next) {
         l->next->prev = l->prev;
diff --git a/adb/jdwp_service.cpp b/adb/jdwp_service.cpp
index cc2d44e..3c812cc 100644
--- a/adb/jdwp_service.cpp
+++ b/adb/jdwp_service.cpp
@@ -460,11 +460,11 @@
                    const char*   sockname,
                    int           socknamelen )
 {
-    struct sockaddr_un   addr;
-    socklen_t            addrlen;
-    int                  s;
-    int                  maxpath = sizeof(addr.sun_path);
-    int                  pathlen = socknamelen;
+    sockaddr_un   addr;
+    socklen_t     addrlen;
+    int           s;
+    int           maxpath = sizeof(addr.sun_path);
+    int           pathlen = socknamelen;
 
     if (pathlen >= maxpath) {
         D( "vm debug control socket name too long (%d extra chars)",
@@ -485,7 +485,7 @@
 
     addrlen = (pathlen + sizeof(addr.sun_family));
 
-    if (bind(s, (struct sockaddr*)&addr, addrlen) < 0) {
+    if (bind(s, reinterpret_cast<sockaddr*>(&addr), addrlen) < 0) {
         D( "could not bind vm debug control socket: %d: %s",
            errno, strerror(errno) );
         adb_close(s);
@@ -523,13 +523,14 @@
     JdwpControl*  control = (JdwpControl*) _control;
 
     if (events & FDE_READ) {
-        struct sockaddr   addr;
-        socklen_t         addrlen = sizeof(addr);
-        int               s = -1;
-        JdwpProcess*      proc;
+        sockaddr_storage   ss;
+        sockaddr*          addrp = reinterpret_cast<sockaddr*>(&ss);
+        socklen_t          addrlen = sizeof(ss);
+        int                s = -1;
+        JdwpProcess*       proc;
 
         do {
-            s = adb_socket_accept( control->listen_socket, &addr, &addrlen );
+            s = adb_socket_accept(control->listen_socket, addrp, &addrlen);
             if (s < 0) {
                 if (errno == EINTR)
                     continue;
diff --git a/adb/shell_service.cpp b/adb/shell_service.cpp
index 3fc70b0..6c06669 100644
--- a/adb/shell_service.cpp
+++ b/adb/shell_service.cpp
@@ -289,7 +289,6 @@
         // TODO: $HOSTNAME? Normally bash automatically sets that, but mksh doesn't.
         passwd* pw = getpwuid(getuid());
         if (pw != nullptr) {
-            setenv("HOME", pw->pw_dir, 1);
             setenv("LOGNAME", pw->pw_name, 1);
             setenv("SHELL", pw->pw_shell, 1);
             setenv("USER", pw->pw_name, 1);
@@ -298,6 +297,8 @@
             setenv("TERM", terminal_type_.c_str(), 1);
         }
 
+        setenv("HOME", "/data/local/tmp", 1);
+        chdir(getenv("HOME"));
         if (is_interactive()) {
             execl(_PATH_BSHELL, _PATH_BSHELL, "-", nullptr);
         } else {
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
index 2c1a71d..d2a375a 100644
--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -143,7 +143,8 @@
 static void *server_socket_thread(void * arg)
 {
     int serverfd, fd;
-    struct sockaddr addr;
+    sockaddr_storage ss;
+    sockaddr *addrp = reinterpret_cast<sockaddr*>(&ss);
     socklen_t alen;
     int port = (int) (uintptr_t) arg;
 
@@ -162,9 +163,9 @@
             close_on_exec(serverfd);
         }
 
-        alen = sizeof(addr);
+        alen = sizeof(ss);
         D("server: trying to get new connection from %d", port);
-        fd = adb_socket_accept(serverfd, &addr, &alen);
+        fd = adb_socket_accept(serverfd, addrp, &alen);
         if(fd >= 0) {
             D("server: new connection on fd %d", fd);
             close_on_exec(fd);
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index 884d4d5..0afa895 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -518,11 +518,12 @@
   ALOGI("debuggerd: starting\n");
 
   for (;;) {
-    sockaddr addr;
-    socklen_t alen = sizeof(addr);
+    sockaddr_storage ss;
+    sockaddr* addrp = reinterpret_cast<sockaddr*>(&ss);
+    socklen_t alen = sizeof(ss);
 
     ALOGV("waiting for connection\n");
-    int fd = accept(s, &addr, &alen);
+    int fd = accept(s, addrp, &alen);
     if (fd < 0) {
       ALOGV("accept failed: %s\n", strerror(errno));
       continue;
diff --git a/include/nativeloader/native_loader.h b/include/nativeloader/native_loader.h
new file mode 100644
index 0000000..18b7ba4
--- /dev/null
+++ b/include/nativeloader/native_loader.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NATIVE_LOADER_H_
+#define NATIVE_LOADER_H_
+
+#include "jni.h"
+#include <stdint.h>
+
+namespace android {
+
+__attribute__((visibility("default")))
+void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path,
+                        jobject class_loader, jstring library_path);
+
+};  // namespace android
+
+#endif  // NATIVE_BRIDGE_H_
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 6e58233..7d32a44 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -64,13 +64,6 @@
 
 static int property_set_fd = -1;
 
-struct workspace {
-    size_t size;
-    int fd;
-};
-
-static workspace pa_workspace;
-
 void property_init() {
     if (property_area_initialized) {
         return;
@@ -82,13 +75,6 @@
         ERROR("Failed to initialize property area\n");
         exit(1);
     }
-
-    pa_workspace.size = 0;
-    pa_workspace.fd = open(PROP_FILENAME, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
-    if (pa_workspace.fd == -1) {
-        ERROR("Failed to open %s: %s\n", PROP_FILENAME, strerror(errno));
-        return;
-    }
 }
 
 static int check_mac_perms(const char *name, char *sctx, struct ucred *cr)
@@ -354,12 +340,6 @@
     }
 }
 
-void get_property_workspace(int *fd, int *sz)
-{
-    *fd = pa_workspace.fd;
-    *sz = pa_workspace.size;
-}
-
 static void load_properties_from_file(const char *, const char *);
 
 /*
diff --git a/init/property_service.h b/init/property_service.h
index 8b76d2b..b662978 100644
--- a/init/property_service.h
+++ b/init/property_service.h
@@ -32,7 +32,6 @@
 extern void load_persist_props(void);
 extern void load_system_props(void);
 extern void start_property_service(void);
-void get_property_workspace(int *fd, int *sz);
 std::string property_get(const char* name);
 extern int property_set(const char *name, const char *value);
 extern bool properties_initialized();
diff --git a/init/service.cpp b/init/service.cpp
index 1af3e60..e78787b 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -400,14 +400,7 @@
 
     pid_t pid = fork();
     if (pid == 0) {
-        int fd, sz;
-
         umask(077);
-        if (properties_initialized()) {
-            get_property_workspace(&fd, &sz);
-            std::string tmp = StringPrintf("%d,%d", dup(fd), sz);
-            add_environment("ANDROID_PROPERTY_WORKSPACE", tmp.c_str());
-        }
 
         for (const auto& ei : envvars_) {
             add_environment(ei.name.c_str(), ei.value.c_str());
diff --git a/libcutils/socket_inaddr_any_server.c b/libcutils/socket_inaddr_any_server.c
index 7f0ccb8..e1b7d84 100644
--- a/libcutils/socket_inaddr_any_server.c
+++ b/libcutils/socket_inaddr_any_server.c
@@ -34,21 +34,21 @@
 /* open listen() port on any interface */
 int socket_inaddr_any_server(int port, int type)
 {
-    struct sockaddr_in addr;
+    struct sockaddr_in6 addr;
     int s, n;
 
     memset(&addr, 0, sizeof(addr));
-    addr.sin_family = AF_INET;
-    addr.sin_port = htons(port);
-    addr.sin_addr.s_addr = htonl(INADDR_ANY);
+    addr.sin6_family = AF_INET6;
+    addr.sin6_port = htons(port);
+    addr.sin6_addr = in6addr_any;
 
-    s = socket(AF_INET, type, 0);
-    if(s < 0) return -1;
+    s = socket(AF_INET6, type, 0);
+    if (s < 0) return -1;
 
     n = 1;
     setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *) &n, sizeof(n));
 
-    if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+    if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
         close(s);
         return -1;
     }
diff --git a/liblog/logprint.c b/liblog/logprint.c
index ad52a81..40e13f4 100644
--- a/liblog/logprint.c
+++ b/liblog/logprint.c
@@ -500,14 +500,14 @@
     }
     if (msgEnd == -1) {
         /* incoming message not null-terminated; force it */
-        msgEnd = buf->len - 1;
+        msgEnd = buf->len - 1; /* may result in msgEnd < msgStart */
         msg[msgEnd] = '\0';
     }
 
     entry->priority = msg[0];
     entry->tag = msg + 1;
     entry->message = msg + msgStart;
-    entry->messageLen = msgEnd - msgStart;
+    entry->messageLen = (msgEnd < msgStart) ? 0 : (msgEnd - msgStart);
 
     return 0;
 }
diff --git a/libnativeloader/Android.mk b/libnativeloader/Android.mk
new file mode 100644
index 0000000..5e65c4c
--- /dev/null
+++ b/libnativeloader/Android.mk
@@ -0,0 +1,54 @@
+LOCAL_PATH:= $(call my-dir)
+
+NATIVE_LOADER_COMMON_SRC_FILES := \
+  native_loader.cpp
+
+# Shared library for target
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= libnativeloader
+
+LOCAL_SRC_FILES:= $(NATIVE_LOADER_COMMON_SRC_FILES)
+LOCAL_SHARED_LIBRARIES := libnativehelper liblog libcutils
+LOCAL_STATIC_LIBRARIES := libbase
+LOCAL_CLANG := true
+LOCAL_CFLAGS += -Werror -Wall
+LOCAL_CPPFLAGS := -std=gnu++14 -fvisibility=hidden
+LOCAL_LDFLAGS := -ldl
+LOCAL_MULTILIB := both
+
+include $(BUILD_SHARED_LIBRARY)
+
+# Shared library for host
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= libnativeloader
+
+LOCAL_SRC_FILES:= $(NATIVE_LOADER_COMMON_SRC_FILES)
+LOCAL_SHARED_LIBRARIES := libnativehelper liblog libcutils
+LOCAL_STATIC_LIBRARIES := libbase
+LOCAL_CLANG := true
+LOCAL_CFLAGS += -Werror -Wall
+LOCAL_CPPFLAGS := -std=gnu++14 -fvisibility=hidden
+LOCAL_LDFLAGS := -ldl
+LOCAL_MULTILIB := both
+
+include $(BUILD_HOST_SHARED_LIBRARY)
+
+# Static library for host
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= libnativeloader
+
+LOCAL_SRC_FILES:= $(NATIVE_LOADER_COMMON_SRC_FILES)
+LOCAL_STATIC_LIBRARIES := libnativehelper libcutils liblog libbase
+LOCAL_CLANG := true
+LOCAL_CFLAGS += -Werror -Wall
+LOCAL_CPPFLAGS := -std=gnu++14 -fvisibility=hidden
+LOCAL_LDFLAGS := -ldl
+LOCAL_MULTILIB := both
+
+include $(BUILD_HOST_STATIC_LIBRARY)
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
new file mode 100644
index 0000000..33870e2
--- /dev/null
+++ b/libnativeloader/native_loader.cpp
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "nativeloader/native_loader.h"
+#include "ScopedUtfChars.h"
+
+#include <dlfcn.h>
+#ifdef __ANDROID__
+#include <android/dlext.h>
+#include "cutils/properties.h"
+#endif
+
+#include <algorithm>
+#include <vector>
+#include <string>
+#include <mutex>
+
+#include "base/macros.h"
+#include "base/strings.h"
+
+namespace android {
+
+#ifdef __ANDROID__
+// TODO(dimitry): move this to system properties.
+static const char* kPublicNativeLibraries = "libandroid.so:"
+                                            "libc.so:"
+                                            "libdl.so:"
+                                            "libEGL.so:"
+                                            "libGLESv1_CM.so:"
+                                            "libGLESv2.so:"
+                                            "libGLESv3.so:"
+                                            "libjnigraphics.so:"
+                                            "liblog.so:"
+                                            "libmediandk.so:"
+                                            "libm.so:"
+                                            "libOpenMAXAL.so:"
+                                            "libOpenSLES.so:"
+                                            "libstdc++.so:"
+                                            "libz.so";
+
+class LibraryNamespaces {
+ public:
+  LibraryNamespaces() : initialized_(false) { }
+
+  android_namespace_t* GetOrCreate(JNIEnv* env, jobject class_loader, jstring library_path) {
+    ScopedUtfChars libraryPath(env, library_path);
+
+    if (!initialized_ && !InitPublicNamespace(libraryPath.c_str())) {
+      return nullptr;
+    }
+
+    std::lock_guard<std::mutex> guard(mutex_);
+
+    auto it = FindNamespaceByClassLoader(env, class_loader);
+
+    if (it != namespaces_.end()) {
+      return it->second;
+    }
+
+    android_namespace_t* ns =
+            android_create_namespace("classloader-namespace",
+                                     nullptr,
+                                     libraryPath.c_str(),
+                                     true);
+
+    namespaces_.push_back(std::make_pair(env->NewWeakGlobalRef(class_loader), ns));
+
+    return ns;
+  }
+
+ private:
+  bool InitPublicNamespace(const char* library_path) {
+    // Make sure all the public libraries are loaded
+    std::vector<std::string> sonames = android::base::Split(kPublicNativeLibraries, ":");
+    for (const auto& soname : sonames) {
+      if (dlopen(soname.c_str(), RTLD_NOW | RTLD_NODELETE) == nullptr) {
+        return false;
+      }
+    }
+
+    // Some apps call dlopen from generated code unknown to linker in which
+    // case linker uses anonymous namespace. See b/25844435 for details.
+    initialized_ = android_init_namespaces(kPublicNativeLibraries, library_path);
+
+    return initialized_;
+  }
+
+  std::vector<std::pair<jweak, android_namespace_t*>>::const_iterator
+  FindNamespaceByClassLoader(JNIEnv* env, jobject class_loader) {
+    return std::find_if(namespaces_.begin(), namespaces_.end(),
+            [&](const std::pair<jweak, android_namespace_t*>& value) {
+              return env->IsSameObject(value.first, class_loader);
+            });
+  }
+
+  bool initialized_;
+  std::mutex mutex_;
+  std::vector<std::pair<jweak, android_namespace_t*>> namespaces_;
+
+  DISALLOW_COPY_AND_ASSIGN(LibraryNamespaces);
+};
+
+static LibraryNamespaces* g_namespaces = new LibraryNamespaces;
+#endif
+
+
+void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path,
+                        jobject class_loader, jstring library_path) {
+#if defined(__ANDROID__)
+  if (target_sdk_version == 0 || class_loader == nullptr) {
+    return dlopen(path, RTLD_NOW);
+  }
+
+  android_namespace_t* ns = g_namespaces->GetOrCreate(env, class_loader, library_path);
+
+  if (ns == nullptr) {
+    return nullptr;
+  }
+
+  android_dlextinfo extinfo;
+  extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
+  extinfo.library_namespace = ns;
+
+  return android_dlopen_ext(path, RTLD_NOW, &extinfo);
+#else
+  UNUSED(env, target_sdk_version, class_loader, library_path);
+  return dlopen(path, RTLD_NOW);
+#endif
+}
+
+}; //  android namespace
diff --git a/libsysutils/src/SocketListener.cpp b/libsysutils/src/SocketListener.cpp
index 3011ed7..168899c 100644
--- a/libsysutils/src/SocketListener.cpp
+++ b/libsysutils/src/SocketListener.cpp
@@ -199,13 +199,14 @@
             continue;
         }
         if (mListen && FD_ISSET(mSock, &read_fds)) {
-            struct sockaddr addr;
+            sockaddr_storage ss;
+            sockaddr* addrp = reinterpret_cast<sockaddr*>(&ss);
             socklen_t alen;
             int c;
 
             do {
-                alen = sizeof(addr);
-                c = accept(mSock, &addr, &alen);
+                alen = sizeof(ss);
+                c = accept(mSock, addrp, &alen);
                 SLOGV("%s got %d from accept", mSocketName, c);
             } while (c < 0 && errno == EINTR);
             if (c < 0) {
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index 7bbc811..50bf6a4 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -410,7 +410,8 @@
 }
 
 static void ctrl_connect_handler(uint32_t events __unused) {
-    struct sockaddr addr;
+    struct sockaddr_storage ss;
+    struct sockaddr *addrp = (struct sockaddr *)&ss;
     socklen_t alen;
     struct epoll_event epev;
 
@@ -419,8 +420,8 @@
         ctrl_dfd_reopened = 1;
     }
 
-    alen = sizeof(addr);
-    ctrl_dfd = accept(ctrl_lfd, &addr, &alen);
+    alen = sizeof(ss);
+    ctrl_dfd = accept(ctrl_lfd, addrp, &alen);
 
     if (ctrl_dfd < 0) {
         ALOGE("lmkd control socket accept failed; errno=%d", errno);
diff --git a/rootdir/init.rc b/rootdir/init.rc
index a0b1acf..e4a34dc 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -244,6 +244,9 @@
     # Mount default storage into root namespace
     mount none /mnt/runtime/default /storage slave bind rec
 
+    # Make sure /sys/kernel/debug (if present) is labeled properly
+    restorecon_recursive /sys/kernel/debug
+
     # We chown/chmod /cache again so because mount is run as root + defaults
     chown system cache /cache
     chmod 0770 /cache