Merge "fs_mgr: support a unified fstab format."
diff --git a/adb/adb.c b/adb/adb.c
index c57a875..530a4c8 100644
--- a/adb/adb.c
+++ b/adb/adb.c
@@ -326,7 +326,7 @@
     send_packet(cp, t);
 }
 
-static void send_auth_request(atransport *t)
+void send_auth_request(atransport *t)
 {
     D("Calling send_auth_request\n");
     apacket *p;
@@ -1184,6 +1184,33 @@
 }
 
 #if !ADB_HOST
+
+static void drop_capabilities_bounding_set_if_needed() {
+#ifdef ALLOW_ADBD_ROOT
+    char value[PROPERTY_VALUE_MAX];
+    property_get("ro.debuggable", value, "");
+    if (strcmp(value, "1") == 0) {
+        return;
+    }
+#endif
+    int i;
+    for (i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) {
+        if ((i == CAP_NET_RAW) || (i == CAP_SETUID) || (i == CAP_SETGID)) {
+            // CAP_NET_RAW needed by /system/bin/ping
+            // CAP_SETUID CAP_SETGID needed by /system/bin/run-as
+            continue;
+        }
+        int err = prctl(PR_CAPBSET_DROP, i, 0, 0, 0);
+
+        // Some kernels don't have file capabilities compiled in, and
+        // prctl(PR_CAPBSET_DROP) returns EINVAL. Don't automatically
+        // die when we see such misconfigured kernels.
+        if ((err < 0) && (errno != EINVAL)) {
+            exit(1);
+        }
+    }
+}
+
 static int should_drop_privileges() {
 #ifndef ALLOW_ADBD_ROOT
     return 1;
@@ -1272,12 +1299,14 @@
     /* don't run as root if we are running in secure mode */
     if (should_drop_privileges()) {
         struct __user_cap_header_struct header;
-        struct __user_cap_data_struct cap;
+        struct __user_cap_data_struct cap[2];
 
         if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) != 0) {
             exit(1);
         }
 
+        drop_capabilities_bounding_set_if_needed();
+
         /* add extra groups:
         ** AID_ADB to access the USB driver
         ** AID_LOG to read system logs (adb logcat)
@@ -1305,12 +1334,15 @@
             exit(1);
         }
 
+        memset(&header, 0, sizeof(header));
+        memset(cap, 0, sizeof(cap));
+
         /* set CAP_SYS_BOOT capability, so "adb reboot" will succeed */
-        header.version = _LINUX_CAPABILITY_VERSION;
+        header.version = _LINUX_CAPABILITY_VERSION_3;
         header.pid = 0;
-        cap.effective = cap.permitted = (1 << CAP_SYS_BOOT);
-        cap.inheritable = 0;
-        capset(&header, &cap);
+        cap[CAP_TO_INDEX(CAP_SYS_BOOT)].effective |= CAP_TO_MASK(CAP_SYS_BOOT);
+        cap[CAP_TO_INDEX(CAP_SYS_BOOT)].permitted |= CAP_TO_MASK(CAP_SYS_BOOT);
+        capset(&header, cap);
 
         D("Local port disabled\n");
     } else {
diff --git a/adb/adb_auth.h b/adb/adb_auth.h
index 96f637b..b24c674 100644
--- a/adb/adb_auth.h
+++ b/adb/adb_auth.h
@@ -20,6 +20,8 @@
 void adb_auth_init(void);
 void adb_auth_verified(atransport *t);
 
+void send_auth_request(atransport *t);
+
 /* AUTH packets first argument */
 /* Request */
 #define ADB_AUTH_TOKEN         1
diff --git a/adb/adb_auth_client.c b/adb/adb_auth_client.c
index a4ad18f..efc49eb 100644
--- a/adb/adb_auth_client.c
+++ b/adb/adb_auth_client.c
@@ -43,6 +43,10 @@
 static fdevent listener_fde;
 static int framework_fd = -1;
 
+static void usb_disconnected(void* unused, atransport* t);
+static struct adisconnect usb_disconnect = { usb_disconnected, 0, 0, 0 };
+static atransport* usb_transport;
+static bool needs_retry = false;
 
 static void read_keys(const char *file, struct listnode *list)
 {
@@ -155,21 +159,30 @@
     return ret;
 }
 
+static void usb_disconnected(void* unused, atransport* t)
+{
+    D("USB disconnect");
+    remove_transport_disconnect(usb_transport, &usb_disconnect);
+    usb_transport = NULL;
+    needs_retry = false;
+}
+
 static void adb_auth_event(int fd, unsigned events, void *data)
 {
-    atransport *t = data;
     char response[2];
     int ret;
 
     if (events & FDE_READ) {
         ret = unix_read(fd, response, sizeof(response));
         if (ret < 0) {
-            D("Disconnect");
-            fdevent_remove(&t->auth_fde);
+            D("Framework disconnect");
+            if (usb_transport)
+                fdevent_remove(&usb_transport->auth_fde);
             framework_fd = -1;
         }
         else if (ret == 2 && response[0] == 'O' && response[1] == 'K') {
-            adb_auth_verified(t);
+            if (usb_transport)
+                adb_auth_verified(usb_transport);
         }
     }
 }
@@ -179,8 +192,12 @@
     char msg[MAX_PAYLOAD];
     int ret;
 
+    usb_transport = t;
+    add_transport_disconnect(t, &usb_disconnect);
+
     if (framework_fd < 0) {
         D("Client not connected\n");
+        needs_retry = true;
         return;
     }
 
@@ -221,6 +238,11 @@
     }
 
     framework_fd = s;
+
+    if (needs_retry) {
+        needs_retry = false;
+        send_auth_request(usb_transport);
+    }
 }
 
 void adb_auth_init(void)
diff --git a/debuggerd/Android.mk b/debuggerd/Android.mk
index e48b9af..3fca64f 100644
--- a/debuggerd/Android.mk
+++ b/debuggerd/Android.mk
@@ -37,6 +37,7 @@
 LOCAL_MODULE := crasher
 LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
 LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS += -fstack-protector-all
 #LOCAL_FORCE_STATIC_EXECUTABLE := true
 LOCAL_SHARED_LIBRARIES := libcutils libc
 include $(BUILD_EXECUTABLE)
diff --git a/debuggerd/crasher.c b/debuggerd/crasher.c
index 74eaa49..134fe80 100644
--- a/debuggerd/crasher.c
+++ b/debuggerd/crasher.c
@@ -35,6 +35,18 @@
     }
 }
 
+int smash_stack(int i) {
+    printf("crasher: deliberately corrupting stack...\n");
+    // Unless there's a "big enough" buffer on the stack, gcc
+    // doesn't bother inserting checks.
+    char buf[8];
+    // If we don't write something relatively unpredicatable
+    // into the buffer and then do something with it, gcc
+    // optimizes everything away and just returns a constant.
+    *(int*)(&buf[7]) = (uintptr_t) &buf[0];
+    return *(int*)(&buf[0]);
+}
+
 void test_call1()
 {
     *((int*) 32) = 1;
@@ -95,6 +107,7 @@
         return do_action_on_thread(arg + strlen("thread-"));
     }
 
+    if(!strcmp(arg,"smash-stack")) return smash_stack(42);
     if(!strcmp(arg,"nostack")) crashnostack();
     if(!strcmp(arg,"ctest")) return ctest();
     if(!strcmp(arg,"exit")) exit(1);
diff --git a/include/system/graphics.h b/include/system/graphics.h
index 82b5fcc..ab064db 100644
--- a/include/system/graphics.h
+++ b/include/system/graphics.h
@@ -87,6 +87,54 @@
      */
     HAL_PIXEL_FORMAT_YV12   = 0x32315659, // YCrCb 4:2:0 Planar
 
+
+    /*
+     * Android Y8 format:
+     *
+     * This format is exposed outside of the HAL to the framework.
+     * The expected gralloc usage flags are SW_* and HW_CAMERA_*,
+     * and no other HW_ flags will be used.
+     *
+     * Y8 is a YUV planar format comprised of a WxH Y plane,
+     * with each pixel being represented by 8 bits.
+     *
+     * It is equivalent to just the Y plane from YV12.
+     *
+     * This format assumes
+     * - an even width
+     * - an even height
+     * - a horizontal stride multiple of 16 pixels
+     * - a vertical stride equal to the height
+     *
+     *   size = stride * height
+     *
+     */
+    HAL_PIXEL_FORMAT_Y8     = 0x20203859,
+
+    /*
+     * Android Y16 format:
+     *
+     * This format is exposed outside of the HAL to the framework.
+     * The expected gralloc usage flags are SW_* and HW_CAMERA_*,
+     * and no other HW_ flags will be used.
+     *
+     * Y16 is a YUV planar format comprised of a WxH Y plane,
+     * with each pixel being represented by 16 bits.
+     *
+     * It is just like Y8, but has double the bits per pixel (little endian).
+     *
+     * This format assumes
+     * - an even width
+     * - an even height
+     * - a horizontal stride multiple of 16 pixels
+     * - a vertical stride equal to the height
+     * - strides are specified in pixels, not in bytes
+     *
+     *   size = stride * height * 2
+     *
+     */
+    HAL_PIXEL_FORMAT_Y16    = 0x20363159,
+
     /*
      * Android RAW sensor format:
      *
diff --git a/include/system/window.h b/include/system/window.h
index 4698fb3..b8a19c8 100644
--- a/include/system/window.h
+++ b/include/system/window.h
@@ -321,7 +321,6 @@
 enum {
     NATIVE_WINDOW_FRAMEBUFFER               = 0, /* FramebufferNativeWindow */
     NATIVE_WINDOW_SURFACE                   = 1, /* Surface */
-    NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT    = 2, /* SurfaceTextureClient */
 };
 
 /* parameter for NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP
diff --git a/logwrapper/logwrap.c b/logwrapper/logwrap.c
index a756eb3..d9247ec 100644
--- a/logwrapper/logwrap.c
+++ b/logwrapper/logwrap.c
@@ -32,7 +32,7 @@
 #include "private/android_filesystem_config.h"
 #include "cutils/log.h"
 
-#define ARRAY_SIZE(x)	(sizeof(x) / sizeof(*(x)))
+#define ARRAY_SIZE(x)   (sizeof(x) / sizeof(*(x)))
 
 static int signal_fd_write;
 
@@ -144,31 +144,34 @@
         }
     }
 
-    // Flush remaining data
-    if (a != b) {
-        buffer[b] = '\0';
-        if (logwrap)
-            ALOG(LOG_INFO, btag, "%s", &buffer[a]);
+    if (chld_sts != NULL) {
+        *chld_sts = status;
+    } else {
+      if (WIFEXITED(status))
+        rc = WEXITSTATUS(status);
+      else
+        rc = -ECHILD;
     }
 
-    if (WIFEXITED(status)) {
+    if (logwrap) {
+      // Flush remaining data
+      if (a != b) {
+        buffer[b] = '\0';
+        ALOG(LOG_INFO, btag, "%s", &buffer[a]);
+      }
+      if (WIFEXITED(status)) {
         if (WEXITSTATUS(status))
-            ALOG(LOG_INFO, "logwrapper", "%s terminated by exit(%d)", btag,
-                    WEXITSTATUS(status));
-        if (chld_sts == NULL)
-            rc = WEXITSTATUS(status);
-    } else {
-        if (chld_sts == NULL)
-            rc = -ECHILD;
+          ALOG(LOG_INFO, "logwrapper", "%s terminated by exit(%d)", btag,
+               WEXITSTATUS(status));
+      } else {
         if (WIFSIGNALED(status))
-            ALOG(LOG_INFO, "logwrapper", "%s terminated by signal %d", btag,
-                    WTERMSIG(status));
+          ALOG(LOG_INFO, "logwrapper", "%s terminated by signal %d", btag,
+               WTERMSIG(status));
         else if (WIFSTOPPED(status))
-            ALOG(LOG_INFO, "logwrapper", "%s stopped by signal %d", btag,
-                    WSTOPSIG(status));
+          ALOG(LOG_INFO, "logwrapper", "%s stopped by signal %d", btag,
+               WSTOPSIG(status));
+      }
     }
-    if (chld_sts != NULL)
-        *chld_sts = status;
 
 err_poll:
     return rc;
diff --git a/run-as/package.c b/run-as/package.c
index 143d647..683dae6 100644
--- a/run-as/package.c
+++ b/run-as/package.c
@@ -76,13 +76,30 @@
     struct stat  st;
     size_t  length = 0;
     void*   address = NULL;
+    gid_t   oldegid;
 
     *filesize = 0;
 
+    /*
+     * Temporarily switch effective GID to allow us to read
+     * the packages file
+     */
+
+    oldegid = getegid();
+    if (setegid(AID_SYSTEM) < 0) {
+        return NULL;
+    }
+
     /* open the file for reading */
     fd = TEMP_FAILURE_RETRY(open(filename, O_RDONLY));
-    if (fd < 0)
+    if (fd < 0) {
         return NULL;
+    }
+
+    /* restore back to our old egid */
+    if (setegid(oldegid) < 0) {
+        goto EXIT;
+    }
 
     /* get its size */
     ret = TEMP_FAILURE_RETRY(fstat(fd, &st));