⛏️ index : haiku.git

author Augustin Cavalier <waddlesplash@gmail.com> 2025-04-22 15:41:14.0 -04:00:00
committer Augustin Cavalier <waddlesplash@gmail.com> 2025-04-22 15:41:14.0 -04:00:00
commit
10eea8dfae01a8301c19a390de20881335d81eff [patch]
tree
81542e9ab7db056f449f2bf19ee50cb5dc6bbdf0
parent
6259a27b726ae1667a0fac8bd8856d72731b315d
download
10eea8dfae01a8301c19a390de20881335d81eff.tar.gz

kernel/debug: Fix handling of sInvokeCommandLevel.

 * Check for overflows in invoke_debugger_command.

 * Reset it inside invoke_debugger_command always.
   It wasn't reset in the case of INVOKE_COMMAND_FAULT, meaning
   we would "leak" command levels, thus leading to crashes
   and other problems inside the kernel debugger.

Fixes recursive KDLs or even triple faults caused by faulting
commands and pipes inside the kernel debugger.

Diff

 src/system/kernel/debug/debug_commands.cpp | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/src/system/kernel/debug/debug_commands.cpp b/src/system/kernel/debug/debug_commands.cpp
index 412a359..299cd0c 100644
--- a/src/system/kernel/debug/debug_commands.cpp
+++ b/src/system/kernel/debug/debug_commands.cpp
@@ -304,19 +304,25 @@
	if (gInvokeCommandDirectly)
		return command->func(argc, argv);

	sInCommand = true;
	if (sInvokeCommandLevel >= kMaxInvokeCommandDepth) {
		kprintf_unfiltered("\n[*** MAX COMMAND DEPTH HIT ***]\n");
		return B_KDEBUG_ERROR;
	}

	invoke_command_parameters parameters;
	parameters.command = command;
	parameters.argc = argc;
	parameters.argv = argv;

	sInCommand = true;
	int result = debug_call_with_fault_handler(
		sInvokeCommandEnv[sInvokeCommandLevel++],
		&invoke_command_trampoline, &parameters);
	sInvokeCommandLevel--;
	sInCommand = false;

	switch (debug_call_with_fault_handler(
			sInvokeCommandEnv[sInvokeCommandLevel++],
			&invoke_command_trampoline, &parameters)) {
	switch (result) {
		case 0:
			sInvokeCommandLevel--;
			sInCommand = false;
			return parameters.result;

		case INVOKE_COMMAND_FAULT:
@@ -338,7 +344,6 @@
			break;
	}

	sInCommand = false;
	return B_KDEBUG_ERROR;
}

@@ -351,7 +356,7 @@
abort_debugger_command()
{
	if (!gInvokeCommandDirectly && sInvokeCommandLevel > 0) {
		longjmp(sInvokeCommandEnv[--sInvokeCommandLevel],
		longjmp(sInvokeCommandEnv[sInvokeCommandLevel - 1],
			INVOKE_COMMAND_ERROR);
	}
}