Re: [PATCH] Improve ptrace-error detection on Linux targets

Sergio Durigan Junior
2019-08-19T13:47:51Z

On Monday, August 19 2019, Ruslan Kabatsayev wrote:

> Hello Sergio,

Hey Ruslan,

> On Mon, 19 Aug 2019 at 06:29, Sergio Durigan Junior <sergiodj@redhat.com> wrote:
>>
>> In Fedora GDB, we carry the following patch:
>>
>> https://src.fedoraproject.org/rpms/gdb/blob/master/f/gdb-attach-fail-reasons-5of5.patch
>>
>> Its purpose is to try to detect a specific scenario where SELinux's
>> 'deny_ptrace' option is enabled, which prevents GDB from ptrace'ing in
>> order to debug the inferior (PTRACE_ATTACH and PTRACE_ME will fail
>> with EACCES in this case).
>>
>> I like the idea of improving error detection and providing more
>> information to the user (a simple "Permission denied" can be really
>> frustrating), but I don't fully agree with the way the patch was
>> implemented: it makes GDB link against libselinux only for the sake of
>> consulting the 'deny_ptrace' setting, and then prints a warning if
>> ptrace failed and this setting is on.
>>
>> Instead of printing a very certain warning about a very specific
>> setting, I decided to propose the following patch, which prints a
>> generic warning about a possible situation (i.e., without going
>> bothering to make sure that the situation is actually happening).
>> What this means is that whenever a ptrace error is detected, and if
>> errno is either EACCES or EPERM, a warning will be printed pointing
>> the user to our documentation, where she will find more details about
>> possible restrictions in place against ptrace.
>
> Doesn't it worsen user experience compared to the current Fedora
> patch? Now a user first coming across the problem will have to
> navigate the documentation, then check possible scenarios – instead of
> simply getting a friendly explanation what exactly is wrong.

I agree that it is easier to just print the reason for the failure
directly, instead of pointing to the documentation. However, the reason
I chose the latter is because it may not always be possible to identify
the reason, and this might confuse the user or lead him to wrong
conclusions. I'm mostly thinking about the seccomp feature here
(because I have no idea how to check if it's active or not), but I'm
also concerned that it's unreasonable to expect users to have
libselinux-devel (on Fedora) installed.

> Compare this with the patch applied by some Linux distributions
> (CentOS IIRC) to make Bash emit
>
>> bash: myprogram: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory
>
> when ELF interpreter can't be found. By default, Bash only prints the
> less than helpful message
>
>> bash: myprogram: No such file or directory
>
> Your proposal (if it's intended to replace Fedora's GDB patch) is
> similar to replacing this default with
>
>> bash: myprogram: No such file or directory. There might be other reasons than simply command executable not existing. Please see Bash documentation section XYZ for details.
>
> and adding a section XYZ in Bash docs explaining that the reasons
> could include lacking libraries, broken symlink to the binary, stale
> hash table of PATH lookups, etc.. This is considerably worse than the
> patch with explicit announcement of actual problem.

Well, in this specific case it's probably not difficult to check for the
right cause and print the specific warning. However, if there were more
than 2 or 3 scenarios where a program couldn't be executed, and if
checking for them involved depending on external libraries and such,
then we'd be talking about a similar situation here.

> So as a user, I disfavor this approach, although it might be more
> maintainable for GDB developers. But, if dependency on libselinux is
> the only objection, then why not simply dlopen it as needed (and
> gracefully handle failure to do so) instead of ELF-level linking to
> it? Then there'll be no hard dependency on libselinux, while user
> experience will not degrade too.

Thanks for expressing your opinion as user, much appreciated!

I had considered dlopen'ing libselinux before, but didn't do that
because of what I mentioned earlier: I think it's not reasonable to
expect that the user will have libselinux-devel installed, and SELinux
is just one of the possible scenarios here.

But your message made me rethink and decide to do the following:

- Try to dlopen libselinux, and check for deny_ptrace if possible. If
it works and deny_ptrace is on, emit a specific warning about it. If
it doesn't work or if deny_ptrace is off, continue.

- Try to check the contents of /proc/sys/kernel/yama/ptrace_scope. If
it works and if ptrace_scope > 0, emit a specific warning about it.
Otherwise, continue.

- See if I can come up with a way to check the seccomp thing. If
possible, emit a specific warning about it. Otherwise, continue.

- If everything failed, emit a generic warning pointing to the docs.

I hope this is a better approach.

Thanks,

--
Sergio
GPG key ID: 237A 54B1 0287 28BF 00EF 31F4 D0EB 7628 65FC 5E36
Please send encrypted e-mail if possible