unfortunately the kernel actually uses ptrace_access_check for more than just ptrace, and the LSM (and hence apparmor) is not given context as to where the check is coming from. The current full list that can trigger an apparmor ptrace check is below. We can discard any that are not using a variant of MODE_READ*
the mostly likely candidate is reading proc files, but this is going to take some more sleuthing to trace the source operation. AppArmor will throw an EACCES so if we can setup a trace to catch that, it would be helpful in tacking this down.
$ git grep security_ptrace_access_check
include/linux/security.h:int security_ptrace_access_check(struct task_struct *child, unsigned int mode);
include/linux/security.h:static inline int security_ptrace_access_check(struct task_struct *child,
kernel/ptrace.c: return security_ptrace_access_check(task, mode);
security/security.c:int security_ptrace_access_check(struct task_struct *child, unsigned int mode)
jj@flux:~/linux-kernels/linux-2.6$ emacs kernel/ptrace.c &
[4] 9110
jj@flux:~/linux-kernels/linux-2.6$ git grep ptrace_may_access
Documentation/process/adding-syscalls.rst:``ptrace_may_access()``) so that only a calling process with the same
Documentation/translations/it_IT/process/adding-syscalls.rst:la chiamata ``ptrace_may_access()``) di modo che solo un processo chiamante
fs/proc/array.c: permitted = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS | PTRACE_MODE_NOAUDIT);
fs/proc/base.c: if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
fs/proc/base.c: if (!ptrace_may_access(task, PTRACE_MODE_ATTACH_FSCREDS)) {
fs/proc/base.c: allowed = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
fs/proc/base.c: return ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
fs/proc/base.c: if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
fs/proc/base.c: if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
fs/proc/base.c: if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
fs/proc/namespaces.c: if (ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
fs/proc/namespaces.c: if (ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
include/linux/ptrace.h: * ptrace_may_access - check whether the caller is permitted to access
include/linux/ptrace.h:extern bool ptrace_may_access(struct task_struct *task, unsigned int mode);
include/linux/sched/mm.h: * and ptrace_may_access with the mode parameter passed to it
kernel/cred.c: * the credential change; otherwise, a __ptrace_may_access()
kernel/cred.c: * Pairs with a read barrier in __ptrace_may_access().
kernel/events/core.c: if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS))
kernel/fork.c: !ptrace_may_access(task, mode)) {
kernel/futex.c: if (!ptrace_may_access(p, PTRACE_MODE_READ_REALCREDS))
kernel/futex.c: if (!ptrace_may_access(p, PTRACE_MODE_READ_REALCREDS))
kernel/kcmp.c: if (!ptrace_may_access(task1, PTRACE_MODE_READ_REALCREDS) ||
kernel/kcmp.c: !ptrace_may_access(task2, PTRACE_MODE_READ_REALCREDS)) {
kernel/ptrace.c:static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
kernel/ptrace.c:bool ptrace_may_access(struct task_struct *task, unsigned int mode)
kernel/ptrace.c: err = __ptrace_may_access(task, mode);
kernel/ptrace.c: retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH_REALCREDS);
kernel/seccomp.c: * equivalent (see ptrace_may_access), it is safe to
mm/mempolicy.c: * Use the regular "ptrace_may_access()" checks.
mm/mempolicy.c: if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) {
mm/migrate.c: * process. Use the regular "ptrace_may_access()" checks.
mm/migrate.c: if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) {
unfortunately the kernel actually uses ptrace_access_check for more than just ptrace, and the LSM (and hence apparmor) is not given context as to where the check is coming from. The current full list that can trigger an apparmor ptrace check is below. We can discard any that are not using a variant of MODE_READ*
the mostly likely candidate is reading proc files, but this is going to take some more sleuthing to trace the source operation. AppArmor will throw an EACCES so if we can setup a trace to catch that, it would be helpful in tacking this down.
$ git grep security_ ptrace_ access_ check linux/security. h:int security_ ptrace_ access_ check(struct task_struct *child, unsigned int mode); linux/security. h:static inline int security_ ptrace_ access_ check(struct task_struct *child, ptrace_ access_ check(task, mode); security. c:int security_ ptrace_ access_ check(struct task_struct *child, unsigned int mode) ~/linux- kernels/ linux-2. 6$ emacs kernel/ptrace.c & ~/linux- kernels/ linux-2. 6$ git grep ptrace_may_access process/ adding- syscalls. rst:``ptrace_ may_access( )``) so that only a calling process with the same translations/ it_IT/process/ adding- syscalls. rst:la chiamata ``ptrace_ may_access( )``) di modo che solo un processo chiamante may_access( task, PTRACE_ MODE_READ_ FSCREDS | PTRACE_ MODE_NOAUDIT) ; may_access( task, PTRACE_ MODE_READ_ FSCREDS) ) may_access( task, PTRACE_ MODE_ATTACH_ FSCREDS) ) { may_access( task, PTRACE_ MODE_READ_ FSCREDS) ; may_access( task, PTRACE_ MODE_READ_ FSCREDS) ; may_access( task, PTRACE_ MODE_READ_ FSCREDS) ) may_access( task, PTRACE_ MODE_READ_ FSCREDS) ) may_access( task, PTRACE_ MODE_READ_ FSCREDS) ) { namespaces. c: if (ptrace_ may_access( task, PTRACE_ MODE_READ_ FSCREDS) ) { namespaces. c: if (ptrace_ may_access( task, PTRACE_ MODE_READ_ FSCREDS) ) { linux/ptrace. h: * ptrace_may_access - check whether the caller is permitted to access linux/ptrace. h:extern bool ptrace_ may_access( struct task_struct *task, unsigned int mode); linux/sched/ mm.h: * and ptrace_may_access with the mode parameter passed to it may_access( ) may_access( ). events/ core.c: if (!ptrace_ may_access( task, PTRACE_ MODE_READ_ REALCREDS) ) may_access( task, mode)) { may_access( p, PTRACE_ MODE_READ_ REALCREDS) ) may_access( p, PTRACE_ MODE_READ_ REALCREDS) ) may_access( task1, PTRACE_ MODE_READ_ REALCREDS) || may_access( task2, PTRACE_ MODE_READ_ REALCREDS) ) { ptrace. c:static int __ptrace_ may_access( struct task_struct *task, unsigned int mode) ptrace. c:bool ptrace_ may_access( struct task_struct *task, unsigned int mode) may_access( task, mode); may_access( task, PTRACE_ MODE_ATTACH_ REALCREDS) ; may_access( )" checks. may_access( task, PTRACE_ MODE_READ_ REALCREDS) ) { may_access( )" checks. may_access( task, PTRACE_ MODE_READ_ REALCREDS) ) {
include/
include/
kernel/ptrace.c: return security_
security/
jj@flux:
[4] 9110
jj@flux:
Documentation/
Documentation/
fs/proc/array.c: permitted = ptrace_
fs/proc/base.c: if (!ptrace_
fs/proc/base.c: if (!ptrace_
fs/proc/base.c: allowed = ptrace_
fs/proc/base.c: return ptrace_
fs/proc/base.c: if (!ptrace_
fs/proc/base.c: if (!ptrace_
fs/proc/base.c: if (!ptrace_
fs/proc/
fs/proc/
include/
include/
include/
kernel/cred.c: * the credential change; otherwise, a __ptrace_
kernel/cred.c: * Pairs with a read barrier in __ptrace_
kernel/
kernel/fork.c: !ptrace_
kernel/futex.c: if (!ptrace_
kernel/futex.c: if (!ptrace_
kernel/kcmp.c: if (!ptrace_
kernel/kcmp.c: !ptrace_
kernel/
kernel/
kernel/ptrace.c: err = __ptrace_
kernel/ptrace.c: retval = __ptrace_
kernel/seccomp.c: * equivalent (see ptrace_may_access), it is safe to
mm/mempolicy.c: * Use the regular "ptrace_
mm/mempolicy.c: if (!ptrace_
mm/migrate.c: * process. Use the regular "ptrace_
mm/migrate.c: if (!ptrace_