Merge "fastboot: Support USB 3.x SuperSpeed devices on Linux"
diff --git a/adb/Android.mk b/adb/Android.mk
index 3cadee3..7136afb 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -64,8 +64,6 @@
$(EXTRA_SRCS) \
$(USB_SRCS) \
-LOCAL_C_INCLUDES += external/openssl/include
-
ifneq ($(USE_SYSDEPS_WIN32),)
LOCAL_SRC_FILES += sysdeps_win32.c
else
@@ -77,7 +75,7 @@
LOCAL_MODULE := adb
LOCAL_MODULE_TAGS := debug
-LOCAL_STATIC_LIBRARIES := libzipfile libunz libcrypto_static $(EXTRA_STATIC_LIBS)
+LOCAL_STATIC_LIBRARIES := libzipfile libz libcrypto_static $(EXTRA_STATIC_LIBS)
ifeq ($(USE_SYSDEPS_WIN32),)
LOCAL_STATIC_LIBRARIES += libcutils
endif
@@ -167,11 +165,9 @@
-D_XOPEN_SOURCE \
-D_GNU_SOURCE
-LOCAL_C_INCLUDES += external/openssl/include
-
LOCAL_MODULE := adb
-LOCAL_STATIC_LIBRARIES := libzipfile libunz libcutils liblog
+LOCAL_STATIC_LIBRARIES := libzipfile libz libcutils liblog
LOCAL_SHARED_LIBRARIES := libcrypto
diff --git a/adb/usb_linux.c b/adb/usb_linux.c
index f16bdd0..7d13a5d 100644
--- a/adb/usb_linux.c
+++ b/adb/usb_linux.c
@@ -237,8 +237,20 @@
// looks like ADB...
ep1 = (struct usb_endpoint_descriptor *)bufptr;
bufptr += USB_DT_ENDPOINT_SIZE;
+ // For USB 3.0 SuperSpeed devices, skip potential
+ // USB 3.0 SuperSpeed Endpoint Companion descriptor
+ if (bufptr+2 <= devdesc + desclength &&
+ bufptr[0] == USB_DT_SS_EP_COMP_SIZE &&
+ bufptr[1] == USB_DT_SS_ENDPOINT_COMP) {
+ bufptr += USB_DT_SS_EP_COMP_SIZE;
+ }
ep2 = (struct usb_endpoint_descriptor *)bufptr;
bufptr += USB_DT_ENDPOINT_SIZE;
+ if (bufptr+2 <= devdesc + desclength &&
+ bufptr[0] == USB_DT_SS_EP_COMP_SIZE &&
+ bufptr[1] == USB_DT_SS_ENDPOINT_COMP) {
+ bufptr += USB_DT_SS_EP_COMP_SIZE;
+ }
if (bufptr > devdesc + desclength ||
ep1->bLength != USB_DT_ENDPOINT_SIZE ||
diff --git a/adb/usb_linux_client.c b/adb/usb_linux_client.c
index 8426e0e..70d2ad0 100644
--- a/adb/usb_linux_client.c
+++ b/adb/usb_linux_client.c
@@ -33,6 +33,7 @@
#define MAX_PACKET_SIZE_FS 64
#define MAX_PACKET_SIZE_HS 512
+#define MAX_PACKET_SIZE_SS 1024
#define cpu_to_le16(x) htole16(x)
#define cpu_to_le32(x) htole32(x)
@@ -56,19 +57,33 @@
};
static const struct {
- struct usb_functionfs_descs_head header;
+ __le32 magic;
+ __le32 length;
+ __le32 flags;
+ __le32 fs_count;
+ __le32 hs_count;
+ __le32 ss_count;
struct {
struct usb_interface_descriptor intf;
struct usb_endpoint_descriptor_no_audio source;
struct usb_endpoint_descriptor_no_audio sink;
} __attribute__((packed)) fs_descs, hs_descs;
+ struct {
+ struct usb_interface_descriptor intf;
+ struct usb_endpoint_descriptor_no_audio source;
+ struct usb_ss_ep_comp_descriptor source_comp;
+ struct usb_endpoint_descriptor_no_audio sink;
+ struct usb_ss_ep_comp_descriptor sink_comp;
+ } __attribute__((packed)) ss_descs;
} __attribute__((packed)) descriptors = {
- .header = {
- .magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC),
- .length = cpu_to_le32(sizeof(descriptors)),
- .fs_count = 3,
- .hs_count = 3,
- },
+ .magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2),
+ .length = cpu_to_le32(sizeof(descriptors)),
+ .flags = cpu_to_le32(FUNCTIONFS_HAS_FS_DESC |
+ FUNCTIONFS_HAS_HS_DESC |
+ FUNCTIONFS_HAS_SS_DESC),
+ .fs_count = 3,
+ .hs_count = 3,
+ .ss_count = 5,
.fs_descs = {
.intf = {
.bLength = sizeof(descriptors.fs_descs.intf),
@@ -121,6 +136,40 @@
.wMaxPacketSize = MAX_PACKET_SIZE_HS,
},
},
+ .ss_descs = {
+ .intf = {
+ .bLength = sizeof(descriptors.ss_descs.intf),
+ .bDescriptorType = USB_DT_INTERFACE,
+ .bInterfaceNumber = 0,
+ .bNumEndpoints = 2,
+ .bInterfaceClass = ADB_CLASS,
+ .bInterfaceSubClass = ADB_SUBCLASS,
+ .bInterfaceProtocol = ADB_PROTOCOL,
+ .iInterface = 1, /* first string from the provided table */
+ },
+ .source = {
+ .bLength = sizeof(descriptors.ss_descs.source),
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 1 | USB_DIR_OUT,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = MAX_PACKET_SIZE_SS,
+ },
+ .source_comp = {
+ .bLength = sizeof(descriptors.ss_descs.source_comp),
+ .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
+ },
+ .sink = {
+ .bLength = sizeof(descriptors.ss_descs.sink),
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 2 | USB_DIR_IN,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = MAX_PACKET_SIZE_SS,
+ },
+ .sink_comp = {
+ .bLength = sizeof(descriptors.ss_descs.sink_comp),
+ .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
+ },
+ },
};
#define STR_INTERFACE_ "ADB Interface"
diff --git a/libutils/Android.mk b/libutils/Android.mk
index e738c15..52de910 100644
--- a/libutils/Android.mk
+++ b/libutils/Android.mk
@@ -53,13 +53,6 @@
endif
endif
-host_commonLdlibs :=
-
-ifeq ($(TARGET_OS),linux)
-host_commonLdlibs += -lrt -ldl
-endif
-
-
# For the host
# =====================================================
include $(CLEAR_VARS)
@@ -93,9 +86,6 @@
endif
LOCAL_CFLAGS += -Werror
-LOCAL_C_INCLUDES += \
- external/zlib
-
LOCAL_STATIC_LIBRARIES := \
libcutils
diff --git a/libziparchive/Android.mk b/libziparchive/Android.mk
index 9bc6e61..ba7b74d 100644
--- a/libziparchive/Android.mk
+++ b/libziparchive/Android.mk
@@ -16,7 +16,6 @@
LOCAL_PATH := $(call my-dir)
source_files := zip_archive.cc
-includes := external/zlib
include $(CLEAR_VARS)
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
@@ -25,16 +24,13 @@
LOCAL_STATIC_LIBRARIES := libz
LOCAL_SHARED_LIBRARIES := libutils
LOCAL_MODULE:= libziparchive
-LOCAL_C_INCLUDES += ${includes}
LOCAL_CFLAGS := -Werror
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-LOCAL_MODULE := libziparchive
LOCAL_CPP_EXTENSION := .cc
LOCAL_SRC_FILES := ${source_files}
-LOCAL_C_INCLUDES += ${includes}
LOCAL_STATIC_LIBRARIES := libz libutils
LOCAL_MODULE:= libziparchive-host
LOCAL_CFLAGS := -Werror
@@ -46,10 +42,8 @@
include $(CLEAR_VARS)
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-LOCAL_MODULE := libziparchive
LOCAL_CPP_EXTENSION := .cc
LOCAL_SRC_FILES := ${source_files}
-LOCAL_C_INCLUDES += ${includes}
LOCAL_STATIC_LIBRARIES := libz libutils
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_MODULE:= libziparchive-host
@@ -63,7 +57,7 @@
LOCAL_MODULE := ziparchive-tests
LOCAL_CPP_EXTENSION := .cc
LOCAL_CFLAGS := -Werror
-LOCAL_SRC_FILES := zip_archive_test.cc
+LOCAL_SRC_FILES := zip_archive_test.cc entry_name_utils_test.cc
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_STATIC_LIBRARIES := libziparchive libz libutils
include $(BUILD_NATIVE_TEST)
@@ -75,7 +69,7 @@
LOCAL_CFLAGS += \
-Werror \
-Wno-unnamed-type-template-args
-LOCAL_SRC_FILES := zip_archive_test.cc
+LOCAL_SRC_FILES := zip_archive_test.cc entry_name_utils_test.cc
LOCAL_SHARED_LIBRARIES := libziparchive-host liblog
LOCAL_STATIC_LIBRARIES := \
libz \
diff --git a/libziparchive/entry_name_utils-inl.h b/libziparchive/entry_name_utils-inl.h
new file mode 100644
index 0000000..ddbc286
--- /dev/null
+++ b/libziparchive/entry_name_utils-inl.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2014 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 LIBZIPARCHIVE_ENTRY_NAME_UTILS_INL_H_
+#define LIBZIPARCHIVE_ENTRY_NAME_UTILS_INL_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// Check if |length| bytes at |entry_name| constitute a valid entry name.
+// Entry names must be valid UTF-8 and must not contain '0'.
+inline bool IsValidEntryName(const uint8_t* entry_name, const size_t length) {
+ for (size_t i = 0; i < length; ++i) {
+ const uint8_t byte = entry_name[i];
+ if (byte == 0) {
+ return false;
+ } else if ((byte & 0x80) == 0) {
+ // Single byte sequence.
+ continue;
+ } else if ((byte & 0xc0) == 0x80 || (byte & 0xfe) == 0xfe) {
+ // Invalid sequence.
+ return false;
+ } else {
+ // 2-5 byte sequences.
+ for (uint8_t first = byte << 1; first & 0x80; first <<= 1) {
+ ++i;
+
+ // Missing continuation byte..
+ if (i == length) {
+ return false;
+ }
+
+ // Invalid continuation byte.
+ const uint8_t continuation_byte = entry_name[i];
+ if ((continuation_byte & 0xc0) != 0x80) {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+
+#endif // LIBZIPARCHIVE_ENTRY_NAME_UTILS_INL_H_
diff --git a/libziparchive/entry_name_utils_test.cc b/libziparchive/entry_name_utils_test.cc
new file mode 100644
index 0000000..20715bb
--- /dev/null
+++ b/libziparchive/entry_name_utils_test.cc
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "entry_name_utils-inl.h"
+
+#include <gtest/gtest.h>
+
+TEST(entry_name_utils, NullChars) {
+ // 'A', 'R', '\0', 'S', 'E'
+ const uint8_t zeroes[] = { 0x41, 0x52, 0x00, 0x53, 0x45 };
+ ASSERT_FALSE(IsValidEntryName(zeroes, sizeof(zeroes)));
+
+ const uint8_t zeroes_continuation_chars[] = { 0xc2, 0xa1, 0xc2, 0x00 };
+ ASSERT_FALSE(IsValidEntryName(zeroes_continuation_chars,
+ sizeof(zeroes_continuation_chars)));
+}
+
+TEST(entry_name_utils, InvalidSequence) {
+ // 0xfe is an invalid start byte
+ const uint8_t invalid[] = { 0x41, 0xfe };
+ ASSERT_FALSE(IsValidEntryName(invalid, sizeof(invalid)));
+
+ // 0x91 is an invalid start byte (it's a valid continuation byte).
+ const uint8_t invalid2[] = { 0x41, 0x91 };
+ ASSERT_FALSE(IsValidEntryName(invalid2, sizeof(invalid2)));
+}
+
+TEST(entry_name_utils, TruncatedContinuation) {
+ // Malayalam script with truncated bytes. There should be 2 bytes
+ // after 0xe0
+ const uint8_t truncated[] = { 0xe0, 0xb4, 0x85, 0xe0, 0xb4 };
+ ASSERT_FALSE(IsValidEntryName(truncated, sizeof(truncated)));
+
+ // 0xc2 is the start of a 2 byte sequence that we've subsequently
+ // dropped.
+ const uint8_t truncated2[] = { 0xc2, 0xc2, 0xa1 };
+ ASSERT_FALSE(IsValidEntryName(truncated2, sizeof(truncated2)));
+}
+
+TEST(entry_name_utils, BadContinuation) {
+ // 0x41 is an invalid continuation char, since it's MSBs
+ // aren't "10..." (are 01).
+ const uint8_t bad[] = { 0xc2, 0xa1, 0xc2, 0x41 };
+ ASSERT_FALSE(IsValidEntryName(bad, sizeof(bad)));
+
+ // 0x41 is an invalid continuation char, since it's MSBs
+ // aren't "10..." (are 11).
+ const uint8_t bad2[] = { 0xc2, 0xa1, 0xc2, 0xfe };
+ ASSERT_FALSE(IsValidEntryName(bad2, sizeof(bad2)));
+}
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index 92150c3..b6fd0d2 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -33,8 +33,10 @@
#include <JNIHelp.h> // TEMP_FAILURE_RETRY may or may not be in unistd
+#include "entry_name_utils-inl.h"
#include "ziparchive/zip_archive.h"
+
// This is for windows. If we don't open a file in binary mode, weird
// things will happen.
#ifndef O_BINARY
@@ -641,9 +643,8 @@
const uint16_t comment_length = cdr->comment_length;
const uint8_t* file_name = ptr + sizeof(CentralDirectoryRecord);
- /* check that file name doesn't contain \0 character */
- if (memchr(file_name, 0, file_name_length) != NULL) {
- ALOGW("Zip: entry name can't contain \\0 character");
+ /* check that file name is valid UTF-8 and doesn't contain NUL (U+0000) characters */
+ if (!IsValidEntryName(file_name, file_name_length)) {
goto bail;
}
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index 6306f5c..79f2ebd 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -455,36 +455,31 @@
delete dev;
}
- dev = devices = new log_device_t("main", false, 'm');
- android::g_devCount = 1;
- if (android_name_to_log_id("system") == LOG_ID_SYSTEM) {
- dev->next = new log_device_t("system", false, 's');
- if (dev->next) {
- dev = dev->next;
- android::g_devCount++;
+ devices = dev = NULL;
+ android::g_devCount = 0;
+ needBinary = false;
+ for(int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
+ const char *name = android_log_id_to_name((log_id_t)i);
+ log_id_t log_id = android_name_to_log_id(name);
+
+ if (log_id != (log_id_t)i) {
+ continue;
}
- }
- if (android_name_to_log_id("radio") == LOG_ID_RADIO) {
- dev->next = new log_device_t("radio", false, 'r');
- if (dev->next) {
- dev = dev->next;
- android::g_devCount++;
+
+ bool binary = strcmp(name, "events") == 0;
+ log_device_t* d = new log_device_t(name, binary, *name);
+
+ if (dev) {
+ dev->next = d;
+ dev = d;
+ } else {
+ devices = dev = d;
}
- }
- if (android_name_to_log_id("events") == LOG_ID_EVENTS) {
- dev->next = new log_device_t("events", true, 'e');
- if (dev->next) {
- dev = dev->next;
- android::g_devCount++;
+ android::g_devCount++;
+ if (binary) {
needBinary = true;
}
}
- if (android_name_to_log_id("crash") == LOG_ID_CRASH) {
- dev->next = new log_device_t("crash", false, 'c');
- if (dev->next) {
- android::g_devCount++;
- }
- }
break;
}
diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp
index ee2f32d..c7c0249 100644
--- a/logd/LogAudit.cpp
+++ b/logd/LogAudit.cpp
@@ -19,7 +19,6 @@
#include <limits.h>
#include <stdarg.h>
#include <stdlib.h>
-#include <sys/klog.h>
#include <sys/prctl.h>
#include <sys/uio.h>
#include <syslog.h>
@@ -33,21 +32,23 @@
'0' + (LOG_AUTH | (PRI)) % 10, \
'>'
-LogAudit::LogAudit(LogBuffer *buf, LogReader *reader, int fdDmsg)
+LogAudit::LogAudit(LogBuffer *buf, LogReader *reader, int fdDmesg)
: SocketListener(getLogSocket(), false)
, logbuf(buf)
, reader(reader)
- , fdDmesg(-1) {
+ , fdDmesg(fdDmesg)
+ , 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(fdDmsg, auditd_message, sizeof(auditd_message));
- logDmesg();
- fdDmesg = fdDmsg;
+ write(fdDmesg, auditd_message, sizeof(auditd_message));
}
bool LogAudit::onDataAvailable(SocketClient *cli) {
- prctl(PR_SET_NAME, "logd.auditd");
+ if (!initialized) {
+ prctl(PR_SET_NAME, "logd.auditd");
+ initialized = true;
+ }
struct audit_message rep;
@@ -60,7 +61,8 @@
return false;
}
- logPrint("type=%d %.*s", rep.nlh.nlmsg_type, rep.nlh.nlmsg_len, rep.data);
+ logPrint("type=%d %.*s",
+ rep.nlh.nlmsg_type, rep.nlh.nlmsg_len, rep.data);
return true;
}
@@ -87,7 +89,7 @@
}
bool info = strstr(str, " permissive=1") || strstr(str, " policy loaded ");
- if (fdDmesg >= 0) {
+ if ((fdDmesg >= 0) && initialized) {
struct iovec iov[3];
static const char log_info[] = { KMSG_PRIORITY(LOG_INFO) };
static const char log_warning[] = { KMSG_PRIORITY(LOG_WARNING) };
@@ -213,34 +215,23 @@
return rc;
}
-void LogAudit::logDmesg() {
- int len = klogctl(KLOG_SIZE_BUFFER, NULL, 0);
- if (len <= 0) {
- return;
+int LogAudit::log(char *buf) {
+ char *audit = strstr(buf, " audit(");
+ if (!audit) {
+ return 0;
}
- len++;
- char buf[len];
+ *audit = '\0';
- int rc = klogctl(KLOG_READ_ALL, buf, len);
-
- buf[len - 1] = '\0';
-
- for(char *tok = buf; (rc >= 0) && ((tok = strtok(tok, "\r\n"))); tok = NULL) {
- char *audit = strstr(tok, " audit(");
- if (!audit) {
- continue;
- }
-
- *audit++ = '\0';
-
- char *type = strstr(tok, "type=");
- if (type) {
- rc = logPrint("%s %s", type, audit);
- } else {
- rc = logPrint("%s", audit);
- }
+ int rc;
+ char *type = strstr(buf, "type=");
+ if (type) {
+ rc = logPrint("%s %s", type, audit + 1);
+ } else {
+ rc = logPrint("%s", audit + 1);
}
+ *audit = ' ';
+ return rc;
}
int LogAudit::getLogSocket() {
diff --git a/logd/LogAudit.h b/logd/LogAudit.h
index 111030a..f977be9 100644
--- a/logd/LogAudit.h
+++ b/logd/LogAudit.h
@@ -24,16 +24,17 @@
LogBuffer *logbuf;
LogReader *reader;
int fdDmesg;
+ bool initialized;
public:
LogAudit(LogBuffer *buf, LogReader *reader, int fdDmesg);
+ int log(char *buf);
protected:
virtual bool onDataAvailable(SocketClient *cli);
private:
static int getLogSocket();
- void logDmesg();
int logPrint(const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
};
diff --git a/logd/main.cpp b/logd/main.cpp
index 54da7e3..946a9a0 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <string.h>
#include <sys/capability.h>
+#include <sys/klog.h>
#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -195,6 +196,23 @@
if (auditd) {
// failure is an option ... messages are in dmesg (required by standard)
LogAudit *al = new LogAudit(logBuf, reader, fdDmesg);
+
+ int len = klogctl(KLOG_SIZE_BUFFER, NULL, 0);
+ if (len > 0) {
+ len++;
+ char buf[len];
+
+ int rc = klogctl(KLOG_READ_ALL, buf, len);
+
+ buf[len - 1] = '\0';
+
+ for(char *ptr, *tok = buf;
+ (rc >= 0) && ((tok = strtok_r(tok, "\r\n", &ptr)));
+ tok = NULL) {
+ rc = al->log(tok);
+ }
+ }
+
if (al->startListener()) {
delete al;
close(fdDmesg);