трассировка процесса (process trace)
Примечание (Note)
Although arguments to ptrace
() are interpreted according to the
prototype given, glibc currently declares ptrace
() as a variadic
function with only the request argument fixed. It is recommended
to always supply four arguments, even if the requested operation
does not use them, setting unused/ignored arguments to 0L or
(void *) 0.
In Linux kernels before 2.6.26, init(1), the process with PID 1,
may not be traced.
A tracees parent continues to be the tracer even if that tracer
calls execve(2).
The layout of the contents of memory and the USER area are quite
operating-system- and architecture-specific. The offset
supplied, and the data returned, might not entirely match with
the definition of struct user.
The size of a "word" is determined by the operating-system
variant (e.g., for 32-bit Linux it is 32 bits).
This page documents the way the ptrace
() call works currently in
Linux. Its behavior differs significantly on other flavors of
UNIX. In any case, use of ptrace
() is highly specific to the
operating system and architecture.
Ptrace access mode checking
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).
These checks are performed in cases where one process can inspect
sensitive information about, or in some cases modify the state
of, another process. The checks are based on factors such as the
credentials and capabilities of the two processes, whether or not
the "target" process is dumpable, and the results of checks
performed by any enabled Linux Security Module (LSM)—for example,
SELinux, Yama, or Smack—and by the commoncap LSM (which is always
invoked).
Prior to Linux 2.6.27, all access 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 effectively the default before
Linux 2.6.27.)
Since Linux 4.5, the above access mode checks are combined (ORed)
with one of the following modifiers:
PTRACE_MODE_FSCREDS
Use the caller's filesystem UID and GID (see
credentials(7)) or effective capabilities for LSM checks.
PTRACE_MODE_REALCREDS
Use the caller's real UID and GID or permitted
capabilities 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. This modifier is
employed for ptrace access mode checks (such as checks
when reading /proc/[pid]/stat) that merely cause the
output to be filtered or sanitized, rather than causing 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.
Note that all of the PTRACE_MODE_*
constants described in this
subsection are kernel-internal, and not visible to user space.
The constant names are mentioned here in order to label the
various kinds of ptrace access mode checks that are performed for
various system calls and accesses to various pseudofiles (e.g.,
under /proc). These names are used in other manual pages to
provide a simple shorthand for labeling the different kernel
checks.
The algorithm employed for ptrace access mode checking determines
whether the calling process is allowed to perform the
corresponding action on the target process. (In the case of
opening /proc/[pid] files, the "calling process" is the one
opening the file, and the process with the corresponding PID is
the "target process".) The algorithm is 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 UID
and GID. (As noted in credentials(7), the filesystem UID and
GID almost always have the same values as the corresponding
effective IDs.)
Otherwise, the access mode specifies PTRACE_MODE_REALCREDS
, so
use the caller's real UID and GID for the checks in the next
step. (Most APIs that check the caller's UID and GID use the
effective IDs. For historical reasons, the
PTRACE_MODE_REALCREDS
check uses the real IDs instead.)
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 in the user
namespace of the target.
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(s). The implementation of this interface in
the commoncap LSM performs the following steps:
a) If the access mode includes PTRACE_MODE_FSCREDS
, then use
the caller's effective capability set in the following
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 and the target process are in the same user
namespace, and the caller's capabilities are a 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 commoncap 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.
/proc/sys/kernel/yama/ptrace_scope
On systems with the Yama Linux Security Module (LSM) installed
(i.e., the kernel was configured with CONFIG_SECURITY_YAMA
), the
/proc/sys/kernel/yama/ptrace_scope file (available since Linux
3.4) can be used to restrict the ability to trace a process with
ptrace
() (and thus also the ability to use tools such as
strace(1) and gdb(1)). The goal of such restrictions is to
prevent attack escalation whereby a compromised process can
ptrace-attach to other sensitive processes (e.g., a GPG agent or
an SSH session) owned by the user in order to gain additional
credentials that may exist in memory and thus expand the scope of
the attack.
More precisely, the Yama LSM limits two types of operations:
* Any operation that performs a ptrace access mode
PTRACE_MODE_ATTACH
check—for example, ptrace
() PTRACE_ATTACH
.
(See the "Ptrace access mode checking" discussion above.)
* ptrace
() PTRACE_TRACEME
.
A process that has the CAP_SYS_PTRACE
capability can update the
/proc/sys/kernel/yama/ptrace_scope file with one of the following
values:
0 ("classic ptrace permissions")
No additional restrictions on operations that perform
PTRACE_MODE_ATTACH
checks (beyond those imposed by the
commoncap and other LSMs).
The use of PTRACE_TRACEME
is unchanged.
1 ("restricted ptrace") [default value]
When performing an operation that requires a
PTRACE_MODE_ATTACH
check, the calling process must either
have the CAP_SYS_PTRACE
capability in the user namespace
of the target process or it must have a predefined
relationship with the target process. By default, the
predefined relationship is that the target process must be
a descendant of the caller.
A target process can employ the prctl(2) PR_SET_PTRACER
operation to declare an additional PID that is allowed to
perform PTRACE_MODE_ATTACH
operations on the target. See
the kernel source file
Documentation/admin-guide/LSM/Yama.rst (or
Documentation/security/Yama.txt before Linux 4.13) for
further details.
The use of PTRACE_TRACEME
is unchanged.
2 ("admin-only attach")
Only processes with the CAP_SYS_PTRACE
capability in the
user namespace of the target process may perform
PTRACE_MODE_ATTACH
operations or trace children that
employ PTRACE_TRACEME
.
3 ("no attach")
No process may perform PTRACE_MODE_ATTACH
operations or
trace children that employ PTRACE_TRACEME
.
Once this value has been written to the file, it cannot be
changed.
With respect to values 1 and 2, note that creating a new user
namespace effectively removes the protection offered by Yama.
This is because a process in the parent user namespace whose
effective UID matches the UID of the creator of a child namespace
has all capabilities (including CAP_SYS_PTRACE
) when performing
operations within the child user namespace (and further-removed
descendants of that namespace). Consequently, when a process
tries to use user namespaces to sandbox itself, it inadvertently
weakens the protections offered by the Yama LSM.
C library/kernel differences
At the system call level, the PTRACE_PEEKTEXT
, PTRACE_PEEKDATA
,
and PTRACE_PEEKUSER
requests have a different API: they store the
result at the address specified by the data parameter, and the
return value is the error flag. The glibc wrapper function
provides the API given in DESCRIPTION above, with the result
being returned via the function return value.