Page MenuHomeFreeBSD

linux: implement PTRACE_EVENT_EXEC
AbandonedPublic

Authored by trasz on Oct 8 2021, 12:55 PM.
Tags
None
Referenced Files
Unknown Object (File)
Fri, Apr 19, 11:53 AM
Unknown Object (File)
Sun, Apr 7, 10:12 PM
Unknown Object (File)
Mar 18 2024, 8:12 PM
Unknown Object (File)
Feb 11 2024, 9:32 AM
Unknown Object (File)
Jan 30 2024, 10:44 PM
Unknown Object (File)
Dec 22 2023, 1:28 PM
Unknown Object (File)
Dec 20 2023, 3:18 AM
Unknown Object (File)
Dec 16 2023, 4:51 PM
Subscribers

Details

Summary

This fixes strace(1) from Ubuntu Focal.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

trasz requested review of this revision.Oct 8 2021, 12:55 PM
sys/kern/subr_syscall.c
284

TDB_EXEC is cleared two lines below

285

Doesn't it result in two ptracestop()s generated for TDB_EXEC/SV_ABI_LINUX targets?

sys/kern/subr_syscall.c
284

Yes, but I don't want this flag set during the second ptracestop().

285

Yes, that's the whole purpose of this patch. I agree it's weird, that's why I've added a comment :-)

The reason why I don't want this flag set during the second ptracestop() is that I don't want to return LINUX_PTRACE_EVENT_EXEC on the second stop.

Can you describe what the two stops are? Is it one stop for syscall exit and a second for exec? If so, I think this isn't quite doing what you want. I think the first stop will report (LINUX_SIGTRAP | (0x80 | LINUX_PTRACE_EXEC_EVENT) << 8) << 8 and the second stop will report (LINUX_SIGTRAP | 0x80 << 8) << 8. I think you'd want to change the linux_ptrace bits to ignore SCX if EXEC is set?

sys/kern/subr_syscall.c
279

Emit those in the right order.

In D32367#732149, @jhb wrote:

Can you describe what the two stops are? Is it one stop for syscall exit and a second for exec? If so, I think this isn't quite doing what you want. I think the first stop will report (LINUX_SIGTRAP | (0x80 | LINUX_PTRACE_EXEC_EVENT) << 8) << 8 and the second stop will report (LINUX_SIGTRAP | 0x80 << 8) << 8. I think you'd want to change the linux_ptrace bits to ignore SCX if EXEC is set?

One is for exec, the other is for syscall return. And yeah, those were wrong.

In D32367#732149, @jhb wrote:

Can you describe what the two stops are? Is it one stop for syscall exit and a second for exec? If so, I think this isn't quite doing what you want. I think the first stop will report (LINUX_SIGTRAP | (0x80 | LINUX_PTRACE_EXEC_EVENT) << 8) << 8 and the second stop will report (LINUX_SIGTRAP | 0x80 << 8) << 8. I think you'd want to change the linux_ptrace bits to ignore SCX if EXEC is set?

One is for exec, the other is for syscall return. And yeah, those were wrong; should be fine now.

jhb added inline comments.
sys/kern/subr_syscall.c
260

Maybe tweak this comment a bit to say something like:

/*
  * Linux debuggers expect an additional stop for exec,
  * between the usual syscall entry and exit.  Raise the
  * exec event now and then clear TDB_EXEC so that
  * the next stop is reported as a syscall exit by
  * linux_ptrace_status().
  */
This revision is now accepted and ready to land.Oct 19 2021, 6:02 PM

BTW, why cannot this be done somewhere in linux_on_exec(), or similar place?

What should the behavior be when process either enters linux ABI or leaves it, instead of simple case of linux binary execing linux binary?

In D32367#736014, @kib wrote:

BTW, why cannot this be done somewhere in linux_on_exec(), or similar place?

Because it runs too early. This needs to happen after the threads in the execve-ing process are terminated, and do_execve() calls Linux-specific code at the very beginning.

What should the behavior be when process either enters linux ABI or leaves it, instead of simple case of linux binary execing linux binary?

Interesting question. No idea, I'm afraid. I don't think Linux debuggers can handle non-Linux binaries.

This revision was automatically updated to reflect the committed changes.

Okay, so as usual Konstantin is right: the patch is wrong, in that it adds an extra stop even if the ptracing process is native, not Linux. This needs to be fixed.

Do I remember right that a process can only have at most one ptracing process? And if so - is there a reasonable way to determine the ptracer's ABI?

Do I remember right that a process can only have at most one ptracing process? And if so - is there a reasonable way to determine the ptracer's ABI?

If there is a tracer, it is p->p_pptr. Lock order is PROC_LOCK(p) before PROC_LOCK(p->p_pptr).