Merge changes I75017420,I3612e131 am: e3f4b84468 am: de50c0081b

Original change: https://android-review.googlesource.com/c/platform/system/core/+/1935479

Change-Id: Ib6fc84794c8273affb34886a6d5e9d19f477dd57
diff --git a/fastboot/device/commands.cpp b/fastboot/device/commands.cpp
index 4042531..b9f6c97 100644
--- a/fastboot/device/commands.cpp
+++ b/fastboot/device/commands.cpp
@@ -268,10 +268,18 @@
     }
 
     // arg[0] is the command name, arg[1] contains size of data to be downloaded
+    // which should always be 8 bytes
+    if (args[1].length() != 8) {
+        return device->WriteStatus(FastbootResult::FAIL,
+                                   "Invalid size (length of size != 8)");
+    }
     unsigned int size;
     if (!android::base::ParseUint("0x" + args[1], &size, kMaxDownloadSizeDefault)) {
         return device->WriteStatus(FastbootResult::FAIL, "Invalid size");
     }
+    if (size == 0) {
+        return device->WriteStatus(FastbootResult::FAIL, "Invalid size (0)");
+    }
     device->download_data().resize(size);
     if (!device->WriteStatus(FastbootResult::DATA, android::base::StringPrintf("%08x", size))) {
         return false;
diff --git a/fastboot/device/fastboot_device.cpp b/fastboot/device/fastboot_device.cpp
index e6a834e..ae225de 100644
--- a/fastboot/device/fastboot_device.cpp
+++ b/fastboot/device/fastboot_device.cpp
@@ -186,6 +186,11 @@
             PLOG(ERROR) << "Couldn't read command";
             return;
         }
+        if (std::count_if(command, command + bytes_read, iscntrl) != 0) {
+            WriteStatus(FastbootResult::FAIL,
+                        "Command contains control character");
+            continue;
+        }
         command[bytes_read] = '\0';
 
         LOG(INFO) << "Fastboot command: " << command;
diff --git a/fastboot/fuzzy_fastboot/main.cpp b/fastboot/fuzzy_fastboot/main.cpp
index b6beaf9..8593adc 100644
--- a/fastboot/fuzzy_fastboot/main.cpp
+++ b/fastboot/fuzzy_fastboot/main.cpp
@@ -890,28 +890,51 @@
 
 TEST_F(Fuzz, BadCommandTooLarge) {
     std::string s = RandomString(FB_COMMAND_SZ + 1, rand_legal);
-    EXPECT_EQ(fb->RawCommand(s), DEVICE_FAIL)
+    RetCode ret = fb->RawCommand(s);
+    EXPECT_TRUE(ret == DEVICE_FAIL || ret == IO_ERROR)
             << "Device did not respond with failure after sending length " << s.size()
             << " string of random ASCII chars";
+    if (ret == IO_ERROR) EXPECT_EQ(transport->Reset(), 0) << "USB reset failed";
     std::string s1 = RandomString(1000, rand_legal);
-    EXPECT_EQ(fb->RawCommand(s1), DEVICE_FAIL)
+    ret = fb->RawCommand(s1);
+    EXPECT_TRUE(ret == DEVICE_FAIL || ret == IO_ERROR)
             << "Device did not respond with failure after sending length " << s1.size()
             << " string of random ASCII chars";
+    if (ret == IO_ERROR) EXPECT_EQ(transport->Reset(), 0) << "USB reset failed";
     std::string s2 = RandomString(1000, rand_illegal);
-    EXPECT_EQ(fb->RawCommand(s2), DEVICE_FAIL)
-            << "Device did not respond with failure after sending length " << s1.size()
+    ret = fb->RawCommand(s2);
+    EXPECT_TRUE(ret == DEVICE_FAIL || ret == IO_ERROR)
+            << "Device did not respond with failure after sending length " << s2.size()
             << " string of random non-ASCII chars";
+    if (ret == IO_ERROR) EXPECT_EQ(transport->Reset(), 0) << "USB reset failed";
     std::string s3 = RandomString(1000, rand_char);
-    EXPECT_EQ(fb->RawCommand(s3), DEVICE_FAIL)
-            << "Device did not respond with failure after sending length " << s1.size()
+    ret = fb->RawCommand(s3);
+    EXPECT_TRUE(ret == DEVICE_FAIL || ret == IO_ERROR)
+            << "Device did not respond with failure after sending length " << s3.size()
             << " string of random chars";
+    if (ret == IO_ERROR) EXPECT_EQ(transport->Reset(), 0) << "USB reset failed";
+
+    std::string s4 = RandomString(10 * 1024 * 1024, rand_legal);
+    ret = fb->RawCommand(s);
+    EXPECT_TRUE(ret == DEVICE_FAIL || ret == IO_ERROR)
+            << "Device did not respond with failure after sending length " << s4.size()
+            << " string of random ASCII chars ";
+    if (ret == IO_ERROR) EXPECT_EQ(transport->Reset(), 0) << "USB reset failed";
+
+    ASSERT_TRUE(UsbStillAvailible()) << USB_PORT_GONE;
+    std::string resp;
+    EXPECT_EQ(fb->GetVar("product", &resp), SUCCESS)
+                << "Device is unresponsive to getvar command";
 }
 
 TEST_F(Fuzz, CommandTooLarge) {
     for (const std::string& s : CMDS) {
         std::string rs = RandomString(1000, rand_char);
-        EXPECT_EQ(fb->RawCommand(s + rs), DEVICE_FAIL)
-                << "Device did not respond with failure after '" << s + rs << "'";
+        RetCode ret;
+        ret = fb->RawCommand(s + rs);
+        EXPECT_TRUE(ret == DEVICE_FAIL || ret == IO_ERROR)
+                << "Device did not respond with failure " << ret << "after '" << s + rs << "'";
+        if (ret == IO_ERROR) EXPECT_EQ(transport->Reset(), 0) << "USB reset failed";
         ASSERT_TRUE(UsbStillAvailible()) << USB_PORT_GONE;
         std::string resp;
         EXPECT_EQ(fb->GetVar("product", &resp), SUCCESS)