Re: Documenting ptrace access mode checking

From: Stephen Smalley
Date: Thu Jun 23 2016 - 14:04:04 EST


On 06/21/2016 05:41 AM, Michael Kerrisk (man-pages) wrote:
> Hi Jann, Stephen, et al.
>
> Jann, since you recently committed a patch in this area, and Stephen,
> since you committed 006ebb40d3d much further back in time, I wonder if
> you might help me by reviewing the text below that I propose to add to
> the ptrace(2) man page, in order to document "ptrace access mode
> checking" that is performed in various parts of the kernel-user-space
> interface. Of course, I welcome input from anyone else as well.
>
> Here's the new ptrace(2) text. Any comments, technical or terminological
> fixes, other improvements, etc. are welcome.
>
> [[
> Ptrace access mode checking
> Various parts of the kernel-user-space API (not just ptrace(2)
> operations), require so-called "ptrace access mode permissions"
> which are gated by Linux Security Modules (LSMs) such as
> SELinux, Yama, Smack, or the default LSM. Prior to Linux
> 2.6.27, all such checks were of a single type. Since Linux
> 2.6.27, two access mode levels are distinguished:
>
> PTRACE_MODE_READ
> For "read" operations or other operations that are less
> dangerous, such as: get_robust_list(2); kcmp(2); reading
> /proc/[pid]/auxv, /proc/[pid]/environ, or
> /proc/[pid]/stat; or readlink(2) of a /proc/[pid]/ns/*
> file.
>
> PTRACE_MODE_ATTACH
> For "write" operations, or other operations that are
> more dangerous, such as: ptrace attaching
> (PTRACE_ATTACH) to another process or calling
> process_vm_writev(2). (PTRACE_MODE_ATTACH was effecâ
> tively the default before Linux 2.6.27.)

That was the intent when the distinction was introduced, but it doesn't
appear to have been properly maintained, e.g. there is now a common
helper lock_trace() that is used for
/proc/pid/{stack,syscall,personality} but checks PTRACE_MODE_ATTACH, and
PTRACE_MODE_ATTACH is also used in timerslack_ns_write/show(). Likely
should review and make them consistent. There was also some debate
about proper handling of /proc/pid/fd. Arguably that one might belong
back in the _ATTACH camp.

>
> Since Linux 4.5, the above access mode checks may be combined
> (ORed) with one of the following modifiers:
>
> PTRACE_MODE_FSCREDS
> Use the caller's filesystem UID and GID (see credenâ
> tials(7)) or effective capabilities for LSM checks.
>
> PTRACE_MODE_REALCREDS
> Use the caller's real UID and GID or permitted capabiliâ
> ties for LSM checks. This was effectively the default
> before Linux 4.5.
>
> Because combining one of the credential modifiers with one of
> the aforementioned access modes is typical, some macros are
> defined in the kernel sources for the combinations:
>
> PTRACE_MODE_READ_FSCREDS
> Defined as PTRACE_MODE_READ | PTRACE_MODE_FSCREDS.
>
> PTRACE_MODE_READ_REALCREDS
> Defined as PTRACE_MODE_READ | PTRACE_MODE_REALCREDS.
>
> PTRACE_MODE_ATTACH_FSCREDS
> Defined as PTRACE_MODE_ATTACH | PTRACE_MODE_FSCREDS.
>
> PTRACE_MODE_ATTACH_REALCREDS
> Defined as PTRACE_MODE_ATTACH | PTRACE_MODE_REALCREDS.
>
> One further modifier can be ORed with the access mode:
>
> PTRACE_MODE_NOAUDIT (since Linux 3.3)
> Don't audit this access mode check.
>
> [I'd quite welcome some text to explain "auditing" here.]

Some ptrace access mode checks, such as checks when reading
/proc/pid/stat, merely cause the output to be filtered/sanitized rather
than an error to be returned to the caller. In these cases, accessing
the file is not a security violation and there is no reason to generate
a security audit record. This modifier suppresses the generation of
such an audit record for the particular access check.

>
> The algorithm employed for ptrace access mode checking deterâ
> mines whether the calling process is allowed to perform the
> corresponding action on the target process, as follows:
>
> 1. If the calling thread and the target thread are in the same
> thread group, access is always allowed.
>
> 2. If the access mode specifies PTRACE_MODE_FSCREDS, then for
> the check in the next step, employ the caller's filesystem
> user ID and group ID (see credentials(7)); otherwise (the
> access mode specifies PTRACE_MODE_REALCREDS, so) use the
> caller's real user ID and group ID.
>
> 3. Deny access if neither of the following is true:
>
> Â The real, effective, and saved-set user IDs of the target
> match the caller's user ID, and the real, effective, and
> saved-set group IDs of the target match the caller's
> group ID.
>
> Â The caller has the CAP_SYS_PTRACE capability.
>
> 4. Deny access if the target process "dumpable" attribute has
> a value other than 1 (SUID_DUMP_USER; see the discussion of
> PR_SET_DUMPABLE in prctl(2)), and the caller does not have
> the CAP_SYS_PTRACE capability in the user namespace of the
> target process.
>
> 5. The kernel LSM security_ptrace_access_check() interface is
> invoked to see if ptrace access is permitted. The results
> depend on the LSM. The implementation of this interface in
> the default LSM performs the following steps:
>
> a) If the access mode includes PTRACE_MODE_FSCREDS, then
> use the caller's effective capability set in the followâ
> ing check; otherwise (the access mode specifies
> PTRACE_MODE_REALCREDS, so) use the caller's permitted
> capability set.
>
> b) Deny access if neither of the following is true:
>
> Â The caller's capabilities are a proper superset of the
> target process's permitted capabilities.
>
> Â The caller has the CAP_SYS_PTRACE capability in the
> target process's user namespace.
>
> Note that the default LSM does not distinguish between
> PTRACE_MODE_READ and PTRACE_MODE_ATTACH.
>
> 6. If access has not been denied by any of the preceding
> steps, then access is allowed.
> ]]
>
> There are accompanying changes to various pages that refer to
> the new text in ptrace(2), so that, for example, kcmp(2) adds:
>
> Permission to employ kcmp() is governed by ptrace access mode
> PTRACE_MODE_ATTACH_REALCREDS checks against both pid1 and pid2;
> see ptrace(2).
>
> and proc.5 has additions such as:
>
> /proc/[pid]/auxv (since 2.6.0-test7)
> ...
> Permission to access this file is governed by a ptrace
> access mode PTRACE_MODE_READ_FSCREDS check; see
> ptrace(2).
>
> /proc/[pid]/cwd
> ...
> Permission to dereference or read (readlink(2)) this
> symbolic link is governed by a ptrace access mode
> PTRACE_MODE_READ_FSCREDS check; see ptrace(2).
>
> Thanks,
>
> Michael
>