Merge "Executable to run on boot that removes old tzdata if needed"
diff --git a/base/include/base/memory.h b/base/include/base/memory.h
new file mode 100644
index 0000000..882582f
--- /dev/null
+++ b/base/include/base/memory.h
@@ -0,0 +1,47 @@
+/*
+ * 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 BASE_MEMORY_H
+#define BASE_MEMORY_H
+
+namespace android {
+namespace base {
+
+// Use packed structures for access to unaligned data on targets with alignment
+// restrictions.  The compiler will generate appropriate code to access these
+// structures without generating alignment exceptions.
+template <typename T>
+static inline T get_unaligned(const T* address) {
+  struct unaligned {
+    T v;
+  } __attribute__((packed));
+  const unaligned* p = reinterpret_cast<const unaligned*>(address);
+  return p->v;
+}
+
+template <typename T>
+static inline void put_unaligned(T* address, T v) {
+  struct unaligned {
+    T v;
+  } __attribute__((packed));
+  unaligned* p = reinterpret_cast<unaligned*>(address);
+  p->v = v;
+}
+
+} // namespace base
+} // namespace android
+
+#endif // BASE_MEMORY_H
diff --git a/fs_mgr/Android.mk b/fs_mgr/Android.mk
index 1179eaa..08d0671 100644
--- a/fs_mgr/Android.mk
+++ b/fs_mgr/Android.mk
@@ -8,8 +8,8 @@
 LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
 
 LOCAL_MODULE:= libfs_mgr
-LOCAL_STATIC_LIBRARIES := liblogwrap libmincrypt libext4_utils_static
-LOCAL_C_INCLUDES += system/extras/ext4_utils
+LOCAL_STATIC_LIBRARIES := liblogwrap libmincrypt libext4_utils_static libsquashfs_utils
+LOCAL_C_INCLUDES += system/extras/ext4_utils system/extras/squashfs_utils
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 LOCAL_CFLAGS := -Werror
 
@@ -34,7 +34,7 @@
 LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)/sbin
 LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED)
 
-LOCAL_STATIC_LIBRARIES := libfs_mgr liblogwrap libcutils liblog libc libmincrypt libext4_utils_static
+LOCAL_STATIC_LIBRARIES := libfs_mgr liblogwrap libcutils liblog libc libmincrypt libext4_utils_static libsquashfs_utils
 LOCAL_CXX_STL := libc++_static
 
 LOCAL_CFLAGS := -Werror
diff --git a/fs_mgr/fs_mgr_verity.c b/fs_mgr/fs_mgr_verity.c
index c55a49f..6ef46ba 100644
--- a/fs_mgr/fs_mgr_verity.c
+++ b/fs_mgr/fs_mgr_verity.c
@@ -38,6 +38,7 @@
 #include "mincrypt/sha256.h"
 
 #include "ext4_sb.h"
+#include "squashfs_utils.h"
 
 #include "fs_mgr_priv.h"
 #include "fs_mgr_priv_verity.h"
@@ -140,7 +141,19 @@
     return retval;
 }
 
-static int get_target_device_size(char *blk_device, uint64_t *device_size)
+static int squashfs_get_target_device_size(char *blk_device, uint64_t *device_size)
+{
+    struct squashfs_info sq_info;
+
+    if (squashfs_parse_sb(blk_device, &sq_info) >= 0) {
+        *device_size = sq_info.bytes_used_4K_padded;
+        return 0;
+    } else {
+        return -1;
+    }
+}
+
+static int ext4_get_target_device_size(char *blk_device, uint64_t *device_size)
 {
     int data_device;
     struct ext4_super_block sb;
@@ -173,11 +186,29 @@
     return 0;
 }
 
-static int read_verity_metadata(char *block_device, char **signature, char **table)
+static int get_fs_size(char *fs_type, char *blk_device, uint64_t *device_size) {
+    if (!strcmp(fs_type, "ext4")) {
+        if (ext4_get_target_device_size(blk_device, device_size) < 0) {
+            ERROR("Failed to get ext4 fs size on %s.", blk_device);
+            return -1;
+        }
+    } else if (!strcmp(fs_type, "squashfs")) {
+        if (squashfs_get_target_device_size(blk_device, device_size) < 0) {
+            ERROR("Failed to get squashfs fs size on %s.", blk_device);
+            return -1;
+        }
+    } else {
+        ERROR("%s: Unsupported filesystem for verity.", fs_type);
+        return -1;
+    }
+    return 0;
+}
+
+static int read_verity_metadata(uint64_t device_size, char *block_device, char **signature,
+        char **table)
 {
     unsigned magic_number;
     unsigned table_length;
-    uint64_t device_length;
     int protocol_version;
     int device;
     int retval = FS_MGR_SETUP_VERITY_FAIL;
@@ -194,12 +225,7 @@
         goto out;
     }
 
-    // find the start of the verity metadata
-    if (get_target_device_size(block_device, &device_length) < 0) {
-        ERROR("Could not get target device size.\n");
-        goto out;
-    }
-    if (TEMP_FAILURE_RETRY(lseek64(device, device_length, SEEK_SET)) < 0) {
+    if (TEMP_FAILURE_RETRY(lseek64(device, device_size, SEEK_SET)) < 0) {
         ERROR("Could not seek to start of verity metadata block.\n");
         goto out;
     }
@@ -220,8 +246,7 @@
 #endif
 
     if (magic_number != VERITY_METADATA_MAGIC_NUMBER) {
-        ERROR("Couldn't find verity metadata at offset %"PRIu64"!\n",
-              device_length);
+        ERROR("Couldn't find verity metadata at offset %"PRIu64"!\n", device_size);
         goto out;
     }
 
@@ -330,17 +355,12 @@
     return 0;
 }
 
-static int load_verity_table(struct dm_ioctl *io, char *name, char *blockdev, int fd, char *table,
+static int load_verity_table(struct dm_ioctl *io, char *name, uint64_t device_size, int fd, char *table,
         int mode)
 {
     char *verity_params;
     char *buffer = (char*) io;
     size_t bufsize;
-    uint64_t device_size = 0;
-
-    if (get_target_device_size(blockdev, &device_size) < 0) {
-        return -1;
-    }
 
     verity_ioctl_init(io, name, DM_STATUS_TABLE_FLAG);
 
@@ -665,10 +685,17 @@
     uint8_t curr[SHA256_DIGEST_SIZE];
     uint8_t prev[SHA256_DIGEST_SIZE];
     off64_t offset = 0;
+    uint64_t device_size;
 
     *match = 1;
 
-    if (read_verity_metadata(fstab->blk_device, &signature, NULL) < 0) {
+    // get verity filesystem size
+    if (get_fs_size(fstab->fs_type, fstab->blk_device, &device_size) < 0) {
+        ERROR("Failed to get filesystem size\n");
+        goto out;
+    }
+
+    if (read_verity_metadata(device_size, fstab->blk_device, &signature, NULL) < 0) {
         ERROR("Failed to read verity signature from %s\n", fstab->mount_point);
         goto out;
     }
@@ -901,6 +928,7 @@
     char *verity_blk_name = 0;
     char *verity_table = 0;
     char *verity_table_signature = 0;
+    uint64_t device_size = 0;
 
     _Alignas(struct dm_ioctl) char buffer[DM_BUF_SIZE];
     struct dm_ioctl *io = (struct dm_ioctl *) buffer;
@@ -910,16 +938,15 @@
     io->flags |= 1;
     io->target_count = 1;
 
-    // check to ensure that the verity device is ext4
-    // TODO: support non-ext4 filesystems
-    if (strcmp(fstab->fs_type, "ext4")) {
-        ERROR("Cannot verify non-ext4 device (%s)", fstab->fs_type);
+    // get verity filesystem size
+    if (get_fs_size(fstab->fs_type, fstab->blk_device, &device_size) < 0) {
         return retval;
     }
 
     // read the verity block at the end of the block device
     // send error code up the chain so we can detect attempts to disable verity
-    retval = read_verity_metadata(fstab->blk_device,
+    retval = read_verity_metadata(device_size,
+                                  fstab->blk_device,
                                   &verity_table_signature,
                                   &verity_table);
     if (retval < 0) {
@@ -964,7 +991,7 @@
     INFO("Enabling dm-verity for %s (mode %d)\n",  mount_point, mode);
 
     // load the verity mapping table
-    if (load_verity_table(io, mount_point, fstab->blk_device, fd, verity_table,
+    if (load_verity_table(io, mount_point, device_size, fd, verity_table,
             mode) < 0) {
         goto out;
     }
diff --git a/include/log/log.h b/include/log/log.h
index 99015db..ce253e2 100644
--- a/include/log/log.h
+++ b/include/log/log.h
@@ -67,6 +67,23 @@
 
 // ---------------------------------------------------------------------
 
+#ifndef __predict_false
+#define __predict_false(exp) __builtin_expect((exp) != 0, 0)
+#endif
+
+/*
+ *      -DLINT_RLOG in sources that you want to enforce that all logging
+ * goes to the radio log buffer. If any logging goes to any of the other
+ * log buffers, there will be a compile or link error to highlight the
+ * problem. This is not a replacement for a full audit of the code since
+ * this only catches compiled code, not ifdef'd debug code. Options to
+ * defining this, either temporarily to do a spot check, or permanently
+ * to enforce, in all the communications trees; We have hopes to ensure
+ * that by supplying just the radio log buffer that the communications
+ * teams will have their one-stop shop for triaging issues.
+ */
+#ifndef LINT_RLOG
+
 /*
  * Simplified macro to send a verbose log message using the current LOG_TAG.
  */
@@ -79,10 +96,6 @@
 #endif
 #endif
 
-#ifndef __predict_false
-#define __predict_false(exp) __builtin_expect((exp) != 0, 0)
-#endif
-
 #ifndef ALOGV_IF
 #if LOG_NDEBUG
 #define ALOGV_IF(cond, ...)   ((void)0)
@@ -283,6 +296,8 @@
     : (void)0 )
 #endif
 
+#endif /* !LINT_RLOG */
+
 // ---------------------------------------------------------------------
 
 /*
@@ -567,11 +582,15 @@
 typedef enum log_id {
     LOG_ID_MIN = 0,
 
+#ifndef LINT_RLOG
     LOG_ID_MAIN = 0,
+#endif
     LOG_ID_RADIO = 1,
+#ifndef LINT_RLOG
     LOG_ID_EVENTS = 2,
     LOG_ID_SYSTEM = 3,
     LOG_ID_CRASH = 4,
+#endif
 
     LOG_ID_MAX
 } log_id_t;
diff --git a/init/Android.mk b/init/Android.mk
index 9d91a3f..4bd4f3d 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -58,6 +58,7 @@
 LOCAL_STATIC_LIBRARIES := \
     libinit \
     libfs_mgr \
+    libsquashfs_utils \
     liblogwrap \
     libcutils \
     libbase \
diff --git a/libziparchive/Android.mk b/libziparchive/Android.mk
index 0d31001..a3087ee 100644
--- a/libziparchive/Android.mk
+++ b/libziparchive/Android.mk
@@ -21,7 +21,7 @@
 LOCAL_CPP_EXTENSION := .cc
 LOCAL_SRC_FILES := ${source_files}
 LOCAL_STATIC_LIBRARIES := libz
-LOCAL_SHARED_LIBRARIES := libutils
+LOCAL_SHARED_LIBRARIES := libutils libbase
 LOCAL_MODULE:= libziparchive
 LOCAL_CFLAGS := -Werror -Wall
 LOCAL_CPPFLAGS := -Wold-style-cast
@@ -30,7 +30,7 @@
 include $(CLEAR_VARS)
 LOCAL_CPP_EXTENSION := .cc
 LOCAL_SRC_FILES := ${source_files}
-LOCAL_STATIC_LIBRARIES := libz libutils
+LOCAL_STATIC_LIBRARIES := libz libutils libbase
 LOCAL_MODULE:= libziparchive-host
 LOCAL_CFLAGS := -Werror
 ifneq ($(strip $(USE_MINGW)),)
@@ -43,7 +43,7 @@
 LOCAL_CPP_EXTENSION := .cc
 LOCAL_SRC_FILES := ${source_files}
 LOCAL_STATIC_LIBRARIES := libz libutils
-LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_SHARED_LIBRARIES := liblog libbase
 LOCAL_MODULE:= libziparchive-host
 LOCAL_CFLAGS := -Werror
 LOCAL_MULTILIB := both
@@ -55,7 +55,7 @@
 LOCAL_CPP_EXTENSION := .cc
 LOCAL_CFLAGS := -Werror
 LOCAL_SRC_FILES := zip_archive_test.cc entry_name_utils_test.cc
-LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_SHARED_LIBRARIES := liblog libbase
 LOCAL_STATIC_LIBRARIES := libziparchive libz libutils
 include $(BUILD_NATIVE_TEST)
 
@@ -66,7 +66,7 @@
     -Werror \
     -Wno-unnamed-type-template-args
 LOCAL_SRC_FILES := zip_archive_test.cc entry_name_utils_test.cc
-LOCAL_SHARED_LIBRARIES := libziparchive-host liblog
+LOCAL_SHARED_LIBRARIES := libziparchive-host liblog libbase
 LOCAL_STATIC_LIBRARIES := \
     libz \
     libutils
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index 58285f1..57c46a3 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -18,27 +18,29 @@
  * Read-only access to Zip archives, with minimal heap allocation.
  */
 
-#include <memory>
-#include <vector>
-
 #include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <inttypes.h>
 #include <limits.h>
-#include <log/log.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <utils/Compat.h>
-#include <utils/FileMap.h>
-#include <zlib.h>
 
-#include <JNIHelp.h>  // TEMP_FAILURE_RETRY may or may not be in unistd
+#include <memory>
+#include <vector>
+
+#include "base/macros.h"  // TEMP_FAILURE_RETRY may or may not be in unistd
+#include "base/memory.h"
+#include "log/log.h"
+#include "utils/Compat.h"
+#include "utils/FileMap.h"
+#include "zlib.h"
 
 #include "entry_name_utils-inl.h"
 #include "ziparchive/zip_archive.h"
 
+using android::base::get_unaligned;
 
 // This is for windows. If we don't open a file in binary mode, weird
 // things will happen.
@@ -46,11 +48,6 @@
 #define O_BINARY 0
 #endif
 
-#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
-    TypeName(); \
-    TypeName(const TypeName&); \
-    void operator=(const TypeName&)
-
 // The "end of central directory" (EOCD) record. Each archive
 // contains exactly once such record which appears at the end of
 // the archive. It contains archive wide information like the
@@ -462,10 +459,12 @@
    */
   int i = read_amount - sizeof(EocdRecord);
   for (; i >= 0; i--) {
-    if (scan_buffer[i] == 0x50 &&
-        ((*reinterpret_cast<uint32_t*>(&scan_buffer[i])) == EocdRecord::kSignature)) {
-      ALOGV("+++ Found EOCD at buf+%d", i);
-      break;
+    if (scan_buffer[i] == 0x50) {
+      uint32_t* sig_addr = reinterpret_cast<uint32_t*>(&scan_buffer[i]);
+      if (get_unaligned<uint32_t>(sig_addr) == EocdRecord::kSignature) {
+        ALOGV("+++ Found EOCD at buf+%d", i);
+        break;
+      }
     }
   }
   if (i < 0) {