Verify memory address range validity in GDBRemoteCommunicationClient

Summary:
This aims to verify the validity of the response from the debugging
server in GDBRemoteCommunicationClient::GetMemoryRegionInfo. I was
working with ds2 (https://github.com/facebook/ds2) and encountered a bug
that caused the server's response to have a 'size' value of 0, which
caused lldb to behave incorrectly.

Reviewers: k8stone, labath, clayborg

Reviewed By: labath, clayborg

Subscribers: clayborg, sas, lldb-commits

Differential Revision: https://reviews.llvm.org/D31485

Change by Alex Langford <apl@fb.com>

llvm-svn: 299239
This commit is contained in:
Stephane Sezer 2017-03-31 18:00:48 +00:00
parent 303abb803a
commit 48d1427c30
2 changed files with 51 additions and 7 deletions

View File

@ -1503,13 +1503,18 @@ Error GDBRemoteCommunicationClient::GetMemoryRegionInfo(
}
}
// We got a valid address range back but no permissions -- which means
// this is an unmapped page
if (region_info.GetRange().IsValid() && saw_permissions == false) {
region_info.SetReadable(MemoryRegionInfo::eNo);
region_info.SetWritable(MemoryRegionInfo::eNo);
region_info.SetExecutable(MemoryRegionInfo::eNo);
region_info.SetMapped(MemoryRegionInfo::eNo);
if (region_info.GetRange().IsValid()) {
// We got a valid address range back but no permissions -- which means
// this is an unmapped page
if (!saw_permissions) {
region_info.SetReadable(MemoryRegionInfo::eNo);
region_info.SetWritable(MemoryRegionInfo::eNo);
region_info.SetExecutable(MemoryRegionInfo::eNo);
region_info.SetMapped(MemoryRegionInfo::eNo);
}
} else {
// We got an invalid address range back
error.SetErrorString("Server returned invalid range");
}
} else {
m_supports_memory_region_info = eLazyBoolNo;

View File

@ -13,6 +13,7 @@
#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/StructuredData.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Utility/DataBuffer.h"
#include "llvm/ADT/ArrayRef.h"
@ -331,3 +332,41 @@ TEST_F(GDBRemoteCommunicationClientTest, SendSignalsToIgnore) {
HandlePacket(server, "QPassSignals:", "OK");
EXPECT_TRUE(result.get().Success());
}
TEST_F(GDBRemoteCommunicationClientTest, GetMemoryRegionInfo) {
TestClient client;
MockServer server;
Connect(client, server);
if (HasFailure())
return;
const lldb::addr_t addr = 0xa000;
MemoryRegionInfo region_info;
std::future<Error> result = std::async(std::launch::async, [&] {
return client.GetMemoryRegionInfo(addr, region_info);
});
// name is: /foo/bar.so
HandlePacket(server,
"qMemoryRegionInfo:a000",
"start:a000;size:2000;permissions:rx;name:2f666f6f2f6261722e736f;");
EXPECT_TRUE(result.get().Success());
}
TEST_F(GDBRemoteCommunicationClientTest, GetMemoryRegionInfoInvalidResponse) {
TestClient client;
MockServer server;
Connect(client, server);
if (HasFailure())
return;
const lldb::addr_t addr = 0x4000;
MemoryRegionInfo region_info;
std::future<Error> result = std::async(std::launch::async, [&] {
return client.GetMemoryRegionInfo(addr, region_info);
});
HandlePacket(server, "qMemoryRegionInfo:4000", "start:4000;size:0000;");
EXPECT_FALSE(result.get().Success());
}