git: 55a0aa21628a - main - p_candebug(), p_cansee(): always allow for curproc

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Sat, 22 Jan 2022 17:37:23 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=55a0aa21628ad7b3bd8d6a42e51d79867d8996a9

commit 55a0aa21628ad7b3bd8d6a42e51d79867d8996a9
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2022-01-21 15:29:17 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2022-01-22 17:36:56 +0000

    p_candebug(), p_cansee(): always allow for curproc
    
    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).
    
    Note that in p_cansee() case, explicit comparision of curproc and p
    avoids a race where the process might change credentials and cause
    thread to compare its cached stale credentials against updated process
    creds, effectively disallowing the process to observe itself.
    
    Reviewed by:    emaste
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D33986
---
 sys/kern/kern_prot.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index 647acfa60681..0031465f081d 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -1460,10 +1460,12 @@ cr_cansee(struct ucred *u1, struct ucred *u2)
 int
 p_cansee(struct thread *td, struct proc *p)
 {
-
 	/* Wrap cr_cansee() for all functionality. */
 	KASSERT(td == curthread, ("%s: td not curthread", __func__));
 	PROC_LOCK_ASSERT(p, MA_OWNED);
+
+	if (td->td_proc == p)
+		return (0);
 	return (cr_cansee(td->td_ucred, p->p_ucred));
 }
 
@@ -1681,10 +1683,10 @@ p_candebug(struct thread *td, struct proc *p)
 
 	KASSERT(td == curthread, ("%s: td not curthread", __func__));
 	PROC_LOCK_ASSERT(p, MA_OWNED);
-	if ((error = priv_check(td, PRIV_DEBUG_UNPRIV)))
-		return (error);
 	if (td->td_proc == p)
 		return (0);
+	if ((error = priv_check(td, PRIV_DEBUG_UNPRIV)))
+		return (error);
 	if ((error = prison_check(td->td_ucred, p->p_ucred)))
 		return (error);
 #ifdef MAC