[Lldb-commits] [lldb] 3427cb5 - [lldb] Prevent an infinite loop while reading memory regions

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Fri Nov 25 02:55:49 PST 2022


Author: Pavel Labath
Date: 2022-11-25T11:55:41+01:00
New Revision: 3427cb5b3a55a454e5750f6318ced8a5d7c1442d

URL: https://github.com/llvm/llvm-project/commit/3427cb5b3a55a454e5750f6318ced8a5d7c1442d
DIFF: https://github.com/llvm/llvm-project/commit/3427cb5b3a55a454e5750f6318ced8a5d7c1442d.diff

LOG: [lldb] Prevent an infinite loop  while reading memory regions

A malformed qMemoryRegionInfo response can easily trigger an infinite
loop if regions end (base + size) wraps the address space. A
particularly interesting is the case where base+size=0, which a stub
could use to say that the rest of the memory space is unmapped, even
though lldb expects 0xff... in this case.

One could argue which behavior is more correct (technically, the
current behavior does not say anything about the last byte), but unless
we stop using 0xff... to mean "invalid address", that discussion is very
academic. This patch truncates address ranges which wraps the address
space, which handles the zero case as well as other kinds of malformed
packets.

Added: 
    lldb/test/API/functionalities/gdb_remote_client/TestGdbClientMemoryRegions.py

Modified: 
    lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index f03fd4231c74a..347c47b078f45 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -1527,8 +1527,14 @@ Status GDBRemoteCommunicationClient::GetMemoryRegionInfo(
           if (!value.getAsInteger(16, addr_value))
             region_info.GetRange().SetRangeBase(addr_value);
         } else if (name.equals("size")) {
-          if (!value.getAsInteger(16, addr_value))
+          if (!value.getAsInteger(16, addr_value)) {
             region_info.GetRange().SetByteSize(addr_value);
+            if (region_info.GetRange().GetRangeEnd() <
+                region_info.GetRange().GetRangeBase()) {
+              // Range size overflowed, truncate it.
+              region_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
+            }
+          }
         } else if (name.equals("permissions") &&
                    region_info.GetRange().IsValid()) {
           saw_permissions = true;

diff  --git a/lldb/test/API/functionalities/gdb_remote_client/TestGdbClientMemoryRegions.py b/lldb/test/API/functionalities/gdb_remote_client/TestGdbClientMemoryRegions.py
new file mode 100644
index 0000000000000..c6ad39bcdc72f
--- /dev/null
+++ b/lldb/test/API/functionalities/gdb_remote_client/TestGdbClientMemoryRegions.py
@@ -0,0 +1,44 @@
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from lldbsuite.test.gdbclientutils import *
+from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
+
+
+class TestGdbClientMemoryRegions(GDBRemoteTestBase):
+
+    def test(self):
+        """
+        Test handling of overflowing memory regions. In particular, make sure
+        they don't trigger an infinite loop.
+        """
+        class MyResponder(MockGDBServerResponder):
+
+            def qHostInfo(self):
+                return "ptrsize:8;endian:little;"
+
+            def qMemoryRegionInfo(self, addr):
+                if addr == 0:
+                    return "start:0;size:8000000000000000;permissions:rw;"
+                if addr == 0x8000000000000000:
+                    return "start:8000000000000000;size:8000000000000000;permissions:r;"
+
+        self.runCmd("log enable gdb-remote packets")
+        self.runCmd("log enable lldb temp")
+        self.server.responder = MyResponder()
+        target = self.dbg.CreateTarget('')
+        process = self.connect(target)
+
+        regions = process.GetMemoryRegions()
+        self.assertEqual(regions.GetSize(), 2)
+
+        region = lldb.SBMemoryRegionInfo()
+        self.assertTrue(regions.GetMemoryRegionAtIndex(0, region))
+        self.assertEqual(region.GetRegionBase(), 0)
+        self.assertEqual(region.GetRegionEnd(), 0x8000000000000000)
+        self.assertTrue(region.IsWritable())
+
+        self.assertTrue(regions.GetMemoryRegionAtIndex(1, region))
+        self.assertEqual(region.GetRegionBase(), 0x8000000000000000)
+        self.assertEqual(region.GetRegionEnd(), 0xffffffffffffffff)
+        self.assertFalse(region.IsWritable())


        


More information about the lldb-commits mailing list