[Lldb-commits] [lldb] [lldb] [Mach-O] don't strip the end of the "kern ver str" LC_NOTE (PR #77538)
Jason Molenda via lldb-commits
lldb-commits at lists.llvm.org
Tue Jan 9 15:04:45 PST 2024
https://github.com/jasonmolenda created https://github.com/llvm/llvm-project/pull/77538
The "kern ver str" LC_NOTE gives lldb a kernel version string -- with a UUID and/or a load address (stext) to load it at. The LC_NOTE specifies a size of the identifier string in bytes. In ObjectFileMachO::GetIdentifierString, I copy that number of bytes into a std::string, and in case there were additional nul characters at the end of the sting for padding reasons, I tried to shrink the std::string to not include these extra nul's.
However, I did this resizing without handling the case of an empty identifier string. I don't know why any corefile creator would do that, but of course at least one does. This patch removes the resizing altogether; I was solving something that hasn't ever shown to be a problem. I also added a test case for this, to check that lldb doesn't crash when given one of these corefiles.
rdar://120390199
>From 76a387985740aaae5624846515a6dbcb9f1ec272 Mon Sep 17 00:00:00 2001
From: Jason Molenda <jmolenda at apple.com>
Date: Tue, 9 Jan 2024 14:57:54 -0800
Subject: [PATCH] [lldb] [Mach-O] don't strip the end of the "kern ver str"
LC_NOTE
The "kern ver str" LC_NOTE gives lldb a kernel version string --
with a UUID and/or a load address (stext) to load it at. The LC_NOTE
specifies a size of the identifier string in bytes. In
ObjectFileMachO::GetIdentifierString, I copy that number of bytes
into a std::string, and in case there were additional nul characters
at the end of the sting for padding reasons, I tried to shrink the
std::string to not include these extra nul's.
However, I did this resizing without handling the case of an empty
identifier string. I don't know why any corefile creator would do
that, but of course at least one does. This patch removes the
resizing altogether; I was solving something that hasn't ever shown
to be a problem. I also added a test case for this, to check that
lldb doesn't crash when given one of these corefiles.
rdar://120390199
---
.../ObjectFile/Mach-O/ObjectFileMachO.cpp | 4 ---
.../TestFirmwareCorefiles.py | 24 +++++++++++++++++-
.../create-empty-corefile.cpp | 25 +++++++++++++------
3 files changed, 40 insertions(+), 13 deletions(-)
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index 182a9f2afaeb2e..d7a2846200fcaf 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -5467,8 +5467,6 @@ std::string ObjectFileMachO::GetIdentifierString() {
uint32_t strsize = payload_size - sizeof(uint32_t);
std::string result(strsize, '\0');
m_data.CopyData(payload_offset, strsize, result.data());
- while (result.back() == '\0')
- result.resize(result.size() - 1);
LLDB_LOGF(log, "LC_NOTE 'kern ver str' found with text '%s'",
result.c_str());
return result;
@@ -5488,8 +5486,6 @@ std::string ObjectFileMachO::GetIdentifierString() {
std::string result(ident_command.cmdsize, '\0');
if (m_data.CopyData(offset, ident_command.cmdsize, result.data()) ==
ident_command.cmdsize) {
- while (result.back() == '\0')
- result.resize(result.size() - 1);
LLDB_LOGF(log, "LC_IDENT found with text '%s'", result.c_str());
return result;
}
diff --git a/lldb/test/API/macosx/lc-note/firmware-corefile/TestFirmwareCorefiles.py b/lldb/test/API/macosx/lc-note/firmware-corefile/TestFirmwareCorefiles.py
index 9fd12c3ba49c29..b9d2055e83a56c 100644
--- a/lldb/test/API/macosx/lc-note/firmware-corefile/TestFirmwareCorefiles.py
+++ b/lldb/test/API/macosx/lc-note/firmware-corefile/TestFirmwareCorefiles.py
@@ -24,6 +24,9 @@ def test_lc_note_version_string(self):
aout_exe_basename = "a.out"
aout_exe = self.getBuildArtifact(aout_exe_basename)
verstr_corefile = self.getBuildArtifact("verstr.core")
+ verstr_corefile_invalid_ident = self.getBuildArtifact(
+ "verstr-invalid-ident.core"
+ )
verstr_corefile_addr = self.getBuildArtifact("verstr-addr.core")
create_corefile = self.getBuildArtifact("create-empty-corefile")
slide = 0x70000000000
@@ -36,6 +39,14 @@ def test_lc_note_version_string(self):
+ " 0xffffffffffffffff 0xffffffffffffffff",
shell=True,
)
+ call(
+ create_corefile
+ + " version-string "
+ + verstr_corefile_invalid_ident
+ + ' "" '
+ + "0xffffffffffffffff 0xffffffffffffffff",
+ shell=True,
+ )
call(
create_corefile
+ " version-string "
@@ -71,7 +82,18 @@ def test_lc_note_version_string(self):
self.assertEqual(fspec.GetFilename(), aout_exe_basename)
self.dbg.DeleteTarget(target)
- # Second, try the "kern ver str" corefile where it loads at an address
+ # Second, try the "kern ver str" corefile which has an invalid ident,
+ # make sure we don't crash.
+ target = self.dbg.CreateTarget("")
+ err = lldb.SBError()
+ if self.TraceOn():
+ self.runCmd(
+ "script print('loading corefile %s')" % verstr_corefile_invalid_ident
+ )
+ process = target.LoadCore(verstr_corefile_invalid_ident)
+ self.assertEqual(process.IsValid(), True)
+
+ # Third, try the "kern ver str" corefile where it loads at an address
target = self.dbg.CreateTarget("")
err = lldb.SBError()
if self.TraceOn():
diff --git a/lldb/test/API/macosx/lc-note/firmware-corefile/create-empty-corefile.cpp b/lldb/test/API/macosx/lc-note/firmware-corefile/create-empty-corefile.cpp
index 8bd6aaabecd636..d7c2d422412e42 100644
--- a/lldb/test/API/macosx/lc-note/firmware-corefile/create-empty-corefile.cpp
+++ b/lldb/test/API/macosx/lc-note/firmware-corefile/create-empty-corefile.cpp
@@ -86,14 +86,16 @@ std::vector<uint8_t> lc_thread_load_command(cpu_type_t cputype) {
void add_lc_note_kern_ver_str_load_command(
std::vector<std::vector<uint8_t>> &loadcmds, std::vector<uint8_t> &payload,
int payload_file_offset, std::string uuid, uint64_t address) {
- std::string ident = "EFI UUID=";
- ident += uuid;
-
- if (address != 0xffffffffffffffff) {
- ident += "; stext=";
- char buf[24];
- sprintf(buf, "0x%" PRIx64, address);
- ident += buf;
+ std::string ident;
+ if (!uuid.empty()) {
+ ident = "EFI UUID=";
+ ident += uuid;
+ if (address != 0xffffffffffffffff) {
+ ident += "; stext=";
+ char buf[24];
+ sprintf(buf, "0x%" PRIx64, address);
+ ident += buf;
+ }
}
std::vector<uint8_t> loadcmd_data;
@@ -187,6 +189,9 @@ void add_lc_segment(std::vector<std::vector<uint8_t>> &loadcmds,
std::string get_uuid_from_binary(const char *fn, cpu_type_t &cputype,
cpu_subtype_t &cpusubtype) {
+ if (strlen(fn) == 0)
+ return {};
+
FILE *f = fopen(fn, "r");
if (f == nullptr) {
fprintf(stderr, "Unable to open binary '%s' to get uuid\n", fn);
@@ -295,6 +300,10 @@ int main(int argc, char **argv) {
fprintf(stderr, "an LC_NOTE 'main bin spec' load command without an "
"address specified, depending on\n");
fprintf(stderr, "whether the 1st arg is version-string or main-bin-spec\n");
+ fprintf(stderr, "\nan LC_NOTE 'kern ver str' with no binary provided "
+ "(empty string filename) to get a UUID\n");
+ fprintf(stderr, "means an empty 'kern ver str' will be written, an invalid "
+ "LC_NOTE that lldb should handle.\n");
exit(1);
}
if (strcmp(argv[1], "version-string") != 0 &&
More information about the lldb-commits
mailing list