Skip to content

Commit

Permalink
HBSD: Harden ioctl(ttyfd, TIOCSTI)
Browse files Browse the repository at this point in the history
Prevent TTY pushback vulnerabilities by hardening the TIOCSTI ioctl.
When the newly-added `hardening.harden_tty` sysctl node is set to 1 (the
default), attempts to use the TIOCSTI ioctl node will fail with EPERM.

Signed-off-by:	Shawn Webb <shawn.webb@hardenedbsd.org>
MFC-to:		13-STABLE
  • Loading branch information
lattera committed Mar 14, 2023
1 parent 45dec60 commit c7d6d4b
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 0 deletions.
23 changes: 23 additions & 0 deletions sys/hardenedbsd/hbsd_pax_hardening.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ static int harden_rtld_global = PAX_FEATURE_SIMPLE_DISABLED;

static int pax_kmod_load_disable = PAX_FEATURE_SIMPLE_DISABLED;
static int prohibit_ptrace_syscall_global = PAX_FEATURE_SIMPLE_ENABLED;
static int harden_tty_global = PAX_FEATURE_SIMPLE_ENABLED;

static int pax_tpe_gid = 0;
static int pax_tpe_negate = 0;
Expand All @@ -95,6 +96,7 @@ TUNABLE_INT("hardening.tpe.all", &pax_tpe_all);
TUNABLE_INT("hardening.tpe.root_owned", &pax_tpe_root_owned);
TUNABLE_INT("hardening.harden_rtld", &harden_rtld_global);
TUNABLE_INT("hardening.prohibit_ptrace_syscall", &prohibit_ptrace_syscall_global);
TUNABLE_INT("hardening.harden_tty", &harden_tty_global);

#ifdef PAX_SYSCTLS
SYSCTL_DECL(_hardening_pax);
Expand All @@ -115,6 +117,11 @@ SYSCTL_HBSD_2STATE(prohibit_ptrace_syscall_global,
_hardening, prohibit_ptrace_syscall,
CTLTYPE_INT|CTLFLAG_RWTUN|CTLFLAG_PRISON|CTLFLAG_SECURE,
"Prohibit syscall over ptrace boundary");
SYSCTL_HBSD_2STATE(harden_tty_global,
pr_hbsd.hardening.harden_tty,
_hardening, harden_tty,
CTLTYPE_INT|CTLFLAG_RWTUN|CTLFLAG_PRISON|CTLFLAG_SECURE,
"Harden the TTY layer");

SYSCTL_DECL(_hardening_pax);
SYSCTL_NODE(_hardening_pax, OID_AUTO, tpe, CTLFLAG_RD, 0,
Expand Down Expand Up @@ -151,6 +158,8 @@ SYSCTL_PROC(_hardening_pax, OID_AUTO, kmod_load_disable,
SYSCTL_DECL(_security_jail_param_hardening);
SYSCTL_JAIL_PARAM(_hardening, harden_rtld,
CTLTYPE_INT | CTLFLAG_RD, "I", "RTLD Hardening");
SYSCTL_JAIL_PARAM(_hardening, harden_tty,
CTLTYPE_INT | CTLFLAG_RD, "I", "TTY Layer Hardening");
#endif

#if 0
Expand Down Expand Up @@ -243,6 +252,7 @@ pax_hardening_init_prison(struct prison *pr, struct vfsoptlist *opts)
pr->pr_allow &= ~(PR_ALLOW_UNPRIV_DEBUG);
pr->pr_hbsd.hardening.prohibit_ptrace_syscall =
prohibit_ptrace_syscall_global;
pr->pr_hbsd.hardening.harden_tty = harden_tty_global;
} else {
KASSERT(pr->pr_parent != NULL,
("%s: pr->pr_parent == NULL", __func__));
Expand All @@ -255,8 +265,12 @@ pax_hardening_init_prison(struct prison *pr, struct vfsoptlist *opts)
pr_p->pr_hbsd.hardening.harden_rtld;
pr->pr_hbsd.hardening.prohibit_ptrace_syscall =
pr_p->pr_hbsd.hardening.prohibit_ptrace_syscall;
pr->pr_hbsd.hardening.harden_tty =
pr_p->pr_hbsd.hardening.harden_tty;
error = pax_handle_prison_param(opts, "hardening.harden_rtld",
&(pr->pr_hbsd.hardening.harden_rtld));
error = pax_handle_prison_param(opts, "hardening.harden_tty",
&(pr->pr_hbsd.hardening.harden_tty));
}

return (error);
Expand Down Expand Up @@ -332,6 +346,15 @@ pax_ptrace_syscall_prohibit(struct thread *td)
return (pr->pr_hbsd.hardening.prohibit_ptrace_syscall ? EPERM : 0);
}

int
pax_harden_tty(struct thread *td)
{
struct prison *pr;

pr = pax_get_prison_td(td);
return (pr->pr_hbsd.hardening.harden_tty ? EPERM : 0);
}

int
pax_enforce_tpe(struct thread *td, struct vnode *vn, const char *path)
{
Expand Down
11 changes: 11 additions & 0 deletions sys/kern/tty.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
__FBSDID("$FreeBSD$");

#include "opt_capsicum.h"
#include "opt_pax.h"
#include "opt_printf.h"

#include <sys/param.h>
Expand All @@ -50,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <sys/limits.h>
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/pax.h>
#include <sys/poll.h>
#include <sys/priv.h>
#include <sys/proc.h>
Expand Down Expand Up @@ -602,6 +604,12 @@ ttydev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
case TIOCSETP:
case TIOCSLTC:
#endif /* COMPAT_43TTY */
if (cmd == TIOCSTI) {
error = pax_harden_tty(td);
if (error) {
goto done;
}
}
/*
* If the ioctl() causes the TTY to be modified, let it
* wait in the background.
Expand Down Expand Up @@ -1952,6 +1960,9 @@ tty_generic_ioctl(struct tty *tp, u_long cmd, void *data, int fflag,
tty_info(tp);
return (0);
case TIOCSTI:
if (pax_harden_tty(td)) {
return (EPERM);
}
if ((fflag & FREAD) == 0 && priv_check(td, PRIV_TTY_STI))
return (EPERM);
if (!tty_is_ctty(tp, td->td_proc) &&
Expand Down
2 changes: 2 additions & 0 deletions sys/sys/pax.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ struct hbsd_features {
int tpe_root_owned;
pax_state_t harden_rtld;
pax_state_t prohibit_ptrace_syscall;
pax_state_t harden_tty;
} hardening;
struct hbsd_log {
pax_state_t log; /* (p) Per-jail logging status */
Expand Down Expand Up @@ -237,6 +238,7 @@ int pax_hardening_init_prison(struct prison *pr, struct vfsoptlist *opts);
#endif
int pax_procfs_harden(struct thread *td);
int pax_ptrace_syscall_prohibit(struct thread *td);
int pax_harden_tty(struct thread *td);
int pax_enforce_tpe(struct thread *, struct vnode *, const char *);
pax_flag_t pax_hardening_setup_flags(struct image_params *, struct thread *,
pax_flag_t);
Expand Down

0 comments on commit c7d6d4b

Please sign in to comment.