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, Nov 8, 6:54 PM
Unknown Object (File)
Sat, Oct 19, 7:45 AM
Unknown Object (File)
Oct 4 2024, 11:47 PM
Unknown Object (File)
Oct 3 2024, 8:45 AM
Unknown Object (File)
Oct 2 2024, 3:04 PM
Unknown Object (File)
Oct 1 2024, 3:22 PM
Unknown Object (File)
Oct 1 2024, 1:51 PM
Unknown Object (File)
Oct 1 2024, 3:56 AM
Subscribers

Details

Summary

This fixes strace(1) from Ubuntu Focal.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 42023
Build 38911: arc lint + arc unit

Event Timeline

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

TDB_EXEC is cleared two lines below

275

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

sys/kern/subr_syscall.c
274

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

275

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
269

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
262

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).