Page MenuHomeFreeBSD

p_candebug(), p_cansee(): always allow for curproc
ClosedPublic

Authored by kib on Jan 21 2022, 3:34 PM.
Tags
None
Referenced Files
Unknown Object (File)
Sun, May 12, 3:16 PM
Unknown Object (File)
Sun, May 12, 3:06 PM
Unknown Object (File)
Tue, May 7, 4:12 PM
Unknown Object (File)
Thu, May 2, 12:16 PM
Unknown Object (File)
Fri, Apr 19, 7:45 AM
Unknown Object (File)
Mar 15 2024, 8:54 AM
Unknown Object (File)
Mar 15 2024, 8:54 AM
Unknown Object (File)
Mar 15 2024, 8:54 AM
Subscribers

Details

Summary
Privilege checks in both functions should allow the current process to
infer information about itself, as well as use the interfaces that are
proclaimed 'debugging', for instance, procctl(2).

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

kib requested review of this revision.Jan 21 2022, 3:34 PM

p_candebug callers are found in:

  • linprocfs_doprocmaps
  • linux_get_robust_list
  • pmc_syscall_handler
  • procfs_candebug
    • procfs_doprocdbregs
    • procfs_doprocfpregs
    • procfs_doprocmap
    • procfs_doprocmem
    • procfs_doprocregs
  • linux_ptrace
  • ktrcanset
  • pget
  • kern_procctl
  • proc_can_ptrace
  • kern_ptrace

It's notable that mac_proc_check_debug (introduced in R10:8a1d977d66a39ae5e98b9ce35dd7041d16b784c7) has always been after the td->td_proc == p (or equivalent)

Also td->td_proc == p bypasses the P2_NOTRACE check; it is only the security.bsd.unprivileged_proc_debug sysctl that (in main) has a higher priority than td->td_proc == p.

Also td->td_proc == p bypasses the P2_NOTRACE check; it is only the security.bsd.unprivileged_proc_debug sysctl that (in main) has a higher priority than td->td_proc == p.

P2_NOTRACE is not relevant at all, because ptrace(PT_ATTACH, getpid()) is disabled outright. procfs checks for the process state being 'stopped' and cannot ever work for curproc for this reason.

Other uses of p_candebug(), like hwpmc self, ktrace self, and misc kern.proc.<pid>. kinfo sysctls (this is what pget(PGET_CANDEBUG) and pget(PGET_WANTREAD) are about) are perfectly fine for curproc.

Oh, we do check mac_priv_grant() from priv_check() though, so MAC could deny priv_check(td, PRIV_DEBUG_UNPRIV))

Looking way back in history, the sysctl was added in R10:0ef5652e271ad0bd5cb065a0f20505055d0117ca

o Introduce new kern.security sysctl tree for kernel security policy
  MIB entries.
o Relocate kern.suser_permitted to kern.security.suser_permitted.
o Introduce new kern.security.unprivileged_procdebug_permitted, which
  (when set to 0) prevents processes without privilege from performing
  a variety of inter-process debugging activities.  The default is 1,
  to provide current behavior.

  This feature allows "hardened" systems to disable access to debugging
  facilities, which have been associated with a number of past security
  vulnerabilities.  Previously, while procfs could be unmounted, other
  in-kernel facilities (such as ptrace()) were still available.  This
  setting should not be modified on normal development systems, as it
  will result in frustration.  Some utilities respond poorly to
  failing to get the debugging access they require, and error response
  by these utilities may be improved in the future in the name of
  beautification.

  Note that there are currently some odd interactions with some
  facilities, which will need to be resolved before this should be used
  in production, including odd interactions with truss and ktrace.
  Note also that currently, tracing is permitted on the current process
  regardless of this flag, for compatibility with previous
  authorization code in various facilities, but that will probably
  change (and resolve the odd interactions).

Given this and some discussion with rwatson, I think there are a few related issues here:

  • there is a desire to allow debugging interfaces to be disabled, which could act as a workaround in the event that a vulnerability is discovered in (say) ptrace(2)
  • perhaps security.bsd.unprivileged_proc_debug should just be a (set of) global sysctl(s) like security.bsd.ptrace_enabled to disable functionality in the event of a vulnerability
  • it could be that p_candebug is not a perfect match for procctl access control
  • maybe we should have some sort of p_cancontrol?

IMO having these fine-control methods would be an overkill. I believe that uses of p_candebug() in all subsystems (ptrace, hwpmc, ktrace, procfs, kern.proc kinfo sysctls) are reasonable and do not need more detailing.

I might have some sympathy to the idea of guarding whole kern_ptrace(9) with additional sysctl knob which would disable it regardless of the uid of the caller.

Overall LGTM. Should we check in sys/compat/linux/linux_ptrace.c also?

sys/kern/kern_prot.c
2490

@rwatson proposed putting this under the security.bsd tree which seems complementary with security.bsd.unprivileged_proc_debug

2492

I'd like to avoid new empty sysctl descriptions, but I also can't think of anything useful to put here beyond "allow ptrace"

security.bsd.allow_ptrace
Add silly sysctl description
Handle linux

Document knobs affecting ptrace permission to work.

This revision is now accepted and ready to land.Jan 22 2022, 12:25 AM