jail: Fix information leak.

There is a lack of proper visibility checking in kern.ttys sysctl handler
which leads to information leak about processes outside the current jail.

This can be demonstrated with pstat -t: when called from within a jail,
it will output all terminal devices including process groups and
session leader process IDs:

	jail# pstat -t | grep pts/ | head
	      LINE   INQ  CAN  LIN  LOW  OUTQ  USE  LOW   COL  SESS  PGID STATE
	     pts/2  1920    0    0  192  1984    0  199     0  4132 27245 Oi
	     pts/3  1920    0    0  192  1984    0  199    16 24890 33627 Oi
	     pts/5     0    0    0    0     0    0    0    25 17758     0 G
	    pts/16     0    0    0    0     0    0    0     0 52495     0 G
	    pts/15     0    0    0    0     0    0    0    25 53446     0 G
	    pts/17     0    0    0    0     0    0    0  6702 33230     0 G
	    pts/19     0    0    0    0     0    0    0    14  1116     0 G
	     pts/0     0    0    0    0     0    0    0     0  2241     0 G
	    pts/23     0    0    0    0     0    0    0    20 15639     0 G
	     pts/6     0    0    0    0     0    0    0     0 44062 93792 G
	jail# pstat -t | grep pts/ | wc -l
	      85

Devfs does the filtering correctly and we get only one entry:

	jail# ls /dev/pts/
	2

Approved by:	mzaborski, secteam
MFC after:	1 week
Sponsored by:	Fudo Security
This commit is contained in:
Pawel Jakub Dawidek 2024-01-17 09:43:55 -08:00
parent b9a60d36ba
commit f1d0a0cbec

View file

@ -1310,9 +1310,11 @@ static int
sysctl_kern_ttys(SYSCTL_HANDLER_ARGS)
{
unsigned long lsize;
struct thread *td = curthread;
struct xtty *xtlist, *xt;
struct tty *tp;
int error;
struct proc *p;
int cansee, error;
sx_slock(&tty_list_sx);
lsize = tty_list_count * sizeof(struct xtty);
@ -1325,13 +1327,28 @@ sysctl_kern_ttys(SYSCTL_HANDLER_ARGS)
TAILQ_FOREACH(tp, &tty_list, t_list) {
tty_lock(tp);
tty_to_xtty(tp, xt);
if (tp->t_session != NULL) {
p = tp->t_session->s_leader;
PROC_LOCK(p);
cansee = (p_cansee(td, p) == 0);
PROC_UNLOCK(p);
} else {
cansee = !jailed(td->td_ucred);
}
if (cansee) {
tty_to_xtty(tp, xt);
xt++;
}
tty_unlock(tp);
xt++;
}
sx_sunlock(&tty_list_sx);
error = SYSCTL_OUT(req, xtlist, lsize);
lsize = (xt - xtlist) * sizeof(struct xtty);
if (lsize > 0) {
error = SYSCTL_OUT(req, xtlist, lsize);
} else {
error = 0;
}
free(xtlist, M_TTY);
return (error);
}