Messages in this thread | | | Subject | Re: [Bug 210655] ptrace.2: documentation is incorrect about access checking threads in same thread group | From | Ted Estes <> | Date | Tue, 15 Dec 2020 20:21:26 -0600 |
| |
On 12/15/2020 6:01 PM, Jann Horn wrote: > On Wed, Dec 16, 2020 at 12:25 AM Alejandro Colomar (man-pages) > <alx.manpages@gmail.com> wrote: >> On 12/16/20 12:23 AM, Alejandro Colomar (man-pages) wrote: >>> On 12/16/20 12:07 AM, Jann Horn wrote: >>>> Am Tue, Dec 15, 2020 at 06:01:25PM +0100 schrieb Alejandro Colomar (man-pages): >>>>> There's a bug report: https://bugzilla.kernel.org/show_bug.cgi?id=210655 >>>>> >>>>> [[ >>>>> Under "Ptrace access mode checking", the documentation states: >>>>> "1. If the calling thread and the target thread are in the same thread >>>>> group, access is always allowed." >>>>> >>>>> This is incorrect. A thread may never attach to another in the same group. >>>> No, that is correct. ptrace-mode access checks do always short-circuit for >>>> tasks in the same thread group: >>>> >>>> /* Returns 0 on success, -errno on denial. */ >>>> static int __ptrace_may_access(struct task_struct *task, unsigned int mode) >>>> { >>>> [...] >>>> /* May we inspect the given task? >>>> * This check is used both for attaching with ptrace >>>> * and for allowing access to sensitive information in /proc. >>>> * >>>> * ptrace_attach denies several cases that /proc allows >>>> * because setting up the necessary parent/child relationship >>>> * or halting the specified task is impossible. >>>> */ >>>> >>>> /* Don't let security modules deny introspection */ >>>> if (same_thread_group(task, current)) >>>> return 0; >>>> [...] >>>> } >>> AFAICS, that code always returns non-zero, >> Sorry, I should have said "that code never returns 0". >> >>> at least when called from ptrace_attach(). > Yes. > >>> As you can see below, >>> __ptrace_may_access() is called some lines after >>> the code pointed to by the bug report. >>> >>> >>> static int ptrace_attach(struct task_struct *task, long request, >>> unsigned long addr, >>> unsigned long flags) >>> { >>> [...] >>> if (same_thread_group(task, current)) >>> goto out; >>> >>> /* >>> * Protect exec's credential calculations against our interference; >>> * SUID, SGID and LSM creds get determined differently >>> * under ptrace. >>> */ >>> retval = -ERESTARTNOINTR; >>> if (mutex_lock_interruptible(&task->signal->cred_guard_mutex)) >>> goto out; >>> >>> task_lock(task); >>> retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH_REALCREDS); >>> [...] >>> } > I said exactly that in my last mail: > >>>> As the comment explains, you can't actually *attach* >>>> to another task in the same thread group; but that's >>>> not because of the ptrace-style access check rules, >>>> but because specifically *attaching* to another task >>>> in the same thread group doesn't work. > As I said, attaching indeed doesn't work. But that's not what "Ptrace > access mode checking" means. As the first sentence of that section > says: > > | Various parts of the kernel-user-space API (not just ptrace() > | operations), require so-called "ptrace access mode" checks, > | whose outcome determines whether an operation is > | permitted (or, in a few cases, causes a "read" operation > | to return sanitized data). > > You can find these places by grepping for \bptrace_may_access\b - > operations like e.g. the get_robust_list() syscall will always succeed > when inspecting other tasks in the caller's thread group thanks to > this rule.
Ah, yes. I missed that back reference while trying to digest that rather meaty man page. A grep on the man page source tree does show a number of references to "ptrace access mode".
That said, the ptrace(2) man page also directly references the ptrace access mode check under both PTRACE_ATTACH and PTACE_SEIZE:
| Permission to perform a PTRACE_ATTACH is governed by a ptrace | access mode PTRACE_MODE_ATTACH_REALCREDS check; see below. As confirmed, the "same thread group" rule does not apply to either of those operations. A re-wording of rule 1 similar to this might help avoid confusion: 1. If the calling thread and the target thread are in the same thread group: a. For ptrace() called with PTRACE_ATTACH or PTRACE_SEIZE, access is NEVER allowed. b. For all other so-called "ptrace access mode checks", access is ALWAYS allowed. --Ted
| |