Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PTRACE_SETREGS lets a process raise a tracee's IOPL for privilege escalation #306

Open
matrizzo opened this issue Dec 30, 2024 · 2 comments

Comments

@matrizzo
Copy link

matrizzo commented Dec 30, 2024

https://github.com/klange/toaruos/blob/master/kernel/sys/ptrace.c#L289

PTRACE_SETREGS copies the value of eflags from userspace with no checks. This lets the tracer change the tracee's IOPL in the the tracee's EFLAGS. When IOPL=3 the tracee can directly talk to the hardware with port I/O from userspace.

@unknown-1-0
Copy link

unknown-1-0 commented Dec 30, 2024

It also allows the tracer to set the tracee's cs register to arbitrary value. If the tracer sets this register to 0x8, the tracee's code will execute in kernel mode.

@klange
Copy link
Owner

klange commented Dec 31, 2024

This one... doesn't surprise me. Based on when PTRACE_SETREGS was implemented, I think I was wholly committed to developing on and for aarch64, so I had completely forgotten the userspace register set on x86-64 included such sensitive things - and, on top of that, I was only trying to support intercepting system calls (eg. setting the syscall register to something else): aa8d79c

Good opportunity to get rid of that #ifdef and push this over to an arch_ function that can do the appropriate sanitation and copying of additional registers.

The rflags filtering has already been floating around in return-from-signal-handler; hopefully that does the right thing:

r->rflags = (out.rflags & 0xcd5) | (1 << 21) | (1 << 9) | ((r->rflags & (1 << 8)) ? (1 << 8) : 0);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants