summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoonas Kylmälä <joonas.kylmala@iki.fi>2018-08-27 13:58:55 -0400
committerJoonas Kylmälä <joonas.kylmala@iki.fi>2018-08-27 13:58:55 -0400
commit39c687ae4136c3a6372b419cf3780f3f39c7075c (patch)
treedf9844ed0f4b43645945a2cc0e0cd505987d3c58
parentadbc92cac57c55e349005d4e0ace67d67b429f72 (diff)
parentb6e95a58fe9109ea8aa6878535267df90dd39455 (diff)
downloadsystem_core-39c687ae4136c3a6372b419cf3780f3f39c7075c.tar.gz
system_core-39c687ae4136c3a6372b419cf3780f3f39c7075c.tar.bz2
system_core-39c687ae4136c3a6372b419cf3780f3f39c7075c.zip
-rw-r--r--libnetutils/packet.c14
-rw-r--r--libutils/String16.cpp66
-rw-r--r--libziparchive/zip_archive.cc18
-rw-r--r--libziparchive/zip_archive_test.cc53
-rw-r--r--rootdir/init.rc3
5 files changed, 124 insertions, 30 deletions
diff --git a/libnetutils/packet.c b/libnetutils/packet.c
index cd26d058a..bfc5f4d4e 100644
--- a/libnetutils/packet.c
+++ b/libnetutils/packet.c
@@ -219,6 +219,20 @@ int receive_packet(int s, struct dhcp_msg *msg)
* to construct the pseudo header used in the checksum calculation.
*/
dhcp_size = ntohs(packet.udp.len) - sizeof(packet.udp);
+ /*
+ * check validity of dhcp_size.
+ * 1) cannot be negative or zero.
+ * 2) src buffer contains enough bytes to copy
+ * 3) cannot exceed destination buffer
+ */
+ if ((dhcp_size <= 0) ||
+ ((int)(nread - sizeof(struct iphdr) - sizeof(struct udphdr)) < dhcp_size) ||
+ ((int)sizeof(struct dhcp_msg) < dhcp_size)) {
+#if VERBOSE
+ ALOGD("Malformed Packet");
+#endif
+ return -1;
+ }
saddr = packet.ip.saddr;
daddr = packet.ip.daddr;
nread = ntohs(packet.ip.tot_len);
diff --git a/libutils/String16.cpp b/libutils/String16.cpp
index 91efdaa39..21a036604 100644
--- a/libutils/String16.cpp
+++ b/libutils/String16.cpp
@@ -83,6 +83,23 @@ static char16_t* allocFromUTF8(const char* u8str, size_t u8len)
return getEmptyString();
}
+static char16_t* allocFromUTF16(const char16_t* u16str, size_t u16len) {
+ if (u16len >= SIZE_MAX / sizeof(char16_t)) {
+ android_errorWriteLog(0x534e4554, "73826242");
+ abort();
+ }
+
+ SharedBuffer* buf = SharedBuffer::alloc((u16len + 1) * sizeof(char16_t));
+ ALOG_ASSERT(buf, "Unable to allocate shared buffer");
+ if (buf) {
+ char16_t* str = (char16_t*)buf->data();
+ memcpy(str, u16str, u16len * sizeof(char16_t));
+ str[u16len] = 0;
+ return str;
+ }
+ return getEmptyString();
+}
+
// ---------------------------------------------------------------------------
String16::String16()
@@ -115,35 +132,9 @@ String16::String16(const String16& o, size_t len, size_t begin)
setTo(o, len, begin);
}
-String16::String16(const char16_t* o)
-{
- size_t len = strlen16(o);
- SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));
- ALOG_ASSERT(buf, "Unable to allocate shared buffer");
- if (buf) {
- char16_t* str = (char16_t*)buf->data();
- strcpy16(str, o);
- mString = str;
- return;
- }
-
- mString = getEmptyString();
-}
+String16::String16(const char16_t* o) : mString(allocFromUTF16(o, strlen16(o))) {}
-String16::String16(const char16_t* o, size_t len)
-{
- SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));
- ALOG_ASSERT(buf, "Unable to allocate shared buffer");
- if (buf) {
- char16_t* str = (char16_t*)buf->data();
- memcpy(str, o, len*sizeof(char16_t));
- str[len] = 0;
- mString = str;
- return;
- }
-
- mString = getEmptyString();
-}
+String16::String16(const char16_t* o, size_t len) : mString(allocFromUTF16(o, len)) {}
String16::String16(const String8& o)
: mString(allocFromUTF8(o.string(), o.size()))
@@ -200,6 +191,11 @@ status_t String16::setTo(const char16_t* other)
status_t String16::setTo(const char16_t* other, size_t len)
{
+ if (len >= SIZE_MAX / sizeof(char16_t)) {
+ android_errorWriteLog(0x534e4554, "73826242");
+ abort();
+ }
+
SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
->editResize((len+1)*sizeof(char16_t));
if (buf) {
@@ -222,7 +218,12 @@ status_t String16::append(const String16& other)
} else if (otherLen == 0) {
return NO_ERROR;
}
-
+
+ if (myLen >= SIZE_MAX / sizeof(char16_t) - otherLen) {
+ android_errorWriteLog(0x534e4554, "73826242");
+ abort();
+ }
+
SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
->editResize((myLen+otherLen+1)*sizeof(char16_t));
if (buf) {
@@ -243,7 +244,12 @@ status_t String16::append(const char16_t* chrs, size_t otherLen)
} else if (otherLen == 0) {
return NO_ERROR;
}
-
+
+ if (myLen >= SIZE_MAX / sizeof(char16_t) - otherLen) {
+ android_errorWriteLog(0x534e4554, "73826242");
+ abort();
+ }
+
SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
->editResize((myLen+otherLen+1)*sizeof(char16_t));
if (buf) {
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index 8c2c559b1..75f3262ea 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -552,6 +552,8 @@ static int32_t MapCentralDirectory(int fd, const char* debug_file_name,
return result;
}
+static inline ssize_t ReadAtOffset(int fd, uint8_t* buf, size_t len, off64_t off);
+
/*
* Parses the Zip archive's Central Directory. Allocates and populates the
* hash table.
@@ -630,6 +632,22 @@ static int32_t ParseZipArchive(ZipArchive* archive) {
return -1;
}
}
+
+ uint32_t lfh_start_bytes;
+ if (ReadAtOffset(archive->fd, reinterpret_cast<uint8_t*>(&lfh_start_bytes),
+ sizeof(uint32_t), 0) != sizeof(uint32_t)) {
+ ALOGW("Zip: Unable to read header for entry at offset == 0.");
+ return -1;
+ }
+
+ if (lfh_start_bytes != LocalFileHeader::kSignature) {
+ ALOGW("Zip: Entry at offset zero has invalid LFH signature %" PRIx32, lfh_start_bytes);
+#if defined(__ANDROID__)
+ android_errorWriteLog(0x534e4554, "64211847");
+#endif
+ return -1;
+ }
+
ALOGV("+++ zip good scan %" PRIu16 " entries", num_entries);
return 0;
diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc
index c79986957..1cb4a8a8d 100644
--- a/libziparchive/zip_archive_test.cc
+++ b/libziparchive/zip_archive_test.cc
@@ -530,6 +530,59 @@ TEST(ziparchive, ExtractToFile) {
close(fd);
}
+// A zip file whose local file header at offset zero is corrupted.
+//
+// ---------------
+// cat foo > a.txt
+// zip a.zip a.txt
+// cat a.zip | xxd -i
+//
+// Manual changes :
+// [2] = 0xff // Corrupt the LFH signature of entry 0.
+// [3] = 0xff // Corrupt the LFH signature of entry 0.
+static const uint8_t kZipFileWithBrokenLfhSignature[] = {
+ //[lfh-sig-----------], [lfh contents---------------------------------
+ 0x50, 0x4b, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80,
+ //--------------------------------------------------------------------
+ 0x09, 0x4b, 0xa8, 0x65, 0x32, 0x7e, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00,
+ //-------------------------------] [file-name-----------------], [---
+ 0x00, 0x00, 0x05, 0x00, 0x1c, 0x00, 0x61, 0x2e, 0x74, 0x78, 0x74, 0x55,
+ // entry-contents------------------------------------------------------
+ 0x54, 0x09, 0x00, 0x03, 0x51, 0x24, 0x8b, 0x59, 0x51, 0x24, 0x8b, 0x59,
+ //--------------------------------------------------------------------
+ 0x75, 0x78, 0x0b, 0x00, 0x01, 0x04, 0x89, 0x42, 0x00, 0x00, 0x04, 0x88,
+ //-------------------------------------], [cd-record-sig-------], [---
+ 0x13, 0x00, 0x00, 0x66, 0x6f, 0x6f, 0x0a, 0x50, 0x4b, 0x01, 0x02, 0x1e,
+ // cd-record-----------------------------------------------------------
+ 0x03, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80, 0x09, 0x4b, 0xa8,
+ //--------------------------------------------------------------------
+ 0x65, 0x32, 0x7e, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05,
+ //--------------------------------------------------------------------
+ 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa0,
+ //-] [lfh-file-header-off-], [file-name-----------------], [extra----
+ 0x81, 0x00, 0x00, 0x00, 0x00, 0x61, 0x2e, 0x74, 0x78, 0x74, 0x55, 0x54,
+ //--------------------------------------------------------------------
+ 0x05, 0x00, 0x03, 0x51, 0x24, 0x8b, 0x59, 0x75, 0x78, 0x0b, 0x00, 0x01,
+ //-------------------------------------------------------], [eocd-sig-
+ 0x04, 0x89, 0x42, 0x00, 0x00, 0x04, 0x88, 0x13, 0x00, 0x00, 0x50, 0x4b,
+ //-------], [---------------------------------------------------------
+ 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x4b, 0x00,
+ //-------------------------------------------]
+ 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+TEST(ziparchive, BrokenLfhSignature) {
+ char kTempFilePattern[] = "zip_archive_input_XXXXXX";
+ int fd = make_temporary_file(kTempFilePattern);
+ ASSERT_NE(-1, fd);
+
+ ASSERT_EQ(static_cast<int32_t>(sizeof(kZipFileWithBrokenLfhSignature)),
+ TEMP_FAILURE_RETRY(write(fd, kZipFileWithBrokenLfhSignature,
+ sizeof(kZipFileWithBrokenLfhSignature))));
+ ZipArchiveHandle handle;
+ ASSERT_EQ(-1, OpenArchiveFd(fd, "LeadingNonZipBytes", &handle));
+ close(fd);
+}
+
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 1c6fca642..cfcab625a 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -125,6 +125,9 @@ on init
write /proc/sys/net/ipv4/conf/all/accept_redirects 0
write /proc/sys/net/ipv6/conf/all/accept_redirects 0
+ # /proc/net/fib_trie leaks interface IP addresses
+ chmod 0400 /proc/net/fib_trie
+
# Create cgroup mount points for process groups
mkdir /dev/cpuctl
mount cgroup none /dev/cpuctl cpu