Disable Automatic Line Discipline Autoload
Set dev.tty.ldisc_autoload=0 so an unprivileged process can no longer make the kernel auto-load a TTY line-discipline module simply by asking for it (the TIOCSETD ioctl). Only already-loaded disciplines remain reachable.
Checked against the resolved running state (e.g. sshd -T, sysctl, systemctl show), catches drop-ins and Includes a file read would miss. Caveat: runtime ≠ persistence; a value correct now may not survive a reboot.
What Pavois checks
Pavois reads the effective value through /proc/sys/dev/tty/ldisc_autoload (the InSpec kernel_parameter resource): that is the value the kernel consults when a process requests a discipline, and it is the only proof that the protection is live. A second check greps /etc/sysctl.conf and the sysctl.d directories to prove persistence, because a value set with sysctl -w alone reverts at the next boot. A configuration file on its own proves nothing either: a later drop-in, or a sysctl -w at runtime, can override it, which is exactly the false negative a file-only check would produce.
describe kernel_parameter('dev.tty.ldisc_autoload') do
its('value') { should cmp 0 }
end
describe command("grep -hsE '^[[:space:]]*dev.tty.ldisc_autoload[[:space:]]*=[[:space:]]*0([[:space:]]|$)' /etc/sysctl.conf /etc/sysctl.d/*.conf /run/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf 2>/dev/null") do
its('stdout') { should match(/\S/) }
endHow to verify it is applied
Check the effective value and its persistence:
sysctl dev.tty.ldisc_autoload
# dev.tty.ldisc_autoload = 0
grep -r dev.tty.ldisc_autoload /etc/sysctl.conf /etc/sysctl.d/
# /etc/sysctl.d/zz-pavois.conf:dev.tty.ldisc_autoload = 0
The two must agree: a 0 in /proc with nothing on disk is lost at the next boot, and a 0 on disk with a 1 in /proc means the setting was never (re)loaded.
Inspect & investigate
The kernel does not log a refused autoload: the requesting process simply gets an error back from its TIOCSETD ioctl, so any trace appears in that program's own logs. What is observable is the module activity around it: a discipline module that is genuinely loaded (by root, deliberately) shows up in lsmod and journalctl -k, and the Pavois audit ruleset records the load syscalls (init_module, finit_module, key modules) in /var/log/audit/audit.log: grep the raw file for key="modules" rather than relying on ausearch.
Remediation
The Pavois plan applies this as a sysctl remediation: the key is aggregated with the other sysctl gaps into a single drop-in, /etc/sysctl.d/zz-pavois.conf. The zz- prefix is deliberate: it sorts after any 99-* file shipped by the distribution, so Pavois wins the last word. Writing the file notifies a sysctl --system reload, so the live value matches what persists straight away, with no reboot. Pavois also enables a oneshot unit that replays sysctl --system after network-online.target, because late network setup resets some keys to their kernel default.
Pavois applies this with its own harden engine, the plan below, not a shell script:
| key | dev.tty.ldisc_autoload |
|---|---|
| resource | sysctl |
| value | 0 |
pavois harden plan localwhere the target is local, a user@host SSH alias, or a container , Docs
Impact & precautions
Low risk: no reboot, no impact on SSH, and no effect on a discipline that is already loaded. The setting only blocks the automatic loading of a line-discipline module on request from a process. It bites only where a workload relies on a non-builtin discipline being pulled in on demand: serial-line stacks (slip, ppp, n_hdlc), CAN over serial (slcan), some Bluetooth, GPS/AIS or industrial serial daemons. Those keep working as long as the module is loaded explicitly beforehand: modprobe <module>, or a permanent entry in /etc/modules-load.d/. Inventory the disciplines your serial workloads use (lsmod) before applying, and pre-load them. On a server with no serial workload, the change is invisible.