1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 17:57:35 +00:00

Kernel: Remove SmapDisablers in sys$ptrace() implementation

Instead, use copy_from_user() or copy_to_user() which does additional
verification and will panic the kernel on attempted kernel access.
This commit is contained in:
Andreas Kling 2020-04-14 09:50:14 +02:00
parent 0440f4f257
commit 0f760797a7

View file

@ -72,14 +72,10 @@ KResultOr<u32> handle_syscall(const Kernel::Syscall::SC_ptrace_params& params, P
if (!tracer->has_regs()) if (!tracer->has_regs())
return KResult(-EINVAL); return KResult(-EINVAL);
PtraceRegisters* regs = reinterpret_cast<PtraceRegisters*>(params.addr); auto* regs = reinterpret_cast<PtraceRegisters*>(params.addr);
if (!caller.validate_write(regs, sizeof(PtraceRegisters))) if (!caller.validate_write_typed(regs))
return KResult(-EFAULT); return KResult(-EFAULT);
copy_to_user(regs, &tracer->regs());
{
SmapDisabler disabler;
*regs = tracer->regs();
}
break; break;
} }
@ -87,22 +83,18 @@ KResultOr<u32> handle_syscall(const Kernel::Syscall::SC_ptrace_params& params, P
if (!tracer->has_regs()) if (!tracer->has_regs())
return KResult(-EINVAL); return KResult(-EINVAL);
if (!caller.validate_read(params.addr, sizeof(PtraceRegisters))) PtraceRegisters regs;
if (!caller.validate_read_and_copy_typed(&regs, (const PtraceRegisters*)params.addr))
return KResult(-EFAULT); return KResult(-EFAULT);
auto& peer_saved_registers = peer->get_register_dump_from_stack(); auto& peer_saved_registers = peer->get_register_dump_from_stack();
// Verify that the saved registers are in usermode context // Verify that the saved registers are in usermode context
if ((peer_saved_registers.cs & 0x03) != 3) { if ((peer_saved_registers.cs & 0x03) != 3)
return -EFAULT; return KResult(-EFAULT);
}
{ tracer->set_regs(regs);
SmapDisabler disabler; copy_ptrace_registers_into_kernel_registers(peer_saved_registers, regs);
PtraceRegisters* regs = reinterpret_cast<PtraceRegisters*>(params.addr); break;
tracer->set_regs(*regs);
copy_ptrace_registers_into_kernel_registers(peer_saved_registers, *regs);
break;
}
} }
case PT_PEEK: { case PT_PEEK: {