From: Nick Alcock <nick.alcock@oracle.com>
To: Kris Van Hees via DTrace-devel <dtrace-devel@oss.oracle.com>
Cc: eugene.loh@oracle.com, Kris Van Hees <kris.van.hees@oracle.com>,
dtrace@lists.linux.dev
Subject: Re: [DTrace-devel] [PATCH 1/4] Tweak self-armouring
Date: Fri, 29 Nov 2024 13:57:17 +0000 [thread overview]
Message-ID: <871pyu5eiq.fsf@esperi.org.uk> (raw)
In-Reply-To: <ZxwHW_cxAA4x41bZ@kvh-deb-bpf.us.oracle.com> (Kris Van Hees via DTrace-devel's message of "Fri, 25 Oct 2024 17:02:19 -0400")
On 25 Oct 2024, Kris Van Hees via DTrace-devel spake thusly:
> On Fri, Oct 04, 2024 at 12:43:52AM -0400, eugene.loh@oracle.com wrote:
>> From: Eugene Loh <eugene.loh@oracle.com>
>>
>> Commit ea592d60 ("proc: improve armouring against self-grabs") has no
>> tests, but it breaks test/unittest/usdt/tst.multitrace.sh. The patch
>> makes the following change in libdtrace/dt_proc.c dt_proc_control():
>>
>> if ((Psystem_daemon(dpr->dpr_pid, dtp->dt_useruid,
>> dtp->dt_sysslice) > 0) ||
>> - ((tracer_pid != 0) &&
>> - (tracer_pid != getpid())) ||
>> + (tracer_pid == getpid()) ||
>> - (dpr->dpr_pid == getpid()))
>> + (tgid == getpid()))
>> noninvasive = 2;
>>
>> We change a
>> (tracer_pid != getpid())
>> into a
>> (tracer_pid == getpid())
>>
>> Changing that == back into a != makes tst.multitrace.sh work again.
>>
>> Signed-off-by: Eugene Loh <eugene.loh@oracle.com>
>
> Reviewed-by: Kris Van Hees <kris.van.hees@oracle.com>
It's better than what I was doing (which was definitely wrong), but it
could still be improved.
>> diff --git a/libdtrace/dt_proc.c b/libdtrace/dt_proc.c
>> index a052abbac..7c3eb2a24 100644
>> --- a/libdtrace/dt_proc.c
>> +++ b/libdtrace/dt_proc.c
>> @@ -954,7 +954,7 @@ dt_proc_control(void *arg)
>>
>> if ((Psystem_daemon(dpr->dpr_pid, dtp->dt_useruid,
>> dtp->dt_sysslice) > 0) ||
>> - (tracer_pid == getpid()) ||
>> + (tracer_pid != getpid()) ||
>> (tgid == getpid()))
>> noninvasive = 2;
What the previous code was saying was "if the traced process is a system
daemon, or is being debugged by someone else, or is ourself, do not do
an invasive grab"; in the one case because stopping systemd or the
system logger, even briefly, seems a like a bad idea, and in the other
two cases because you can't be debugged by two people at once and
because stopping yourself is an obvious deadlock.
We want to check if it's ourself in two ways: firstly, if the tracer PID
is our own PID, we are obviously ourself (this is the process-monitoring
thread itself); secondly, if the tracer PID's task group leader is our
own thread's task group leader, this is the main thread asking.
Unfortunately that's not what the original code was doing (the
tracer_pid thing was indeed wrong, we were saying "if we are debugged by
ourself, go noninvasive, but not if we're debugged by someone else"), so
your change was good as far as it goes... but if the process-monitoring
thread ever decides to monitor itself (perfectly possible with
suffiently-wildcardy probes and a ustack() or something), we'll
deadlock -- and unfortunately the tracer_pid is 0 when the process is
*not* being traced, so what that change is doing is going noninvasive
for *everyone, always*. That's what the original's
((tracer_pid != 0) &&
(tracer_pid != getpid())) ||
was all about: if you flip the latter conditional away from ==, you
*must* put the != 0 back in.
Something we're also not covering but should is that we want to fail
when asked to do long-lived grabs of ourself or a process being debugged
by someone else, or for that matter PID 1, *always*: long-lived grabs
mean we rely on getting process death notifications, etc, and
noninvasive grabs can't do that, so we *should* fail.
Also, we should define "ourself" more widely: we should really refuse
ptrace grabs on *any* DTrace thread, because the amount of proxying and
callbacks back and forth makes deadlocks horribly likely if, say, the
main thread gets invasively grabbed.
Fix coming shortly (before you get back and read this, assuming you're
guzzling turkey now like you should be).
--
NULL && (void)
next prev parent reply other threads:[~2024-11-29 13:57 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-04 4:43 [PATCH 1/4] Tweak self-armouring eugene.loh
2024-10-04 4:43 ` [PATCH 2/4] test: Increase timeout due to long shutdown eugene.loh
2024-10-25 21:05 ` Kris Van Hees
2024-10-04 4:43 ` [PATCH 3/4] test: Do not return 1 for err.*.x checks eugene.loh
2024-10-25 21:09 ` Kris Van Hees
2024-10-04 4:43 ` [PATCH 4/4] test: Do not depend on ext4 eugene.loh
2024-10-25 21:16 ` Kris Van Hees
2024-10-30 20:14 ` Eugene Loh
2024-11-27 16:51 ` Kris Van Hees
2025-09-14 11:18 ` Nick Alcock
2025-09-15 17:39 ` [DTrace-devel] " Kris Van Hees
2024-10-25 21:02 ` [PATCH 1/4] Tweak self-armouring Kris Van Hees
2024-11-29 13:57 ` Nick Alcock [this message]
2024-12-03 11:46 ` [DTrace-devel] " Nick Alcock
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=871pyu5eiq.fsf@esperi.org.uk \
--to=nick.alcock@oracle.com \
--cc=dtrace-devel@oss.oracle.com \
--cc=dtrace@lists.linux.dev \
--cc=eugene.loh@oracle.com \
--cc=kris.van.hees@oracle.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox