Skip to content

Commit 0ce6be1

Browse files
authored
Merge pull request #6587 from jasonmolenda/r107445318-set-addressable-bits-from-kernel-sym
Using global variable in xnu kernel, set # of addressable bits
2 parents d371822 + 043436d commit 0ce6be1

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,7 @@ void DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() {
10691069

10701070
if (m_kernel.IsLoaded() && m_kernel.GetModule()) {
10711071
static ConstString kext_summary_symbol("gLoadedKextSummaries");
1072+
static ConstString arm64_T1Sz_value("gT1Sz");
10721073
const Symbol *symbol =
10731074
m_kernel.GetModule()->FindFirstSymbolWithNameAndType(
10741075
kext_summary_symbol, eSymbolTypeData);
@@ -1077,6 +1078,36 @@ void DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() {
10771078
// Update all image infos
10781079
ReadAllKextSummaries();
10791080
}
1081+
// If the kernel global with the T1Sz setting is available,
1082+
// update the target.process.virtual-addressable-bits to be correct.
1083+
symbol = m_kernel.GetModule()->FindFirstSymbolWithNameAndType(
1084+
arm64_T1Sz_value, eSymbolTypeData);
1085+
if (symbol) {
1086+
const uint32_t orig_bits_value = m_process->GetVirtualAddressableBits();
1087+
// Mark all bits as addressable so we don't strip any from our
1088+
// memory read below, with an incorrect default value.
1089+
// b55 is the sign extension bit with PAC, b56:63 are TBI,
1090+
// don't mark those as addressable.
1091+
m_process->SetVirtualAddressableBits(55);
1092+
Status error;
1093+
// gT1Sz is 8 bytes. We may run on a stripped kernel binary
1094+
// where we can't get the size accurately. Hardcode it.
1095+
const size_t sym_bytesize = 8; // size of gT1Sz value
1096+
uint64_t sym_value =
1097+
m_process->GetTarget().ReadUnsignedIntegerFromMemory(
1098+
symbol->GetAddress(), sym_bytesize, 0, error);
1099+
if (error.Success()) {
1100+
// 64 - T1Sz is the highest bit used for auth.
1101+
// The value we pass in to SetVirtualAddressableBits is
1102+
// the number of bits used for addressing, so if
1103+
// T1Sz is 25, then 64-25 == 39, bits 0..38 are used for
1104+
// addressing, bits 39..63 are used for PAC/TBI or whatever.
1105+
uint32_t virt_addr_bits = 64 - sym_value;
1106+
m_process->SetVirtualAddressableBits(virt_addr_bits);
1107+
} else {
1108+
m_process->SetVirtualAddressableBits(orig_bits_value);
1109+
}
1110+
}
10801111
} else {
10811112
m_kernel.Clear();
10821113
}

0 commit comments

Comments
 (0)