Merge "android_filesystem: Remove setuid bits from tcpdump" into lmp-mr1-dev
diff --git a/adb/get_my_path_darwin.c b/adb/get_my_path_darwin.c
index 5b95d15..ff1396c 100644
--- a/adb/get_my_path_darwin.c
+++ b/adb/get_my_path_darwin.c
@@ -19,12 +19,12 @@
 
 void get_my_path(char *s, size_t maxLen)
 {
-    ProcessSerialNumber psn;
-    GetCurrentProcess(&psn);
-    CFDictionaryRef dict;
-    dict = ProcessInformationCopyDictionary(&psn, 0xffffffff);
-    CFStringRef value = (CFStringRef)CFDictionaryGetValue(dict,
-                CFSTR("CFBundleExecutable"));
-    CFStringGetCString(value, s, maxLen, kCFStringEncodingUTF8);
+    CFBundleRef mainBundle = CFBundleGetMainBundle();
+    CFURLRef executableURL = CFBundleCopyExecutableURL(mainBundle);
+    CFStringRef executablePathString = CFURLCopyFileSystemPath(executableURL, kCFURLPOSIXPathStyle);
+    CFRelease(executableURL);
+
+    CFStringGetFileSystemRepresentation(executablePathString, s, maxLen);
+    CFRelease(executablePathString);
 }
 
diff --git a/fastboot/util_osx.c b/fastboot/util_osx.c
index 26b832a..e718562 100644
--- a/fastboot/util_osx.c
+++ b/fastboot/util_osx.c
@@ -31,14 +31,15 @@
 
 void get_my_path(char s[PATH_MAX])
 {
-    char *x;
-    ProcessSerialNumber psn;
-    GetCurrentProcess(&psn);
-    CFDictionaryRef dict;
-    dict = ProcessInformationCopyDictionary(&psn, 0xffffffff);
-    CFStringRef value = (CFStringRef)CFDictionaryGetValue(dict,
-                CFSTR("CFBundleExecutable"));
-    CFStringGetCString(value, s, PATH_MAX - 1, kCFStringEncodingUTF8);
+    CFBundleRef mainBundle = CFBundleGetMainBundle();
+    CFURLRef executableURL = CFBundleCopyExecutableURL(mainBundle);
+    CFStringRef executablePathString = CFURLCopyFileSystemPath(executableURL, kCFURLPOSIXPathStyle);
+    CFRelease(executableURL);
+
+    CFStringGetFileSystemRepresentation(executablePathString, s, PATH_MAX-1);
+    CFRelease(executablePathString);
+
+	char *x;
     x = strrchr(s, '/');
     if(x) x[1] = 0;
 }
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index d1e92f2..ad02922 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -256,6 +256,15 @@
     return strcmp(value, "0") ? 1 : 0;
 }
 
+static int device_is_force_encrypted() {
+    int ret = -1;
+    char value[PROP_VALUE_MAX];
+    ret = __system_property_get("ro.vold.forceencryption", value);
+    if (ret < 0)
+        return 0;
+    return strcmp(value, "1") ? 0 : 1;
+}
+
 /*
  * Tries to mount any of the consecutive fstab entries that match
  * the mountpoint of the one given by fstab->recs[start_idx].
@@ -378,7 +387,9 @@
         /* Deal with encryptability. */
         if (!mret) {
             /* If this is encryptable, need to trigger encryption */
-            if ((fstab->recs[attempted_idx].fs_mgr_flags & MF_FORCECRYPT)) {
+            if (   (fstab->recs[attempted_idx].fs_mgr_flags & MF_FORCECRYPT)
+                || (device_is_force_encrypted()
+                    && fs_mgr_is_encryptable(&fstab->recs[attempted_idx]))) {
                 if (umount(fstab->recs[attempted_idx].mount_point) == 0) {
                     if (encryptable == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
                         ERROR("Will try to encrypt %s %s\n", fstab->recs[attempted_idx].mount_point,
diff --git a/include/cutils/debugger.h b/include/cutils/debugger.h
index 4bcc8e6..bae687d 100644
--- a/include/cutils/debugger.h
+++ b/include/cutils/debugger.h
@@ -64,11 +64,26 @@
  */
 int dump_tombstone(pid_t tid, char* pathbuf, size_t pathlen);
 
+/* Dumps a process backtrace, registers, and stack to a tombstone file (requires root).
+ * Stores the tombstone path in the provided buffer.
+ * If reading debugger data from debuggerd ever takes longer than timeout_secs
+ * seconds, then stop and return an error.
+ * Returns 0 on success, -1 on error.
+ */
+int dump_tombstone_timeout(pid_t tid, char* pathbuf, size_t pathlen, int timeout_secs);
+
 /* Dumps a process backtrace only to the specified file (requires root).
  * Returns 0 on success, -1 on error.
  */
 int dump_backtrace_to_file(pid_t tid, int fd);
 
+/* Dumps a process backtrace only to the specified file (requires root).
+ * If reading debugger data from debuggerd ever takes longer than timeout_secs
+ * seconds, then stop and return an error.
+ * Returns 0 on success, -1 on error.
+ */
+int dump_backtrace_to_file_timeout(pid_t tid, int fd, int timeout_secs);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/init/util.c b/init/util.c
index 0f69e1c..e1a3ee3 100644
--- a/init/util.c
+++ b/init/util.c
@@ -329,9 +329,9 @@
     if (!s)
         return;
 
-    for (; *s; s++) {
+    while (*s) {
         s += strspn(s, accept);
-        if (*s) *s = '_';
+        if (*s) *s++ = '_';
     }
 }
 
diff --git a/libcutils/debugger.c b/libcutils/debugger.c
index 4035ee1..b8a2efc 100644
--- a/libcutils/debugger.c
+++ b/libcutils/debugger.c
@@ -19,11 +19,16 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
 #include <unistd.h>
 
 #include <cutils/debugger.h>
 #include <cutils/sockets.h>
 
+#define LOG_TAG "DEBUG"
+#include <log/log.h>
+
 #if defined(__LP64__)
 #include <elf.h>
 
@@ -64,7 +69,7 @@
   return result;
 }
 
-static int make_dump_request(debugger_action_t action, pid_t tid) {
+static int make_dump_request(debugger_action_t action, pid_t tid, int timeout_secs) {
   const char* socket_name;
   debugger_msg_t msg;
   size_t msg_len;
@@ -98,6 +103,19 @@
     return -1;
   }
 
+  if (timeout_secs > 0) {
+    struct timeval tm;
+    tm.tv_sec = timeout_secs;
+    tm.tv_usec = 0;
+    if (setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, &tm, sizeof(tm)) == -1) {
+      ALOGE("WARNING: Cannot set receive timeout value on socket: %s", strerror(errno));
+    }
+
+    if (setsockopt(sock_fd, SOL_SOCKET, SO_SNDTIMEO, &tm, sizeof(tm)) == -1) {
+      ALOGE("WARNING: Cannot set send timeout value on socket: %s", strerror(errno));
+    }
+  }
+
   if (send_request(sock_fd, msg_ptr, msg_len) < 0) {
     TEMP_FAILURE_RETRY(close(sock_fd));
     return -1;
@@ -107,7 +125,11 @@
 }
 
 int dump_backtrace_to_file(pid_t tid, int fd) {
-  int sock_fd = make_dump_request(DEBUGGER_ACTION_DUMP_BACKTRACE, tid);
+  return dump_backtrace_to_file_timeout(tid, fd, 0);
+}
+
+int dump_backtrace_to_file_timeout(pid_t tid, int fd, int timeout_secs) {
+  int sock_fd = make_dump_request(DEBUGGER_ACTION_DUMP_BACKTRACE, tid, timeout_secs);
   if (sock_fd < 0) {
     return -1;
   }
@@ -127,7 +149,11 @@
 }
 
 int dump_tombstone(pid_t tid, char* pathbuf, size_t pathlen) {
-  int sock_fd = make_dump_request(DEBUGGER_ACTION_DUMP_TOMBSTONE, tid);
+  return dump_tombstone_timeout(tid, pathbuf, pathlen, 0);
+}
+
+int dump_tombstone_timeout(pid_t tid, char* pathbuf, size_t pathlen, int timeout_secs) {
+  int sock_fd = make_dump_request(DEBUGGER_ACTION_DUMP_TOMBSTONE, tid, timeout_secs);
   if (sock_fd < 0) {
     return -1;
   }
diff --git a/sdcard/sdcard.c b/sdcard/sdcard.c
index 247ddd0..9cfb040 100644
--- a/sdcard/sdcard.c
+++ b/sdcard/sdcard.c
@@ -168,6 +168,11 @@
     __u32 refcount;
     __u64 nid;
     __u64 gen;
+    /*
+     * The inode number for this FUSE node. Note that this isn't stable across
+     * multiple invocations of the FUSE daemon.
+     */
+    __u32 ino;
 
     /* State derived based on current position in hierarchy. */
     perm_t perm;
@@ -224,6 +229,25 @@
     struct node root;
     char obbpath[PATH_MAX];
 
+    /* Used to allocate unique inode numbers for fuse nodes. We use
+     * a simple counter based scheme where inode numbers from deleted
+     * nodes aren't reused. Note that inode allocations are not stable
+     * across multiple invocation of the sdcard daemon, but that shouldn't
+     * be a huge problem in practice.
+     *
+     * Note that we restrict inodes to 32 bit unsigned integers to prevent
+     * truncation on 32 bit processes when unsigned long long stat.st_ino is
+     * assigned to an unsigned long ino_t type in an LP32 process.
+     *
+     * Also note that fuse_attr and fuse_dirent inode values are 64 bits wide
+     * on both LP32 and LP64, but the fuse kernel code doesn't squash 64 bit
+     * inode numbers into 32 bit values on 64 bit kernels (see fuse_squash_ino
+     * in fs/fuse/inode.c).
+     *
+     * Accesses must be guarded by |lock|.
+     */
+    __u32 inode_ctr;
+
     Hashmap* package_to_appid;
     Hashmap* appid_with_rw;
 };
@@ -387,7 +411,7 @@
 
 static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node)
 {
-    attr->ino = node->nid;
+    attr->ino = node->ino;
     attr->size = s->st_size;
     attr->blocks = s->st_blocks;
     attr->atime = s->st_atime;
@@ -575,6 +599,13 @@
     struct node *node;
     size_t namelen = strlen(name);
 
+    // Detect overflows in the inode counter. "4 billion nodes should be enough
+    // for everybody".
+    if (fuse->inode_ctr == 0) {
+        ERROR("No more inode numbers available");
+        return NULL;
+    }
+
     node = calloc(1, sizeof(struct node));
     if (!node) {
         return NULL;
@@ -596,6 +627,7 @@
     }
     node->namelen = namelen;
     node->nid = ptr_to_id(node);
+    node->ino = fuse->inode_ctr++;
     node->gen = fuse->next_generation++;
 
     derive_permissions_locked(fuse, parent, node);
@@ -700,6 +732,7 @@
     fuse->derive = derive;
     fuse->split_perms = split_perms;
     fuse->write_gid = write_gid;
+    fuse->inode_ctr = 1;
 
     memset(&fuse->root, 0, sizeof(fuse->root));
     fuse->root.nid = FUSE_ROOT_ID; /* 1 */