Merge "Create a new directory on boot for update_engine logs"
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index faaad0c..8fb3a52 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -110,7 +110,7 @@
                 "klog.cpp",
                 "partition_utils.c",
                 "properties.cpp",
-                "qtaguid.c",
+                "qtaguid.cpp",
                 "trace-dev.c",
                 "uevent.cpp",
             ],
diff --git a/libcutils/include/cutils/qtaguid.h b/libcutils/include/cutils/qtaguid.h
index 803fe0d..3f5e41f 100644
--- a/libcutils/include/cutils/qtaguid.h
+++ b/libcutils/include/cutils/qtaguid.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2017 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.
@@ -17,18 +17,14 @@
 #ifndef __CUTILS_QTAGUID_H
 #define __CUTILS_QTAGUID_H
 
-#include <stdint.h>
 #include <sys/types.h>
-#include <unistd.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /*
- * Set tags (and owning UIDs) for network sockets. The socket must be untagged
- * by calling qtaguid_untagSocket() before closing it, otherwise the qtaguid
- * module will keep a reference to it even after close.
+ * Set tags (and owning UIDs) for network sockets.
  */
 extern int qtaguid_tagSocket(int sockfd, int tag, uid_t uid);
 
@@ -46,8 +42,8 @@
 
 /*
  * Delete all tag info that relates to the given tag an uid.
- * If the tag is 0, then ALL info about the uid is freeded.
- * The delete data also affects active tagged socketd, which are
+ * If the tag is 0, then ALL info about the uid is freed.
+ * The delete data also affects active tagged sockets, which are
  * then untagged.
  * The calling process can only operate on its own tags.
  * Unless it is part of the happy AID_NET_BW_ACCT group.
diff --git a/libcutils/qtaguid.cpp b/libcutils/qtaguid.cpp
new file mode 100644
index 0000000..86a5dc4
--- /dev/null
+++ b/libcutils/qtaguid.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+// #define LOG_NDEBUG 0
+
+#define LOG_TAG "qtaguid"
+
+#include <dlfcn.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <cutils/qtaguid.h>
+#include <log/log.h>
+
+class netdHandler {
+  public:
+    int (*netdTagSocket)(int, uint32_t, uid_t);
+    int (*netdUntagSocket)(int);
+    int (*netdSetCounterSet)(uint32_t, uid_t);
+    int (*netdDeleteTagData)(uint32_t, uid_t);
+};
+
+int dummyTagSocket(int, uint32_t, uid_t) {
+    return -EREMOTEIO;
+}
+
+int dummyUntagSocket(int) {
+    return -EREMOTEIO;
+}
+
+int dummySetCounterSet(uint32_t, uid_t) {
+    return -EREMOTEIO;
+}
+
+int dummyDeleteTagData(uint32_t, uid_t) {
+    return -EREMOTEIO;
+}
+
+netdHandler initHandler(void) {
+    netdHandler handler = {dummyTagSocket, dummyUntagSocket, dummySetCounterSet, dummyDeleteTagData};
+
+    void* netdClientHandle = dlopen("libnetd_client.so", RTLD_NOW);
+    if (!netdClientHandle) {
+        ALOGE("Failed to open libnetd_client.so: %s", dlerror());
+        return handler;
+    }
+
+    handler.netdTagSocket = (int (*)(int, uint32_t, uid_t))dlsym(netdClientHandle, "tagSocket");
+    if (!handler.netdTagSocket) {
+        ALOGE("load netdTagSocket handler failed: %s", dlerror());
+    }
+
+    handler.netdUntagSocket = (int (*)(int))dlsym(netdClientHandle, "untagSocket");
+    if (!handler.netdUntagSocket) {
+        ALOGE("load netdUntagSocket handler failed: %s", dlerror());
+    }
+
+    handler.netdSetCounterSet = (int (*)(uint32_t, uid_t))dlsym(netdClientHandle, "setCounterSet");
+    if (!handler.netdSetCounterSet) {
+        ALOGE("load netdSetCounterSet handler failed: %s", dlerror());
+    }
+
+    handler.netdDeleteTagData = (int (*)(uint32_t, uid_t))dlsym(netdClientHandle, "deleteTagData");
+    if (!handler.netdDeleteTagData) {
+        ALOGE("load netdDeleteTagData handler failed: %s", dlerror());
+    }
+    return handler;
+}
+
+// The language guarantees that this object will be initialized in a thread-safe way.
+static netdHandler& getHandler() {
+    static netdHandler instance = initHandler();
+    return instance;
+}
+
+int qtaguid_tagSocket(int sockfd, int tag, uid_t uid) {
+    // Check the socket fd passed to us is still valid before we load the netd
+    // client. Pass a already closed socket fd to netd client may let netd open
+    // the unix socket with the same fd number and pass it to server for
+    // tagging.
+    // TODO: move the check into netdTagSocket.
+    int res = fcntl(sockfd, F_GETFD);
+    if (res < 0) return res;
+
+    ALOGV("Tagging socket %d with tag %u for uid %d", sockfd, tag, uid);
+    return getHandler().netdTagSocket(sockfd, tag, uid);
+}
+
+int qtaguid_untagSocket(int sockfd) {
+    // Similiar to tag socket. We need a check before untag to make sure untag a closed socket fail
+    // as expected.
+    // TODO: move the check into netdTagSocket.
+    int res = fcntl(sockfd, F_GETFD);
+    if (res < 0) return res;
+
+    ALOGV("Untagging socket %d", sockfd);
+    return getHandler().netdUntagSocket(sockfd);
+}
+
+int qtaguid_setCounterSet(int counterSetNum, uid_t uid) {
+    ALOGV("Setting counters to set %d for uid %d", counterSetNum, uid);
+    return getHandler().netdSetCounterSet(counterSetNum, uid);
+}
+
+int qtaguid_deleteTagData(int tag, uid_t uid) {
+    ALOGV("Deleting tag data with tag %u for uid %d", tag, uid);
+    return getHandler().netdDeleteTagData(tag, uid);
+}
diff --git a/libqtaguid/Android.bp b/libqtaguid/Android.bp
new file mode 100644
index 0000000..de632ca
--- /dev/null
+++ b/libqtaguid/Android.bp
@@ -0,0 +1,56 @@
+//
+// Copyright (C) 2017 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.
+//
+
+cc_library_headers {
+    name: "libqtaguid_headers",
+    vendor_available: false,
+    host_supported: false,
+    export_include_dirs: ["include"],
+    target: {
+        linux_bionic: {
+            enabled: true,
+        },
+    },
+}
+
+cc_library {
+    name: "libqtaguid",
+    vendor_available: false,
+    host_supported: false,
+    target: {
+        android: {
+            srcs: [
+                "qtaguid.c",
+            ],
+            sanitize: {
+                misc_undefined: ["integer"],
+            },
+        },
+    },
+
+    shared_libs: ["liblog"],
+    header_libs: [
+        "libqtaguid_headers",
+    ],
+    export_header_lib_headers: ["libqtaguid_headers"],
+    local_include_dirs: ["include"],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+        "-Wextra",
+    ],
+}
diff --git a/libqtaguid/include/qtaguid/qtaguid.h b/libqtaguid/include/qtaguid/qtaguid.h
new file mode 100644
index 0000000..72285e5
--- /dev/null
+++ b/libqtaguid/include/qtaguid/qtaguid.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2011 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 __LEGACY_QTAGUID_H
+#define __LEGACY_QTAGUID_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Set tags (and owning UIDs) for network sockets. The socket must be untagged
+ * by calling qtaguid_untagSocket() before closing it, otherwise the qtaguid
+ * module will keep a reference to it even after close.
+ */
+extern int legacy_tagSocket(int sockfd, int tag, uid_t uid);
+
+/*
+ * Untag a network socket before closing.
+ */
+extern int legacy_untagSocket(int sockfd);
+
+/*
+ * For the given uid, switch counter sets.
+ * The kernel only keeps a limited number of sets.
+ * 2 for now.
+ */
+extern int legacy_setCounterSet(int counterSetNum, uid_t uid);
+
+/*
+ * Delete all tag info that relates to the given tag an uid.
+ * If the tag is 0, then ALL info about the uid is freeded.
+ * The delete data also affects active tagged socketd, which are
+ * then untagged.
+ * The calling process can only operate on its own tags.
+ * Unless it is part of the happy AID_NET_BW_ACCT group.
+ * In which case it can clobber everything.
+ */
+extern int legacy_deleteTagData(int tag, uid_t uid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LEGACY_QTAGUID_H */
diff --git a/libcutils/qtaguid.c b/libqtaguid/qtaguid.c
similarity index 72%
rename from libcutils/qtaguid.c
rename to libqtaguid/qtaguid.c
index 22b8325..cd38bad 100644
--- a/libcutils/qtaguid.c
+++ b/libqtaguid/qtaguid.c
@@ -27,12 +27,10 @@
 #include <unistd.h>
 
 #include <log/log.h>
-#include <cutils/qtaguid.h>
+#include <qtaguid/qtaguid.h>
 
 static const char* CTRL_PROCPATH = "/proc/net/xt_qtaguid/ctrl";
 static const int CTRL_MAX_INPUT_LEN = 128;
-static const char *GLOBAL_PACIFIER_PARAM = "/sys/module/xt_qtaguid/parameters/passive";
-static const char *TAG_PACIFIER_PARAM = "/sys/module/xt_qtaguid/parameters/tag_tracking_passive";
 
 /*
  * One per proccess.
@@ -46,7 +44,7 @@
 pthread_once_t resTrackInitDone = PTHREAD_ONCE_INIT;
 
 /* Only call once per process. */
-void qtaguid_resTrack(void) {
+void legacy_resTrack(void) {
     resTrackFd = TEMP_FAILURE_RETRY(open("/dev/xt_qtaguid", O_RDONLY | O_CLOEXEC));
 }
 
@@ -55,7 +53,7 @@
  *   0 on success.
  *   -errno on failure.
  */
-static int write_ctrl(const char *cmd) {
+static int write_ctrl(const char* cmd) {
     int fd, res, savedErrno;
 
     ALOGV("write_ctrl(%s)", cmd);
@@ -79,28 +77,12 @@
     return -savedErrno;
 }
 
-static int write_param(const char *param_path, const char *value) {
-    int param_fd;
-    int res;
-
-    param_fd = TEMP_FAILURE_RETRY(open(param_path, O_WRONLY | O_CLOEXEC));
-    if (param_fd < 0) {
-        return -errno;
-    }
-    res = TEMP_FAILURE_RETRY(write(param_fd, value, strlen(value)));
-    if (res < 0) {
-        return -errno;
-    }
-    close(param_fd);
-    return 0;
-}
-
-int qtaguid_tagSocket(int sockfd, int tag, uid_t uid) {
+int legacy_tagSocket(int sockfd, int tag, uid_t uid) {
     char lineBuf[CTRL_MAX_INPUT_LEN];
     int res;
     uint64_t kTag = ((uint64_t)tag << 32);
 
-    pthread_once(&resTrackInitDone, qtaguid_resTrack);
+    pthread_once(&resTrackInitDone, legacy_resTrack);
 
     snprintf(lineBuf, sizeof(lineBuf), "t %d %" PRIu64 " %d", sockfd, kTag, uid);
 
@@ -108,14 +90,14 @@
 
     res = write_ctrl(lineBuf);
     if (res < 0) {
-        ALOGI("Tagging socket %d with tag %" PRIx64 "(%d) for uid %d failed errno=%d",
-             sockfd, kTag, tag, uid, res);
+        ALOGI("Tagging socket %d with tag %" PRIx64 "(%d) for uid %d failed errno=%d", sockfd, kTag,
+              tag, uid, res);
     }
 
     return res;
 }
 
-int qtaguid_untagSocket(int sockfd) {
+int legacy_untagSocket(int sockfd) {
     char lineBuf[CTRL_MAX_INPUT_LEN];
     int res;
 
@@ -130,7 +112,7 @@
     return res;
 }
 
-int qtaguid_setCounterSet(int counterSetNum, uid_t uid) {
+int legacy_setCounterSet(int counterSetNum, uid_t uid) {
     char lineBuf[CTRL_MAX_INPUT_LEN];
     int res;
 
@@ -141,34 +123,21 @@
     return res;
 }
 
-int qtaguid_deleteTagData(int tag, uid_t uid) {
+int legacy_deleteTagData(int tag, uid_t uid) {
     char lineBuf[CTRL_MAX_INPUT_LEN];
     int cnt = 0, res = 0;
     uint64_t kTag = (uint64_t)tag << 32;
 
     ALOGV("Deleting tag data with tag %" PRIx64 "{%d,0} for uid %d", kTag, tag, uid);
 
-    pthread_once(&resTrackInitDone, qtaguid_resTrack);
+    pthread_once(&resTrackInitDone, legacy_resTrack);
 
     snprintf(lineBuf, sizeof(lineBuf), "d %" PRIu64 " %d", kTag, uid);
     res = write_ctrl(lineBuf);
     if (res < 0) {
         ALOGI("Deleting tag data with tag %" PRIx64 "/%d for uid %d failed with cnt=%d errno=%d",
-             kTag, tag, uid, cnt, errno);
+              kTag, tag, uid, cnt, errno);
     }
 
     return res;
 }
-
-int qtaguid_setPacifier(int on) {
-    const char *value;
-
-    value = on ? "Y" : "N";
-    if (write_param(GLOBAL_PACIFIER_PARAM, value) < 0) {
-        return -errno;
-    }
-    if (write_param(TAG_PACIFIER_PARAM, value) < 0) {
-        return -errno;
-    }
-    return 0;
-}
diff --git a/libvndksupport/linker.c b/libvndksupport/linker.c
index 696e978..d06cafc 100644
--- a/libvndksupport/linker.c
+++ b/libvndksupport/linker.c
@@ -23,24 +23,38 @@
 
 extern struct android_namespace_t* android_get_exported_namespace(const char*);
 
+static const char* namespace_name = NULL;
+
+static struct android_namespace_t* get_vendor_namespace() {
+    const char* namespace_names[] = {"sphal", "default", NULL};
+    static struct android_namespace_t* vendor_namespace = NULL;
+    if (vendor_namespace == NULL) {
+        int name_idx = 0;
+        while (namespace_names[name_idx] != NULL) {
+            vendor_namespace = android_get_exported_namespace(namespace_names[name_idx]);
+            if (vendor_namespace != NULL) {
+                namespace_name = namespace_names[name_idx];
+                break;
+            }
+            name_idx++;
+        }
+    }
+    return vendor_namespace;
+}
+
 void* android_load_sphal_library(const char* name, int flag) {
-    struct android_namespace_t* sphal_namespace = android_get_exported_namespace("sphal");
-    if (sphal_namespace != NULL) {
+    struct android_namespace_t* vendor_namespace = get_vendor_namespace();
+    if (vendor_namespace != NULL) {
         const android_dlextinfo dlextinfo = {
-            .flags = ANDROID_DLEXT_USE_NAMESPACE, .library_namespace = sphal_namespace,
+            .flags = ANDROID_DLEXT_USE_NAMESPACE, .library_namespace = vendor_namespace,
         };
         void* handle = android_dlopen_ext(name, flag, &dlextinfo);
         if (!handle) {
-            ALOGE(
-                "Could not load %s from sphal namespace: %s. ",
-                name, dlerror());
+            ALOGE("Could not load %s from %s namespace: %s.", name, namespace_name, dlerror());
         }
         return handle;
     } else {
-        ALOGI(
-            "sphal namespace is not configured for this process. "
-            "Loading %s from the current namespace instead.",
-            name);
+        ALOGD("Loading %s from current namespace instead of sphal namespace.", name);
         return dlopen(name, flag);
     }
 }