auto import from //branches/cupcake_rel/...@138607
diff --git a/adb/adb.c b/adb/adb.c
index 7b23894..12a36f5 100644
--- a/adb/adb.c
+++ b/adb/adb.c
@@ -859,8 +859,20 @@
     property_get("ro.kernel.qemu", value, "");
     if (strcmp(value, "1") != 0) {
         property_get("ro.secure", value, "");
-        if (strcmp(value, "1") == 0)
+        if (strcmp(value, "1") == 0) {
+            // don't run as root if ro.secure is set...
             secure = 1;
+
+            // ... except we allow running as root in userdebug builds if the 
+            // service.adb.root property has been set by the "adb root" command
+            property_get("ro.debuggable", value, "");
+            if (strcmp(value, "1") == 0) {
+                property_get("service.adb.root", value, "");
+                if (strcmp(value, "1") == 0) {
+                    secure = 0;
+                }
+            }
+        }
     }
 
     /* don't listen on port 5037 if we are running in secure mode */
diff --git a/adb/commandline.c b/adb/commandline.c
index be596ce..7410dce 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -147,6 +147,7 @@
         "  adb get-serialno             - prints: <serial-number>\n"
         "  adb status-window            - continuously print device status for a specified device\n"
         "  adb remount                  - remounts the /system partition on the device read-write\n"
+        "  adb root                     - restarts adb with root permissions\n"
         "\n"
         "networking:\n"
         "  adb ppp <tty> [parameters]   - Run PPP over USB.\n"
@@ -914,6 +915,17 @@
         return 1;
     }
 
+    if(!strcmp(argv[0], "root")) {
+        int fd = adb_connect("root:");
+        if(fd >= 0) {
+            read_and_dump(fd);
+            adb_close(fd);
+            return 0;
+        }
+        fprintf(stderr,"error: %s\n", adb_error());
+        return 1;
+    }
+
     if(!strcmp(argv[0], "bugreport")) {
         if (argc != 1) {
             return 1;
diff --git a/adb/services.c b/adb/services.c
index e686949..1de55e6 100644
--- a/adb/services.c
+++ b/adb/services.c
@@ -103,6 +103,34 @@
     adb_close(fd);
 }
 
+void restart_root_service(int fd, void *cookie)
+{
+    char buf[100];
+    char value[PROPERTY_VALUE_MAX];
+
+    if (getuid() == 0) {
+        snprintf(buf, sizeof(buf), "adbd is already running as root\n");
+        writex(fd, buf, strlen(buf));
+        adb_close(fd);
+    } else {
+        property_get("ro.debuggable", value, "");
+        if (strcmp(value, "1") != 0) {
+            snprintf(buf, sizeof(buf), "adbd cannot run as root in production builds\n");
+            writex(fd, buf, strlen(buf));
+            return;
+        }
+
+        property_set("service.adb.root", "1");
+        snprintf(buf, sizeof(buf), "restarting adbd as root\n");
+        writex(fd, buf, strlen(buf));
+        adb_close(fd);
+
+        // quit, and init will restart us as root
+        sleep(1);
+        exit(1);
+    }
+}
+
 #endif
 
 #if 0
@@ -289,6 +317,8 @@
         ret = create_service_thread(file_sync_service, NULL);
     } else if(!strncmp(name, "remount:", 8)) {
         ret = create_service_thread(remount_service, NULL);
+    } else if(!strncmp(name, "root:", 5)) {
+        ret = create_service_thread(restart_root_service, NULL);
 #endif
 #if 0
     } else if(!strncmp(name, "echo:", 5)){
diff --git a/init/property_service.c b/init/property_service.c
index 7a6416b..0bc6239 100644
--- a/init/property_service.c
+++ b/init/property_service.c
@@ -69,6 +69,7 @@
     { "dhcp.",		AID_DHCP },
     { "debug.",		AID_SHELL },
     { "log.",		AID_SHELL },
+    { "service.adb.root",	AID_SHELL },
     { "persist.sys.",	AID_SYSTEM },
     { "persist.service.",   AID_SYSTEM },
     { NULL, 0 }
diff --git a/libcutils/array.c b/libcutils/array.c
index ff2c8ff..55ec055 100644
--- a/libcutils/array.c
+++ b/libcutils/array.c
@@ -18,8 +18,10 @@
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
+#include <limits.h>
 
 #define INITIAL_CAPACITY (4)
+#define MAX_CAPACITY     ((int)(UINT_MAX/sizeof(void*)))
 
 struct Array {
     void** contents;
@@ -45,13 +47,26 @@
 static int ensureCapacity(Array* array, int capacity) {
     int oldCapacity = array->capacity;
     if (capacity > oldCapacity) {
-        int newCapacity = (oldCapacity == 0) ? INITIAL_CAPACITY : oldCapacity * 2;
-    
-        // Keep doubling capacity until we surpass necessary capacity. 
+        int newCapacity = (oldCapacity == 0) ? INITIAL_CAPACITY : oldCapacity;
+
+        // Ensure we're not doing something nasty
+        if (capacity > MAX_CAPACITY)
+            return -1;
+
+        // Keep doubling capacity until we surpass necessary capacity.
         while (newCapacity < capacity) {
-            newCapacity *= 2;
+            int  newCap = newCapacity*2;
+            // Handle integer overflows
+            if (newCap < newCapacity || newCap > MAX_CAPACITY) {
+                newCap = MAX_CAPACITY;
+            }
+            newCapacity = newCap;
         }
-    
+
+        // Should not happen, but better be safe than sorry
+        if (newCapacity < 0 || newCapacity > MAX_CAPACITY)
+            return -1;
+
         void** newContents;
         if (array->contents == NULL) {
             // Allocate new array.
@@ -151,5 +166,5 @@
 }
 
 const void** arrayUnwrap(Array* array) {
-    return array->contents;
+    return (const void**)array->contents;
 }
diff --git a/libcutils/strdup8to16.c b/libcutils/strdup8to16.c
index 8654b04..63e5ca4 100644
--- a/libcutils/strdup8to16.c
+++ b/libcutils/strdup8to16.c
@@ -18,6 +18,7 @@
 #include <cutils/jstring.h>
 #include <assert.h>
 #include <stdlib.h>
+#include <limits.h>
 
 /* See http://www.unicode.org/reports/tr22/ for discussion
  * on invalid sequences
@@ -48,6 +49,10 @@
 
     len = strlen8to16(s);
 
+    // fail on overflow
+    if (len && SIZE_MAX/len < sizeof(char16_t))
+        return NULL;
+
     // no plus-one here. UTF-16 strings are not null terminated
     ret = (char16_t *) malloc (sizeof(char16_t) * len);
 
diff --git a/rootdir/init.rc b/rootdir/init.rc
index e4bb529..a0d6c54 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -116,7 +116,7 @@
     write /sys/module/lowmemorykiller/parameters/adj 0,1,2,7,14,15
 
     write /proc/sys/vm/overcommit_memory 1
-    write /proc/sys/vm/min_free_order_shift 2
+    write /proc/sys/vm/min_free_order_shift 4
     write /sys/module/lowmemorykiller/parameters/minfree 1536,2048,4096,5120,5632,6144
 
     # Set init its forked children's oom_adj.
diff --git a/vold/blkdev.c b/vold/blkdev.c
index 533bc35..981d0f2 100644
--- a/vold/blkdev.c
+++ b/vold/blkdev.c
@@ -107,8 +107,8 @@
         blk->nr_parts = 0;
 
         if ((block[0x1fe] != 0x55) || (block[0x1ff] != 0xAA)) {
-            LOG_VOL("Disk %d:%d does not contain a partition table",
-                    blk->major, blk->minor);
+            LOGI("Disk %d:%d does not contain a partition table",
+                 blk->major, blk->minor);
             goto out;
         }
 
@@ -120,10 +120,10 @@
                 struct fat_boot_sector *fb = (struct fat_boot_sector *) &block[0];
              
                 if (!i && fb->reserved && fb->fats && fat_valid_media(fb->media)) {
-                    LOG_VOL("Detected FAT filesystem in partition table");
+                    LOGI("Detected FAT filesystem in partition table");
                     break;
                 } else {
-                    LOG_VOL("Partition table looks corrupt");
+                    LOGI("Partition table looks corrupt");
                     break;
                 }
             }
@@ -157,7 +157,7 @@
         sprintf(tmp2, " type 0x%x", blk->part_type);
 
     strcat(tmp, tmp2);
-    LOG_VOL(tmp);
+    LOGI(tmp);
 
     close(fd);
 
diff --git a/vold/media.c b/vold/media.c
index 40637ff..db42a3e 100644
--- a/vold/media.c
+++ b/vold/media.c
@@ -114,10 +114,8 @@
 {
     blkdev_list_t *list_entry;
 
-    if (!(list_entry = malloc(sizeof(blkdev_list_t)))) {
-        LOGE("Out of memory");
+    if (!(list_entry = malloc(sizeof(blkdev_list_t))))
         return -ENOMEM;
-    }
     
     list_entry->next = NULL;
     list_entry->dev = dev;
diff --git a/vold/uevent.c b/vold/uevent.c
index b1a6944..d16f315 100644
--- a/vold/uevent.c
+++ b/vold/uevent.c
@@ -248,7 +248,6 @@
             low_batt = true;
         else
             low_batt = false;
-LOG_VOL("handle_powersupply_event(): low_batt = %d, door_open = %d", low_batt, door_open);
         volmgr_safe_mode(low_batt || door_open);
     }
     return 0;
@@ -272,7 +271,6 @@
             door_open = true;
         else
             door_open = false;
-LOG_VOL("handle_powersupply_event(): low_batt = %d, door_open = %d", low_batt, door_open);
         volmgr_safe_mode(low_batt || door_open);
     } else
         LOG_VOL("handle_switch_event(): Ignoring switch '%s'", name);
@@ -351,7 +349,7 @@
             return rc;
         }
 
-        LOG_VOL("New blkdev %d.%d on media %s, media path %s, Dpp %d",
+        LOGI("New blkdev %d.%d on media %s, media path %s, Dpp %d",
                 blkdev->major, blkdev->minor, media->name, mediapath,
                 blkdev_get_num_pending_partitions(blkdev->disk));
 
@@ -365,7 +363,7 @@
         if (!(blkdev = blkdev_lookup_by_devno(maj, min)))
             return 0;
 
-        LOG_VOL("Destroying blkdev %d.%d @ %s on media %s", blkdev->major,
+        LOGI("Destroying blkdev %d.%d @ %s on media %s", blkdev->major,
                 blkdev->minor, blkdev->devpath, media->name);
         volmgr_notify_eject(blkdev, _cb_blkdev_ok_to_destroy);
 
@@ -373,7 +371,7 @@
         if (!(blkdev = blkdev_lookup_by_devno(maj, min)))
             return 0;
 
-        LOG_VOL("Modified blkdev %d.%d @ %s on media %s", blkdev->major,
+        LOGI("Modified blkdev %d.%d @ %s on media %s", blkdev->major,
                 blkdev->minor, blkdev->devpath, media->name);
         
         blkdev_refresh(blkdev);
@@ -420,7 +418,7 @@
             LOGE("Unable to allocate new media (%m)");
             return -1;
         }
-        LOG_VOL("New MMC card '%s' (serial %u) added @ %s", media->name,
+        LOGI("New MMC card '%s' (serial %u) added @ %s", media->name,
                   media->serial, media->devpath);
     } else if (event->action == action_remove) {
         media_t *media;
@@ -430,7 +428,7 @@
             return -1;
         }
 
-        LOG_VOL("MMC card '%s' (serial %u) @ %s removed", media->name, 
+        LOGI("MMC card '%s' (serial %u) @ %s removed", media->name, 
                   media->serial, media->devpath);
         media_destroy(media);
     } else {
diff --git a/vold/vold.c b/vold/vold.c
index 17331ac..7d50a2f 100644
--- a/vold/vold.c
+++ b/vold/vold.c
@@ -60,7 +60,7 @@
     struct sockaddr_nl nladdr;
     int uevent_sz = 64 * 1024;
 
-    LOG_VOL("Android Volume Daemon version %d.%d", ver_major, ver_minor);
+    LOGI("Android Volume Daemon version %d.%d", ver_major, ver_minor);
 
     /*
      * Create all the various sockets we'll need
@@ -208,7 +208,7 @@
 
     pthread_mutex_lock(&write_mutex);
 
-    LOG_VOL("send_msg(%s):", message);
+//    LOG_VOL("send_msg(%s):", message);
 
     if (fw_sock >= 0)
         result = write(fw_sock, message, strlen(message) + 1);
diff --git a/vold/volmgr.c b/vold/volmgr.c
index c3ce8d1..7c4c077 100644
--- a/vold/volmgr.c
+++ b/vold/volmgr.c
@@ -205,7 +205,7 @@
     volume_t *v = vol_root;
     while (v) {
         if (_mountpoint_mounted(v->mount_point)) {
-            LOG_VOL("Volume '%s' already mounted at startup", v->mount_point);
+            LOGW("Volume '%s' already mounted at startup", v->mount_point);
             v->state = volstate_mounted;
         }
         v = v->next;
@@ -229,7 +229,7 @@
         if (v->state == volstate_mounted && v->fs) {
             rc = v->fs->mount_fn(v->dev, v, safe_mode);
             if (!rc) {
-                LOG_VOL("Safe mode %s on %s", (enable ? "enabled" : "disabled"), v->mount_point);
+                LOGI("Safe mode %s on %s", (enable ? "enabled" : "disabled"), v->mount_point);
             } else {
                 LOGE("Failed to %s safe-mode on %s (%s)",
                      (enable ? "enable" : "disable" ), v->mount_point, strerror(-rc));
@@ -555,7 +555,7 @@
         
     }
 
-    LOG_VOL("Evaluating dev '%s' for mountable filesystems for '%s'",
+    LOGI("Evaluating dev '%s' for mountable filesystems for '%s'",
             dev->devpath, vol->mount_point);
 
     if (dev->nr_parts == 0) {
@@ -642,7 +642,7 @@
     actions.sa_handler = volmgr_reaper_thread_sighandler;
     sigaction(SIGUSR1, &actions, NULL);
 
-    LOG_VOL("Reaper here - working on %s", vol->mount_point);
+    LOGW("Reaper here - working on %s", vol->mount_point);
 
     boolean send_sig_kill = false;
     int i, rc;
@@ -650,7 +650,7 @@
     for (i = 0; i < 10; i++) {
         errno = 0;
         rc = umount(vol->mount_point);
-        LOG_VOL("volmngr reaper umount(%s) attempt %d (%s)",
+        LOGW("volmngr reaper umount(%s) attempt %d (%s)",
                 vol->mount_point, i + 1, strerror(errno));
         if (!rc)
             break;
@@ -667,7 +667,7 @@
     }
 
     if (!rc) {
-        LOG_VOL("Reaper sucessfully unmounted %s", vol->mount_point);
+        LOGI("Reaper sucessfully unmounted %s", vol->mount_point);
         vol->fs = NULL;
         volume_setstate(vol, volstate_unmounted);
     } else {
@@ -687,7 +687,7 @@
     if (vol->worker_running) {
         LOGE("Worker thread is currently running.. waiting..");
         pthread_mutex_lock(&vol->worker_sem);
-        LOG_VOL("Worker thread now available");
+        LOGI("Worker thread now available");
     }
 
     vol->worker_args.reaper_args.cb = cb;
@@ -716,7 +716,7 @@
                 break;
             }
 
-            LOG_VOL("volmngr quick stop umount(%s) attempt %d (%s)",
+            LOGI("volmngr quick stop umount(%s) attempt %d (%s)",
                     v->mount_point, i + 1, strerror(errno));
 
             if (i == 0)
@@ -726,7 +726,7 @@
         }
 
         if (!rc) {
-            LOG_VOL("volmgr_stop_volume(%s): Volume unmounted sucessfully",
+            LOGI("volmgr_stop_volume(%s): Volume unmounted sucessfully",
                     v->mount_point);
             if (emit_statechange)
                 volume_setstate(v, volstate_unmounted);
@@ -738,7 +738,7 @@
          * Since the volume is still in use, dispatch the stopping to
          * a thread
          */
-        LOG_VOL("Volume %s is busy (%d) - uncaging the reaper", v->mount_point, rc);
+        LOGW("Volume %s is busy (%d) - uncaging the reaper", v->mount_point, rc);
         volmgr_uncage_reaper(v, cb, arg);
         return -EINPROGRESS;
     } else if (v->state == volstate_checking) {
@@ -1061,7 +1061,7 @@
     if (vol->worker_running) {
         LOGE("Worker thread is currently running.. waiting..");
         pthread_mutex_lock(&vol->worker_sem);
-        LOG_VOL("Worker thread now available");
+        LOGI("Worker thread now available");
     }
 
     vol->dev = dev; 
@@ -1132,7 +1132,7 @@
         rc = fs->check_fn(dev);
         pthread_mutex_lock(&vol->lock);
         if (vol->state != volstate_checking) {
-            LOG_VOL("filesystem check aborted");
+            LOGE("filesystem check aborted");
             goto out;
         }
         
@@ -1146,14 +1146,14 @@
             goto out_unmountable;
         }
 #if DEBUG_VOLMGR
-        LOG_VOL("%s filesystem check of %d:%d OK", fs->name,
+        LOGI("%s filesystem check of %d:%d OK", fs->name,
                 dev->major, dev->minor);
 #endif
     }
 
     rc = fs->mount_fn(dev, vol, safe_mode);
     if (!rc) {
-        LOG_VOL("Sucessfully mounted %s filesystem %d:%d on %s (safe-mode %s)",
+        LOGI("Sucessfully mounted %s filesystem %d:%d on %s (safe-mode %s)",
                 fs->name, dev->major, dev->minor, vol->mount_point,
                 (safe_mode ? "on" : "off"));
         vol->fs = fs;
diff --git a/vold/volmgr_vfat.c b/vold/volmgr_vfat.c
index b08e6a5..344a166 100644
--- a/vold/volmgr_vfat.c
+++ b/vold/volmgr_vfat.c
@@ -107,8 +107,6 @@
 
     flags = MS_NODEV | MS_NOEXEC | MS_NOSUID | MS_DIRSYNC;
 
-    if (safe_mode)
-        flags |= MS_SYNCHRONOUS;
     if (vol->state == volstate_mounted) {
         LOG_VOL("Remounting %d:%d on %s, safe mode %d", dev->major,
                 dev->minor, vol->mount_point, safe_mode);