Skip to content

Commit 31ebf37

Browse files
Fix potential stack corruption in DebugSessionImp
- allocate 64 bytes on stack when accessing registers Signed-off-by: Mateusz Hoppe <[email protected]>
1 parent b5ee204 commit 31ebf37

File tree

3 files changed

+44
-10
lines changed

3 files changed

+44
-10
lines changed

level_zero/tools/source/debug/debug_session_imp.cpp

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -343,14 +343,18 @@ bool DebugSessionImp::writeResumeCommand(const std::vector<EuThread::ThreadId> &
343343
dword = 4;
344344
}
345345

346+
const auto regSize = std::max(getRegisterSize(registerType), hwInfo.capabilityTable.grfSize);
347+
auto reg = std::make_unique<uint32_t[]>(regSize / sizeof(uint32_t));
348+
346349
for (auto &threadID : threadIds) {
347-
uint32_t reg[8] = {};
348350
auto apiThread = convertToApi(threadID);
349-
if (readRegistersImp(apiThread, registerType, 0, 1, reg) != ZE_RESULT_SUCCESS) {
351+
memset(reg.get(), 0, regSize);
352+
353+
if (readRegistersImp(apiThread, registerType, 0, 1, reg.get()) != ZE_RESULT_SUCCESS) {
350354
success = false;
351355
} else {
352356
reg[dword] |= sipResumeValue;
353-
if (writeRegistersImp(apiThread, registerType, 0, 1, reg) != ZE_RESULT_SUCCESS) {
357+
if (writeRegistersImp(apiThread, registerType, 0, 1, reg.get()) != ZE_RESULT_SUCCESS) {
354358
success = false;
355359
}
356360
}
@@ -626,14 +630,16 @@ bool DebugSessionImp::isForceExceptionOrForceExternalHaltOnlyExceptionReason(uin
626630

627631
void DebugSessionImp::fillResumeAndStoppedThreadsFromNewlyStopped(std::vector<EuThread::ThreadId> &resumeThreads, std::vector<EuThread::ThreadId> &stoppedThreadsToReport) {
628632

633+
const auto regSize = std::max(getRegisterSize(ZET_DEBUG_REGSET_TYPE_CR_INTEL_GPU), 64u);
634+
auto reg = std::make_unique<uint32_t[]>(regSize / sizeof(uint32_t));
635+
629636
for (auto &newlyStopped : newlyStoppedThreads) {
630637
if (allThreads[newlyStopped]->isStopped()) {
631-
uint32_t reg[8] = {};
632-
638+
memset(reg.get(), 0, regSize);
633639
ze_device_thread_t apiThread = convertToApi(newlyStopped);
634-
readRegistersImp(apiThread, ZET_DEBUG_REGSET_TYPE_CR_INTEL_GPU, 0, 1, reg);
640+
readRegistersImp(apiThread, ZET_DEBUG_REGSET_TYPE_CR_INTEL_GPU, 0, 1, reg.get());
635641

636-
if (isForceExceptionOrForceExternalHaltOnlyExceptionReason(reg)) {
642+
if (isForceExceptionOrForceExternalHaltOnlyExceptionReason(reg.get())) {
637643
PRINT_DEBUGGER_THREAD_LOG("RESUME accidentally stopped thread = %s\n", allThreads[newlyStopped]->toString().c_str());
638644
resumeThreads.push_back(newlyStopped);
639645
} else {
@@ -727,7 +733,10 @@ const SIP::regset_desc *DebugSessionImp::getSbaRegsetDesc() {
727733
const SIP::regset_desc *DebugSessionImp::typeToRegsetDesc(uint32_t type) {
728734
auto pStateSaveAreaHeader = getStateSaveAreaHeader();
729735

730-
UNRECOVERABLE_IF(pStateSaveAreaHeader == nullptr);
736+
DEBUG_BREAK_IF(pStateSaveAreaHeader == nullptr);
737+
if (pStateSaveAreaHeader == nullptr) {
738+
return nullptr;
739+
}
731740

732741
switch (type) {
733742
case ZET_DEBUG_REGSET_TYPE_GRF_INTEL_GPU:
@@ -757,6 +766,14 @@ const SIP::regset_desc *DebugSessionImp::typeToRegsetDesc(uint32_t type) {
757766
}
758767
}
759768

769+
uint32_t DebugSessionImp::getRegisterSize(uint32_t type) {
770+
auto regset = typeToRegsetDesc(type);
771+
if (regset) {
772+
return regset->bytes;
773+
}
774+
return 0;
775+
}
776+
760777
uint32_t DebugSessionImp::typeToRegsetFlags(uint32_t type) {
761778
switch (type) {
762779
case ZET_DEBUG_REGSET_TYPE_GRF_INTEL_GPU:
@@ -806,8 +823,11 @@ ze_result_t DebugSessionImp::readSbaRegisters(ze_device_thread_t thread, uint32_
806823
return ret;
807824
}
808825

809-
uint32_t r0[8];
810-
ret = readRegistersImp(thread, ZET_DEBUG_REGSET_TYPE_GRF_INTEL_GPU, 0, 1, r0);
826+
const auto &hwInfo = connectedDevice->getHwInfo();
827+
const auto regSize = std::max(getRegisterSize(ZET_DEBUG_REGSET_TYPE_GRF_INTEL_GPU), hwInfo.capabilityTable.grfSize);
828+
auto r0 = std::make_unique<uint32_t[]>(regSize / sizeof(uint32_t));
829+
830+
ret = readRegistersImp(thread, ZET_DEBUG_REGSET_TYPE_GRF_INTEL_GPU, 0, 1, r0.get());
811831
if (ret != ZE_RESULT_SUCCESS) {
812832
return ret;
813833
}

level_zero/tools/source/debug/debug_session_imp.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ struct DebugSessionImp : DebugSession {
7979
uint32_t start, uint32_t count, void *pRegisterValues, bool write);
8080

8181
const SIP::regset_desc *typeToRegsetDesc(uint32_t type);
82+
uint32_t getRegisterSize(uint32_t type);
83+
8284
size_t calculateThreadSlotOffset(EuThread::ThreadId threadId);
8385
size_t calculateRegisterOffsetInThreadSlot(const SIP::regset_desc *const regdesc, uint32_t start);
8486

level_zero/tools/test/unit_tests/sources/debug/debug_session_tests.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ struct MockDebugSession : public L0::DebugSessionImp {
3636
using L0::DebugSessionImp::generateEventsAndResumeStoppedThreads;
3737
using L0::DebugSessionImp::generateEventsForPendingInterrupts;
3838
using L0::DebugSessionImp::generateEventsForStoppedThreads;
39+
using L0::DebugSessionImp::getRegisterSize;
3940
using L0::DebugSessionImp::getStateSaveAreaHeader;
4041
using L0::DebugSessionImp::markPendingInterruptsOrAddToNewlyStoppedFromRaisedAttention;
4142
using L0::DebugSessionImp::newAttentionRaised;
@@ -1717,6 +1718,17 @@ TEST_F(DebugSessionRegistersAccessTest, givenTypeToRegsetDescCalledThenCorrectRe
17171718
EXPECT_NE(session->typeToRegsetDesc(ZET_DEBUG_REGSET_TYPE_SBA_INTEL_GPU), nullptr);
17181719
}
17191720

1721+
TEST_F(DebugSessionRegistersAccessTest, givenValidRegisterWhenGettingSizeThenCorrectSizeIsReturned) {
1722+
session->stateSaveAreaHeader = MockSipData::createStateSaveAreaHeader(2);
1723+
auto pStateSaveAreaHeader = session->getStateSaveAreaHeader();
1724+
EXPECT_EQ(pStateSaveAreaHeader->regHeader.grf.bytes, session->getRegisterSize(ZET_DEBUG_REGSET_TYPE_GRF_INTEL_GPU));
1725+
}
1726+
1727+
TEST_F(DebugSessionRegistersAccessTest, givenInvalidRegisterWhenGettingSizeThenZeroSizeIsReturned) {
1728+
session->stateSaveAreaHeader = MockSipData::createStateSaveAreaHeader(2);
1729+
EXPECT_EQ(0u, session->getRegisterSize(ZET_DEBUG_REGSET_TYPE_INVALID_INTEL_GPU));
1730+
}
1731+
17201732
TEST_F(DebugSessionRegistersAccessTest, givenUnsupportedRegisterTypeWhenReadRegistersCalledThenErrorInvalidArgumentIsReturned) {
17211733
session->areRequestedThreadsStoppedReturnValue = 1;
17221734
session->stateSaveAreaHeader = MockSipData::createStateSaveAreaHeader(2);

0 commit comments

Comments
 (0)