Merge "bootstat: Record metrics for factory_reset and time_since_factory_reset."
diff --git a/include/utils/String16.h b/include/utils/String16.h
index 9a67c7a..50ac6d0 100644
--- a/include/utils/String16.h
+++ b/include/utils/String16.h
@@ -62,9 +62,9 @@
     explicit                    String16(const char* o, size_t len);
 
                                 ~String16();
-    
+
     inline  const char16_t*     string() const;
-    
+
             size_t              size() const;
             void                setTo(const String16& other);
             status_t            setTo(const char16_t* other);
@@ -72,12 +72,12 @@
             status_t            setTo(const String16& other,
                                       size_t len,
                                       size_t begin=0);
-    
+
             status_t            append(const String16& other);
             status_t            append(const char16_t* other, size_t len);
-            
+
     inline  String16&           operator=(const String16& other);
-    
+
     inline  String16&           operator+=(const String16& other);
     inline  String16            operator+(const String16& other) const;
 
@@ -90,7 +90,7 @@
 
             bool                startsWith(const String16& prefix) const;
             bool                startsWith(const char16_t* prefix) const;
-            
+
             status_t            makeLower();
 
             status_t            replaceAll(char16_t replaceThis,
@@ -106,16 +106,16 @@
     inline  bool                operator!=(const String16& other) const;
     inline  bool                operator>=(const String16& other) const;
     inline  bool                operator>(const String16& other) const;
-    
+
     inline  bool                operator<(const char16_t* other) const;
     inline  bool                operator<=(const char16_t* other) const;
     inline  bool                operator==(const char16_t* other) const;
     inline  bool                operator!=(const char16_t* other) const;
     inline  bool                operator>=(const char16_t* other) const;
     inline  bool                operator>(const char16_t* other) const;
-    
+
     inline                      operator const char16_t*() const;
-    
+
 private:
             const char16_t*     mString;
 };
diff --git a/liblog/fake_log_device.c b/liblog/fake_log_device.c
index 5f7a078..a6d9a348 100644
--- a/liblog/fake_log_device.c
+++ b/liblog/fake_log_device.c
@@ -689,6 +689,17 @@
     return redirectOpen(pathName, flags);
 }
 
+/*
+ * The logger API has no means or need to 'stop' or 'close' using the logs,
+ * and as such, there is no way for that 'stop' or 'close' to translate into
+ * a close operation to the fake log handler. fakeLogClose is provided for
+ * completeness only.
+ *
+ * We have no intention of adding a log close operation as it would complicate
+ * every user of the logging API with no gain since the only valid place to
+ * call is in the exit handler. Logging can continue in the exit handler to
+ * help debug HOST tools ...
+ */
 int fakeLogClose(int fd)
 {
     /* Assume that open() was called first. */
diff --git a/libmemtrack/include/memtrack/memtrack.h b/libmemtrack/include/memtrack/memtrack.h
index 3917300..8c0ab89 100644
--- a/libmemtrack/include/memtrack/memtrack.h
+++ b/libmemtrack/include/memtrack/memtrack.h
@@ -19,7 +19,6 @@
 
 #include <sys/types.h>
 #include <stddef.h>
-#include <cutils/compiler.h>
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/libnetutils/Android.mk b/libnetutils/Android.mk
index 2060df4..281b6c8 100644
--- a/libnetutils/Android.mk
+++ b/libnetutils/Android.mk
@@ -16,6 +16,9 @@
 
 LOCAL_CFLAGS := -Werror
 
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+
 include $(BUILD_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
diff --git a/include/netutils/dhcp.h b/libnetutils/include/netutils/dhcp.h
similarity index 100%
rename from include/netutils/dhcp.h
rename to libnetutils/include/netutils/dhcp.h
diff --git a/include/netutils/ifc.h b/libnetutils/include/netutils/ifc.h
similarity index 100%
rename from include/netutils/ifc.h
rename to libnetutils/include/netutils/ifc.h
diff --git a/libutils/String16.cpp b/libutils/String16.cpp
index 6a5273f..449fb20 100644
--- a/libutils/String16.cpp
+++ b/libutils/String16.cpp
@@ -77,7 +77,7 @@
         //printf("Created UTF-16 string from UTF-8 \"%s\":", in);
         //printHexData(1, str, buf->size(), 16, 1);
         //printf("\n");
-        
+
         return u16str;
     }
 
@@ -127,7 +127,7 @@
         mString = str;
         return;
     }
-    
+
     mString = getEmptyString();
 }
 
@@ -142,7 +142,7 @@
         mString = str;
         return;
     }
-    
+
     mString = getEmptyString();
 }
 
@@ -228,7 +228,7 @@
     } else if (otherLen == 0) {
         return NO_ERROR;
     }
-    
+
     SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
         ->editResize((myLen+otherLen+1)*sizeof(char16_t));
     if (buf) {
@@ -249,7 +249,7 @@
     } else if (otherLen == 0) {
         return NO_ERROR;
     }
-    
+
     SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
         ->editResize((myLen+otherLen+1)*sizeof(char16_t));
     if (buf) {
diff --git a/logd/Android.mk b/logd/Android.mk
index feca8d5..203943c 100644
--- a/logd/Android.mk
+++ b/logd/Android.mk
@@ -42,6 +42,10 @@
 
 LOCAL_CFLAGS := -Werror $(event_flag)
 
+ifeq ($(TARGET_BUILD_VARIANT),user)
+LOCAL_CFLAGS += -DAUDITD_ENFORCE_INTEGRITY=true
+endif
+
 include $(BUILD_EXECUTABLE)
 
 include $(call first-makefiles-under,$(LOCAL_PATH))
diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp
index 143fb04..fffc9ba 100644
--- a/logd/LogAudit.cpp
+++ b/logd/LogAudit.cpp
@@ -24,6 +24,7 @@
 #include <sys/uio.h>
 #include <syslog.h>
 
+#include <cutils/properties.h>
 #include <log/logger.h>
 #include <private/android_filesystem_config.h>
 #include <private/android_logger.h>
@@ -32,6 +33,10 @@
 #include "LogAudit.h"
 #include "LogKlog.h"
 
+#ifndef AUDITD_ENFORCE_INTEGRITY
+#define AUDITD_ENFORCE_INTEGRITY false
+#endif
+
 #define KMSG_PRIORITY(PRI)                          \
     '<',                                            \
     '0' + LOG_MAKEPRI(LOG_AUTH, LOG_PRI(PRI)) / 10, \
@@ -43,11 +48,10 @@
         logbuf(buf),
         reader(reader),
         fdDmesg(fdDmesg),
+        policyLoaded(false),
+        rebootToSafeMode(false),
         initialized(false) {
-    static const char auditd_message[] = { KMSG_PRIORITY(LOG_INFO),
-        'l', 'o', 'g', 'd', '.', 'a', 'u', 'd', 'i', 't', 'd', ':',
-        ' ', 's', 't', 'a', 'r', 't', '\n' };
-    write(fdDmesg, auditd_message, sizeof(auditd_message));
+    logToDmesg("start");
 }
 
 bool LogAudit::onDataAvailable(SocketClient *cli) {
@@ -73,6 +77,46 @@
     return true;
 }
 
+void LogAudit::logToDmesg(const std::string& str)
+{
+    static const char prefix[] = { KMSG_PRIORITY(LOG_INFO),
+        'l', 'o', 'g', 'd', '.', 'a', 'u', 'd', 'i', 't', 'd', ':',
+        ' ', '\0' };
+    std::string message = prefix + str + "\n";
+    write(fdDmesg, message.c_str(), message.length());
+}
+
+std::string LogAudit::getProperty(const std::string& name)
+{
+    char value[PROP_VALUE_MAX] = {0};
+    property_get(name.c_str(), value, "");
+    return value;
+}
+
+void LogAudit::enforceIntegrity() {
+    if (!AUDITD_ENFORCE_INTEGRITY) {
+        logToDmesg("integrity enforcement suppressed; not rebooting");
+    } else if (rebootToSafeMode) {
+        if (getProperty("persist.sys.safemode") == "1") {
+            logToDmesg("integrity enforcement suppressed; in safe mode");
+            return;
+        }
+
+        logToDmesg("enforcing integrity; rebooting to safe mode");
+        property_set("persist.sys.safemode", "1");
+
+        std::string buildDate = getProperty("ro.build.date.utc");
+        if (!buildDate.empty()) {
+            property_set("persist.sys.audit_safemode", buildDate.c_str());
+        }
+
+        property_set("sys.powerctl", "reboot");
+    } else {
+        logToDmesg("enforcing integrity: rebooting to recovery");
+        property_set("sys.powerctl", "reboot,recovery");
+    }
+}
+
 int LogAudit::logPrint(const char *fmt, ...) {
     if (fmt == NULL) {
         return -EINVAL;
@@ -94,7 +138,27 @@
         memmove(cp, cp + 1, strlen(cp + 1) + 1);
     }
 
-    bool info = strstr(str, " permissive=1") || strstr(str, " policy loaded ");
+    bool loaded = strstr(str, " policy loaded ");
+
+    if (loaded) {
+        if (policyLoaded) {
+            // SELinux policy changes are not allowed
+            enforceIntegrity();
+        } else {
+            logToDmesg("policy loaded");
+            policyLoaded = true;
+        }
+    }
+
+    bool permissive = strstr(str, " enforcing=0") ||
+                      strstr(str, " permissive=1");
+
+    if (permissive) {
+        // SELinux in permissive mode is not allowed
+        enforceIntegrity();
+    }
+
+    bool info = loaded || permissive;
     if ((fdDmesg >= 0) && initialized) {
         struct iovec iov[3];
         static const char log_info[] = { KMSG_PRIORITY(LOG_INFO) };
diff --git a/logd/LogAudit.h b/logd/LogAudit.h
index 8a82630..455ed58 100644
--- a/logd/LogAudit.h
+++ b/logd/LogAudit.h
@@ -24,12 +24,15 @@
     LogBuffer *logbuf;
     LogReader *reader;
     int fdDmesg;
+    bool policyLoaded;
+    bool rebootToSafeMode;
     bool initialized;
 
 public:
     LogAudit(LogBuffer *buf, LogReader *reader, int fdDmesg);
     int log(char *buf, size_t len);
     bool isMonotonic() { return logbuf->isMonotonic(); }
+    void allowSafeMode(bool allow = true) { rebootToSafeMode = allow; }
 
 protected:
     virtual bool onDataAvailable(SocketClient *cli);
@@ -38,6 +41,9 @@
     static int getLogSocket();
     int logPrint(const char *fmt, ...)
         __attribute__ ((__format__ (__printf__, 2, 3)));
+    void logToDmesg(const std::string& str);
+    std::string getProperty(const std::string& name);
+    void enforceIntegrity();
 };
 
 #endif
diff --git a/logd/README.property b/logd/README.property
index 6200d3e..4bc5541 100644
--- a/logd/README.property
+++ b/logd/README.property
@@ -1,7 +1,6 @@
 The properties that logd responds to are:
 
 name                       type default  description
-ro.logd.auditd             bool   true   Enable selinux audit daemon
 ro.logd.auditd.dmesg       bool   true   selinux audit messages duplicated and
                                          sent on to dmesg log
 persist.logd.security      bool   false  Enable security buffer.
diff --git a/logd/main.cpp b/logd/main.cpp
index bef40c7..f4d7464 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -245,6 +245,7 @@
 static sem_t reinit;
 static bool reinit_running = false;
 static LogBuffer *logBuf = NULL;
+static LogAudit *logAudit = NULL;
 
 static bool package_list_parser_cb(pkg_info *info, void * /* userdata */) {
 
@@ -292,6 +293,10 @@
             logBuf->init();
             logBuf->initPrune(NULL);
         }
+
+        if (logAudit) {
+            logAudit->allowSafeMode();
+        }
     }
 
     return NULL;
@@ -512,25 +517,19 @@
     // initiated log messages. New log entries are added to LogBuffer
     // and LogReader is notified to send updates to connected clients.
 
-    bool auditd = property_get_bool("logd.auditd",
-                                    BOOL_DEFAULT_TRUE |
-                                    BOOL_DEFAULT_FLAG_PERSIST);
-    LogAudit *al = NULL;
-    if (auditd) {
-        al = new LogAudit(logBuf, reader,
-                          property_get_bool("logd.auditd.dmesg",
-                                            BOOL_DEFAULT_TRUE |
-                                            BOOL_DEFAULT_FLAG_PERSIST)
-                              ? fdDmesg
-                              : -1);
-    }
+    logAudit = new LogAudit(logBuf, reader,
+                            property_get_bool("logd.auditd.dmesg",
+                                              BOOL_DEFAULT_TRUE |
+                                              BOOL_DEFAULT_FLAG_PERSIST)
+                                ? fdDmesg
+                                : -1);
 
     LogKlog *kl = NULL;
     if (klogd) {
-        kl = new LogKlog(logBuf, reader, fdDmesg, fdPmesg, al != NULL);
+        kl = new LogKlog(logBuf, reader, fdDmesg, fdPmesg, logAudit != NULL);
     }
 
-    readDmesg(al, kl);
+    readDmesg(logAudit, kl);
 
     // failure is an option ... messages are in dmesg (required by standard)
 
@@ -538,8 +537,9 @@
         delete kl;
     }
 
-    if (al && al->startListener()) {
-        delete al;
+    if (logAudit && logAudit->startListener()) {
+        delete logAudit;
+        logAudit = NULL;
     }
 
     TEMP_FAILURE_RETRY(pause());
diff --git a/metricsd/.clang-format b/metricsd/.clang-format
deleted file mode 100644
index c98efc2..0000000
--- a/metricsd/.clang-format
+++ /dev/null
@@ -1,10 +0,0 @@
-BasedOnStyle: Google
-AllowShortFunctionsOnASingleLine: Inline
-AllowShortIfStatementsOnASingleLine: false
-AllowShortLoopsOnASingleLine: false
-BinPackArguments: false
-BinPackParameters: false
-CommentPragmas: NOLINT:.*
-DerivePointerAlignment: false
-PointerAlignment: Left
-TabWidth: 2
diff --git a/metricsd/.clang-format b/metricsd/.clang-format
new file mode 120000
index 0000000..f9066d4
--- /dev/null
+++ b/metricsd/.clang-format
@@ -0,0 +1 @@
+../../../build/tools/brillo-clang-format
\ No newline at end of file