[Android-tools-devel] unblock android-platform-system-core/1:7.0.0+r1-4

Hans-Christoph Steiner hans at eds.org
Mon Mar 27 19:15:04 UTC 2017


Package: release.debian.org
Severity: normal
User: release.debian.org at packages.debian.org
Usertags: unblock

Please unblock package: android-platform-system-core

This fixes some usability and minor security issues:  #823792 #688280
#858177  The part of the diff for #858177 is a bit large, since I just
took the whole bugfix/security release i.e. 7.0.0r1 vs 7.0.0r33, since
the whole thing is tested together as a whole package, and the changes
did not seem small enough to be cherry-pickable.

Sorry to say that this also includes packages in NEW.  These are only
transitional dummy packages so that users of the previous
android-tools-* packages will be upgraded to the new packages where it
makes sense.  The android-tools source package is not in stretch, and is
mostly deprecated.  This is the Android Tools Team's first transitional
package, so we didn't realize it had to go through NEW.  If this is not
possible, I can strip out the new packages and resubmit.

Attached is the source debdiff.

-------------- next part --------------
diff -Nru android-platform-system-core-7.0.0+r1/debian/adb.lintian-overrides android-platform-system-core-7.0.0+r1/debian/adb.lintian-overrides
--- android-platform-system-core-7.0.0+r1/debian/adb.lintian-overrides	2016-01-13 23:23:40.000000000 +0100
+++ android-platform-system-core-7.0.0+r1/debian/adb.lintian-overrides	2017-03-27 09:05:23.000000000 +0200
@@ -1,3 +1,12 @@
-# Executables of Android SDK uses private libraries located in /usr/lib/android
+# Executables from the Android SDK normally each staticly link in all
+# of the libs.  That means each executable includes a full copy of all
+# the libs, which is not how Debian works.  These libs need to be
+# dynamically linlked in so that just the library can be updated when
+# there is a security fix, instead of requiring all of the executables
+# be recompiled.  That said, these libraries do not have a stable
+# interface and were never intended to be used by any other project,
+# only with the internal, Android SDK executables.  Therefore, the
+# Android SDK executables use private libraries located in
+# /usr/lib/android
 
-binary-or-shlib-defines-rpath
\ No newline at end of file
+binary-or-shlib-defines-rpath
diff -Nru android-platform-system-core-7.0.0+r1/debian/append2simg.lintian-overrides android-platform-system-core-7.0.0+r1/debian/append2simg.lintian-overrides
--- android-platform-system-core-7.0.0+r1/debian/append2simg.lintian-overrides	1970-01-01 01:00:00.000000000 +0100
+++ android-platform-system-core-7.0.0+r1/debian/append2simg.lintian-overrides	2017-03-27 09:05:23.000000000 +0200
@@ -0,0 +1,12 @@
+# Executables from the Android SDK normally each staticly link in all
+# of the libs.  That means each executable includes a full copy of all
+# the libs, which is not how Debian works.  These libs need to be
+# dynamically linlked in so that just the library can be updated when
+# there is a security fix, instead of requiring all of the executables
+# be recompiled.  That said, these libraries do not have a stable
+# interface and were never intended to be used by any other project,
+# only with the internal, Android SDK executables.  Therefore, the
+# Android SDK executables use private libraries located in
+# /usr/lib/android
+
+binary-or-shlib-defines-rpath
diff -Nru android-platform-system-core-7.0.0+r1/debian/changelog android-platform-system-core-7.0.0+r1/debian/changelog
--- android-platform-system-core-7.0.0+r1/debian/changelog	2017-02-28 23:45:05.000000000 +0100
+++ android-platform-system-core-7.0.0+r1/debian/changelog	2017-03-21 21:24:59.000000000 +0100
@@ -1,3 +1,11 @@
+android-platform-system-core (1:7.0.0+r1-4) unstable; urgency=medium
+
+  * transitional dummy packages for android-tools-adb / android-tools-fastboot
+  * move adb log file to proper dir (Closes: #823792, #688280)
+  * import upstream 7.0.0_r31 fixes for CVE-2016-3861 (Closes: #858177)
+
+ -- Hans-Christoph Steiner <hans at eds.org>  Wed, 15 Mar 2017 13:47:44 +0100
+
 android-platform-system-core (1:7.0.0+r1-3) unstable; urgency=medium
 
   * install bash-completion for adb and fastboot (Closes: #856418, #856419)
diff -Nru android-platform-system-core-7.0.0+r1/debian/fastboot.lintian-overrides android-platform-system-core-7.0.0+r1/debian/fastboot.lintian-overrides
--- android-platform-system-core-7.0.0+r1/debian/fastboot.lintian-overrides	2016-01-13 23:23:40.000000000 +0100
+++ android-platform-system-core-7.0.0+r1/debian/fastboot.lintian-overrides	2017-03-27 09:05:23.000000000 +0200
@@ -1,3 +1,12 @@
-# Executables of Android SDK uses private libraries located in /usr/lib/android
+# Executables from the Android SDK normally each staticly link in all
+# of the libs.  That means each executable includes a full copy of all
+# the libs, which is not how Debian works.  These libs need to be
+# dynamically linlked in so that just the library can be updated when
+# there is a security fix, instead of requiring all of the executables
+# be recompiled.  That said, these libraries do not have a stable
+# interface and were never intended to be used by any other project,
+# only with the internal, Android SDK executables.  Therefore, the
+# Android SDK executables use private libraries located in
+# /usr/lib/android
 
-binary-or-shlib-defines-rpath
\ No newline at end of file
+binary-or-shlib-defines-rpath
diff -Nru android-platform-system-core-7.0.0+r1/debian/img2simg.lintian-overrides android-platform-system-core-7.0.0+r1/debian/img2simg.lintian-overrides
--- android-platform-system-core-7.0.0+r1/debian/img2simg.lintian-overrides	1970-01-01 01:00:00.000000000 +0100
+++ android-platform-system-core-7.0.0+r1/debian/img2simg.lintian-overrides	2017-03-27 09:04:45.000000000 +0200
@@ -0,0 +1,12 @@
+# Executables from the Android SDK normally each staticly link in all
+# of the libs.  That means each executable includes a full copy of all
+# the libs, which is not how Debian works.  These libs need to be
+# dynamically linlked in so that just the library can be updated when
+# there is a security fix, instead of requiring all of the executables
+# be recompiled.  That said, these libraries do not have a stable
+# interface and were never intended to be used by any other project,
+# only with the internal, Android SDK executables.  Therefore, the
+# Android SDK executables use private libraries located in
+# /usr/lib/android
+
+binary-or-shlib-defines-rpath
diff -Nru android-platform-system-core-7.0.0+r1/debian/patches/import-7.0.0_r31.patch android-platform-system-core-7.0.0+r1/debian/patches/import-7.0.0_r31.patch
--- android-platform-system-core-7.0.0+r1/debian/patches/import-7.0.0_r31.patch	1970-01-01 01:00:00.000000000 +0100
+++ android-platform-system-core-7.0.0+r1/debian/patches/import-7.0.0_r31.patch	2017-03-21 21:22:51.000000000 +0100
@@ -0,0 +1,487 @@
+--- a/debuggerd/debuggerd.cpp
++++ b/debuggerd/debuggerd.cpp
+@@ -183,6 +183,16 @@
+    return allowed;
+ }
+ 
++static bool pid_contains_tid(pid_t pid, pid_t tid) {
++  char task_path[PATH_MAX];
++  if (snprintf(task_path, PATH_MAX, "/proc/%d/task/%d", pid, tid) >= PATH_MAX) {
++    ALOGE("debuggerd: task path overflow (pid = %d, tid = %d)\n", pid, tid);
++    exit(1);
++  }
++
++  return access(task_path, F_OK) == 0;
++}
++
+ static int read_request(int fd, debugger_request_t* out_request) {
+   ucred cr;
+   socklen_t len = sizeof(cr);
+@@ -227,16 +237,13 @@
+ 
+   if (msg.action == DEBUGGER_ACTION_CRASH) {
+     // Ensure that the tid reported by the crashing process is valid.
+-    char buf[64];
+-    struct stat s;
+-    snprintf(buf, sizeof buf, "/proc/%d/task/%d", out_request->pid, out_request->tid);
+-    if (stat(buf, &s)) {
+-      ALOGE("tid %d does not exist in pid %d. ignoring debug request\n",
+-          out_request->tid, out_request->pid);
++    // This check needs to happen again after ptracing the requested thread to prevent a race.
++    if (!pid_contains_tid(out_request->pid, out_request->tid)) {
++      ALOGE("tid %d does not exist in pid %d. ignoring debug request\n", out_request->tid,
++            out_request->pid);
+       return -1;
+     }
+-  } else if (cr.uid == 0
+-            || (cr.uid == AID_SYSTEM && msg.action == DEBUGGER_ACTION_DUMP_BACKTRACE)) {
++  } else if (cr.uid == 0 || (cr.uid == AID_SYSTEM && msg.action == DEBUGGER_ACTION_DUMP_BACKTRACE)) {
+     // Only root or system can ask us to attach to any process and dump it explicitly.
+     // However, system is only allowed to collect backtraces but cannot dump tombstones.
+     status = get_process_info(out_request->tid, &out_request->pid,
+@@ -413,10 +420,31 @@
+ }
+ #endif
+ 
++// Attach to a thread, and verify that it's still a member of the given process
++static bool ptrace_attach_thread(pid_t pid, pid_t tid) {
++  if (ptrace(PTRACE_ATTACH, tid, 0, 0) != 0) {
++    return false;
++  }
++
++  // Make sure that the task we attached to is actually part of the pid we're dumping.
++  if (!pid_contains_tid(pid, tid)) {
++    if (ptrace(PTRACE_DETACH, tid, 0, 0) != 0) {
++      ALOGE("debuggerd: failed to detach from thread '%d'", tid);
++      exit(1);
++    }
++    return false;
++  }
++
++  return true;
++}
++
+ static void ptrace_siblings(pid_t pid, pid_t main_tid, std::set<pid_t>& tids) {
+-  char task_path[64];
++  char task_path[PATH_MAX];
+ 
+-  snprintf(task_path, sizeof(task_path), "/proc/%d/task", pid);
++  if (snprintf(task_path, PATH_MAX, "/proc/%d/task", pid) >= PATH_MAX) {
++    ALOGE("debuggerd: task path overflow (pid = %d)\n", pid);
++    abort();
++  }
+ 
+   std::unique_ptr<DIR, int (*)(DIR*)> d(opendir(task_path), closedir);
+ 
+@@ -443,7 +471,7 @@
+       continue;
+     }
+ 
+-    if (ptrace(PTRACE_ATTACH, tid, 0, 0) < 0) {
++    if (!ptrace_attach_thread(pid, tid)) {
+       ALOGE("debuggerd: ptrace attach to %d failed: %s", tid, strerror(errno));
+       continue;
+     }
+@@ -568,11 +596,33 @@
+   // debugger_signal_handler().
+ 
+   // Attach to the target process.
+-  if (ptrace(PTRACE_ATTACH, request.tid, 0, 0) != 0) {
++  if (!ptrace_attach_thread(request.pid, request.tid)) {
+     ALOGE("debuggerd: ptrace attach failed: %s", strerror(errno));
+     exit(1);
+   }
+ 
++  // DEBUGGER_ACTION_CRASH requests can come from arbitrary processes and the tid field in the
++  // request is sent from the other side. If an attacker can cause a process to be spawned with the
++  // pid of their process, they could trick debuggerd into dumping that process by exiting after
++  // sending the request. Validate the trusted request.uid/gid to defend against this.
++  if (request.action == DEBUGGER_ACTION_CRASH) {
++    pid_t pid;
++    uid_t uid;
++    gid_t gid;
++    if (get_process_info(request.tid, &pid, &uid, &gid) != 0) {
++      ALOGE("debuggerd: failed to get process info for tid '%d'", request.tid);
++      exit(1);
++    }
++
++    if (pid != request.pid || uid != request.uid || gid != request.gid) {
++      ALOGE(
++        "debuggerd: attached task %d does not match request: "
++        "expected pid=%d,uid=%d,gid=%d, actual pid=%d,uid=%d,gid=%d",
++        request.tid, request.pid, request.uid, request.gid, pid, uid, gid);
++      exit(1);
++    }
++  }
++
+   // Don't attach to the sibling threads if we want to attach gdb.
+   // Supposedly, it makes the process less reliable.
+   bool attach_gdb = should_attach_gdb(request);
+--- a/include/android/log.h
++++ b/include/android/log.h
+@@ -89,6 +89,11 @@
+ } android_LogPriority;
+ 
+ /*
++ * Release any logger resources (a new log write will immediately re-acquire)
++ */
++void __android_log_close();
++
++/*
+  * Send a simple string to the log.
+  */
+ int __android_log_write(int prio, const char *tag, const char *text);
+--- a/include/sysutils/FrameworkListener.h
++++ b/include/sysutils/FrameworkListener.h
+@@ -32,6 +32,7 @@
+     int mCommandCount;
+     bool mWithSeq;
+     FrameworkCommandCollection *mCommands;
++    bool mSkipToNextNullByte;
+ 
+ public:
+     FrameworkListener(const char *socketName);
+--- a/include/utils/Unicode.h
++++ b/include/utils/Unicode.h
+@@ -88,7 +88,7 @@
+  * "dst" becomes \xE3\x81\x82\xE3\x81\x84
+  * (note that "dst" is NOT null-terminated, like strncpy)
+  */
+-void utf32_to_utf8(const char32_t* src, size_t src_len, char* dst);
++void utf32_to_utf8(const char32_t* src, size_t src_len, char* dst, size_t dst_len);
+ 
+ /**
+  * Returns the unicode value at "index".
+@@ -110,7 +110,7 @@
+  * enough to fit the UTF-16 as measured by utf16_to_utf8_length with an added
+  * NULL terminator.
+  */
+-void utf16_to_utf8(const char16_t* src, size_t src_len, char* dst);
++void utf16_to_utf8(const char16_t* src, size_t src_len, char* dst, size_t dst_len);
+ 
+ /**
+  * Returns the length of "src" when "src" is valid UTF-8 string.
+--- a/liblog/logger_write.c
++++ b/liblog/logger_write.c
+@@ -132,6 +132,41 @@
+     }
+     return kLogNotAvailable;
+ }
++/*
++ * Release any logger resources. A new log write will immediately re-acquire.
++ */
++LIBLOG_ABI_PUBLIC void __android_log_close()
++{
++    struct android_log_transport_write *transport;
++
++    __android_log_lock();
++
++    write_to_log = __write_to_log_init;
++
++    /*
++     * Threads that are actively writing at this point are not held back
++     * by a lock and are at risk of dropping the messages with a return code
++     * -EBADF. Prefer to return error code than add the overhead of a lock to
++     * each log writing call to guarantee delivery. In addition, anyone
++     * calling this is doing so to release the logging resources and shut down,
++     * for them to do so with outstanding log requests in other threads is a
++     * disengenuous use of this function.
++     */
++
++    write_transport_for_each(transport, &__android_log_persist_write) {
++        if (transport->close) {
++            (*transport->close)();
++        }
++    }
++
++    write_transport_for_each(transport, &__android_log_transport_write) {
++        if (transport->close) {
++            (*transport->close)();
++        }
++    }
++
++    __android_log_unlock();
++}
+ 
+ /* log_init_lock assumed */
+ static int __write_to_log_initialize()
+--- a/liblog/tests/liblog_test.cpp
++++ b/liblog/tests/liblog_test.cpp
+@@ -132,12 +132,17 @@
+     ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
+         LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
+ 
++    // Check that we can close and reopen the logger
+     log_time ts(CLOCK_MONOTONIC);
+-
+     ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
++    __android_log_close();
++
++    log_time ts1(CLOCK_MONOTONIC);
++    ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1)));
+     usleep(1000000);
+ 
+     int count = 0;
++    int second_count = 0;
+ 
+     for (;;) {
+         log_msg log_msg;
+@@ -161,10 +166,13 @@
+         log_time tx(eventData + 4 + 1);
+         if (ts == tx) {
+             ++count;
++        } else if (ts1 == tx) {
++            ++second_count;
+         }
+     }
+ 
+     EXPECT_EQ(1, count);
++    EXPECT_EQ(1, second_count);
+ 
+     android_logger_list_close(logger_list);
+ }
+--- a/libsysutils/src/FrameworkListener.cpp
++++ b/libsysutils/src/FrameworkListener.cpp
+@@ -49,6 +49,7 @@
+     errorRate = 0;
+     mCommandCount = 0;
+     mWithSeq = withSeq;
++    mSkipToNextNullByte = false;
+ }
+ 
+ bool FrameworkListener::onDataAvailable(SocketClient *c) {
+@@ -59,10 +60,15 @@
+     if (len < 0) {
+         SLOGE("read() failed (%s)", strerror(errno));
+         return false;
+-    } else if (!len)
++    } else if (!len) {
+         return false;
+-   if(buffer[len-1] != '\0')
++    } else if (buffer[len-1] != '\0') {
+         SLOGW("String is not zero-terminated");
++        android_errorWriteLog(0x534e4554, "29831647");
++        c->sendMsg(500, "Command too large for buffer", false);
++        mSkipToNextNullByte = true;
++        return false;
++    }
+ 
+     int offset = 0;
+     int i;
+@@ -70,11 +76,16 @@
+     for (i = 0; i < len; i++) {
+         if (buffer[i] == '\0') {
+             /* IMPORTANT: dispatchCommand() expects a zero-terminated string */
+-            dispatchCommand(c, buffer + offset);
++            if (mSkipToNextNullByte) {
++                mSkipToNextNullByte = false;
++            } else {
++                dispatchCommand(c, buffer + offset);
++            }
+             offset = i + 1;
+         }
+     }
+ 
++    mSkipToNextNullByte = false;
+     return true;
+ }
+ 
+--- a/libutils/String8.cpp
++++ b/libutils/String8.cpp
+@@ -104,20 +104,21 @@
+ {
+     if (len == 0) return getEmptyString();
+ 
+-    const ssize_t bytes = utf16_to_utf8_length(in, len);
+-    if (bytes < 0) {
++     // Allow for closing '\0'
++    const ssize_t resultStrLen = utf16_to_utf8_length(in, len) + 1;
++    if (resultStrLen < 1) {
+         return getEmptyString();
+     }
+ 
+-    SharedBuffer* buf = SharedBuffer::alloc(bytes+1);
++    SharedBuffer* buf = SharedBuffer::alloc(resultStrLen);
+     ALOG_ASSERT(buf, "Unable to allocate shared buffer");
+     if (!buf) {
+         return getEmptyString();
+     }
+ 
+-    char* str = (char*)buf->data();
+-    utf16_to_utf8(in, len, str);
+-    return str;
++    char* resultStr = (char*)buf->data();
++    utf16_to_utf8(in, len, resultStr, resultStrLen);
++    return resultStr;
+ }
+ 
+ static char* allocFromUTF32(const char32_t* in, size_t len)
+@@ -126,21 +127,21 @@
+         return getEmptyString();
+     }
+ 
+-    const ssize_t bytes = utf32_to_utf8_length(in, len);
+-    if (bytes < 0) {
++    const ssize_t resultStrLen = utf32_to_utf8_length(in, len) + 1;
++    if (resultStrLen < 1) {
+         return getEmptyString();
+     }
+ 
+-    SharedBuffer* buf = SharedBuffer::alloc(bytes+1);
++    SharedBuffer* buf = SharedBuffer::alloc(resultStrLen);
+     ALOG_ASSERT(buf, "Unable to allocate shared buffer");
+     if (!buf) {
+         return getEmptyString();
+     }
+ 
+-    char* str = (char*) buf->data();
+-    utf32_to_utf8(in, len, str);
++    char* resultStr = (char*) buf->data();
++    utf32_to_utf8(in, len, resultStr, resultStrLen);
+ 
+-    return str;
++    return resultStr;
+ }
+ 
+ // ---------------------------------------------------------------------------
+--- a/libutils/Unicode.cpp
++++ b/libutils/Unicode.cpp
+@@ -14,6 +14,7 @@
+  * limitations under the License.
+  */
+ 
++#include <log/log.h>
+ #include <utils/Unicode.h>
+ 
+ #include <stddef.h>
+@@ -182,7 +183,7 @@
+     return ret;
+ }
+ 
+-void utf32_to_utf8(const char32_t* src, size_t src_len, char* dst)
++void utf32_to_utf8(const char32_t* src, size_t src_len, char* dst, size_t dst_len)
+ {
+     if (src == NULL || src_len == 0 || dst == NULL) {
+         return;
+@@ -193,9 +194,12 @@
+     char *cur = dst;
+     while (cur_utf32 < end_utf32) {
+         size_t len = utf32_codepoint_utf8_length(*cur_utf32);
++        LOG_ALWAYS_FATAL_IF(dst_len < len, "%zu < %zu", dst_len, len);
+         utf32_codepoint_to_utf8((uint8_t *)cur, *cur_utf32++, len);
+         cur += len;
++        dst_len -= len;
+     }
++    LOG_ALWAYS_FATAL_IF(dst_len < 1, "dst_len < 1: %zu < 1", dst_len);
+     *cur = '\0';
+ }
+ 
+@@ -348,7 +352,7 @@
+            : 0);
+ }
+ 
+-void utf16_to_utf8(const char16_t* src, size_t src_len, char* dst)
++void utf16_to_utf8(const char16_t* src, size_t src_len, char* dst, size_t dst_len)
+ {
+     if (src == NULL || src_len == 0 || dst == NULL) {
+         return;
+@@ -369,9 +373,12 @@
+             utf32 = (char32_t) *cur_utf16++;
+         }
+         const size_t len = utf32_codepoint_utf8_length(utf32);
++        LOG_ALWAYS_FATAL_IF(dst_len < len, "%zu < %zu", dst_len, len);
+         utf32_codepoint_to_utf8((uint8_t*)cur, utf32, len);
+         cur += len;
++        dst_len -= len;
+     }
++    LOG_ALWAYS_FATAL_IF(dst_len < 1, "%zu < 1", dst_len);
+     *cur = '\0';
+ }
+ 
+@@ -432,10 +439,10 @@
+     const char16_t* const end = src + src_len;
+     while (src < end) {
+         if ((*src & 0xFC00) == 0xD800 && (src + 1) < end
+-                && (*++src & 0xFC00) == 0xDC00) {
++                && (*(src + 1) & 0xFC00) == 0xDC00) {
+             // surrogate pairs are always 4 bytes.
+             ret += 4;
+-            src++;
++            src += 2;
+         } else {
+             ret += utf32_codepoint_utf8_length((char32_t) *src++);
+         }
+--- a/libutils/tests/String8_test.cpp
++++ b/libutils/tests/String8_test.cpp
+@@ -17,6 +17,7 @@
+ #define LOG_TAG "String8_test"
+ #include <utils/Log.h>
+ #include <utils/String8.h>
++#include <utils/String16.h>
+ 
+ #include <gtest/gtest.h>
+ 
+@@ -77,4 +78,22 @@
+     EXPECT_EQ(NO_MEMORY, String8("").setTo(in, SIZE_MAX));
+ }
+ 
++// http://b/29250543
++TEST_F(String8Test, CorrectInvalidSurrogate) {
++    // d841d8 is an invalid start for a surrogate pair. Make sure this is handled by ignoring the
++    // first character in the pair and handling the rest correctly.
++    String16 string16(u"\xd841\xd841\xdc41\x0000");
++    String8 string8(string16);
++
++    EXPECT_EQ(4U, string8.length());
++}
++
++TEST_F(String8Test, CheckUtf32Conversion) {
++    // Since bound checks were added, check the conversion can be done without fatal errors.
++    // The utf8 lengths of these are chars are 1 + 2 + 3 + 4 = 10.
++    const char32_t string32[] = U"\x0000007f\x000007ff\x0000911\x0010fffe";
++    String8 string8(string32);
++    EXPECT_EQ(10U, string8.length());
++}
++
+ }
+--- a/libziparchive/zip_archive.cc
++++ b/libziparchive/zip_archive.cc
+@@ -269,9 +269,14 @@
+    * Grab the CD offset and size, and the number of entries in the
+    * archive and verify that they look reasonable.
+    */
+-  if (eocd->cd_start_offset + eocd->cd_size > eocd_offset) {
++  if (static_cast<off64_t>(eocd->cd_start_offset) + eocd->cd_size > eocd_offset) {
+     ALOGW("Zip: bad offsets (dir %" PRIu32 ", size %" PRIu32 ", eocd %" PRId64 ")",
+         eocd->cd_start_offset, eocd->cd_size, static_cast<int64_t>(eocd_offset));
++#if defined(__ANDROID__)
++    if (eocd->cd_start_offset + eocd->cd_size <= eocd_offset) {
++      android_errorWriteLog(0x534e4554, "31251826");
++    }
++#endif
+     return kInvalidOffset;
+   }
+   if (eocd->num_records == 0) {
+--- a/rootdir/Android.mk
++++ b/rootdir/Android.mk
+@@ -56,6 +56,7 @@
+ LOCAL_POST_INSTALL_CMD := mkdir -p $(addprefix $(TARGET_ROOT_OUT)/, \
+     sbin dev proc sys system data oem acct cache config storage mnt root $(BOARD_ROOT_EXTRA_FOLDERS)); \
+     ln -sf /system/etc $(TARGET_ROOT_OUT)/etc; \
++    ln -sf /data/user_de/0/com.android.shell/files/bugreports $(TARGET_ROOT_OUT)/bugreports; \
+     ln -sf /sys/kernel/debug $(TARGET_ROOT_OUT)/d; \
+     ln -sf /storage/self/primary $(TARGET_ROOT_OUT)/sdcard
+ ifdef BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE
+--- a/rootdir/init.rc
++++ b/rootdir/init.rc
+@@ -414,10 +414,6 @@
+ 
+     mkdir /data/anr 0775 system system
+ 
+-    # symlink to bugreport storage location
+-    rm /data/bugreports
+-    symlink /data/user_de/0/com.android.shell/files/bugreports /data/bugreports
+-
+     # Separate location for storing security policy files on data
+     mkdir /data/security 0711 system system
+ 
diff -Nru android-platform-system-core-7.0.0+r1/debian/patches/series android-platform-system-core-7.0.0+r1/debian/patches/series
--- android-platform-system-core-7.0.0+r1/debian/patches/series	2017-02-28 23:45:05.000000000 +0100
+++ android-platform-system-core-7.0.0+r1/debian/patches/series	2017-03-21 21:22:18.000000000 +0100
@@ -1,3 +1,4 @@
+import-7.0.0_r31.patch
 libandroidcutils_makefile_pkgconfig
 add_missing_headers.diff
 use_separated_cutils_atomic.diff
diff -Nru android-platform-system-core-7.0.0+r1/debian/simg2img.lintian-overrides android-platform-system-core-7.0.0+r1/debian/simg2img.lintian-overrides
--- android-platform-system-core-7.0.0+r1/debian/simg2img.lintian-overrides	1970-01-01 01:00:00.000000000 +0100
+++ android-platform-system-core-7.0.0+r1/debian/simg2img.lintian-overrides	2017-03-27 09:05:23.000000000 +0200
@@ -0,0 +1,12 @@
+# Executables from the Android SDK normally each staticly link in all
+# of the libs.  That means each executable includes a full copy of all
+# the libs, which is not how Debian works.  These libs need to be
+# dynamically linlked in so that just the library can be updated when
+# there is a security fix, instead of requiring all of the executables
+# be recompiled.  That said, these libraries do not have a stable
+# interface and were never intended to be used by any other project,
+# only with the internal, Android SDK executables.  Therefore, the
+# Android SDK executables use private libraries located in
+# /usr/lib/android
+
+binary-or-shlib-defines-rpath


More information about the Android-tools-devel mailing list