There appear to have been no callers with wait=1 since NetBSD 1.0
from a cursory search. Let's nix the parameter altogether on the
next kernel revbump. This logic is probably broken anyway in the
presence of ttycancel, which is necessary for, e.g., yanking USB
serial adapters.
These are wrappers around the global tty_lock for now (and the
continued existence of the tty_lock variable is why the ttylock
function has no underscore in its name). They will assist in
converting drivers to per-tty locking later on.
Access to the global constty variable is coordinated as follows:
1. Setting constty to nonnull, with atomic_store_release, is allowed
only under the new adaptive constty_lock in thread context. This
serializes TIOCCONS operations and ensures unlocked readers can
safely use a constty pointer read with atomic_load_consume.
2. Changing constty from nonnull to null, with atomic_cas_ptr, is
allowed in any context -- printf(9) uses this to disable a broken
constty.
3. Reading constty under constty_lock is allowed with
atomic_load_relaxed, because while constty_lock is held, it can
only be made null by some other thread/CPU, never made nonnull.
4. Reading constty outside constty_lock is allowed with
atomic_load_consume in a pserialize read section -- constty is
only ever made nonnull with atomic_store_release, in (1).
ttyclose will wait for all these pserialize read sections to
complete before flushing the tty.
5. To continue to use a struct tty pointer in (4) after the
pserialize read section has completed, caller must use tty_acquire
during the pserialize read section and then tty_release when done.
ttyclose will wait for all these references to drain before
returning.
These access rules allow us to serialize TIOCCONS, and safely destroy
ttys, without putting any locks on the access paths like printf(9)
that use constty. Once we set D_MPSAFE, operations on /dev/console
will contend only with other users of the same tty as constty, which
will be an improvement over contending with all other kernel lock
users in the system.
Changes second time around:
- Fix initialization of ok in cons.c cn_redirect.
- Fix reversed sense of conditional in subr_prf.c putone.
Changes third time around:
- Initialize ttyref_cv so we don't panic when trying to use it,
leading to infinite loop when panic tries to take tty_lock to print
the panic message while we already hold tty_lock.
Access to the global constty variable is coordinated as follows:
1. Setting constty to nonnull, with atomic_store_release, is allowed
only under the new adaptive constty_lock in thread context. This
serializes TIOCCONS operations and ensures unlocked readers can
safely use a constty pointer read with atomic_load_consume.
2. Changing constty from nonnull to null, with atomic_cas_ptr, is
allowed in any context -- printf(9) uses this to disable a broken
constty.
3. Reading constty under constty_lock is allowed with
atomic_load_relaxed, because while constty_lock is held, it can
only be made null by some other thread/CPU, never made nonnull.
4. Reading constty outside constty_lock is allowed with
atomic_load_consume in a pserialize read section -- constty is
only ever made nonnull with atomic_store_release, in (1).
ttyclose will wait for all these pserialize read sections to
complete before flushing the tty.
5. To continue to use a struct tty pointer in (4) after the
pserialize read section has completed, caller must use tty_acquire
during the pserialize read section and then tty_release when done.
ttyclose will wait for all these references to drain before
returning.
These access rules allow us to serialize TIOCCONS, and safely destroy
ttys, without putting any locks on the access paths like printf(9)
that use constty. Once we set D_MPSAFE, operations on /dev/console
will contend only with other users of the same tty as constty, which
will be an improvement over contending with all other kernel lock
users in the system.
Changes second time around:
- Fix initialization of ok in cons.c cn_redirect.
- Fix reversed sense of conditional in subr_prf.c putone.
Access to the global constty variable is coordinated as follows:
1. Setting constty to nonnull, with atomic_store_release, is allowed
only under the new adaptive constty_lock in thread context. This
serializes TIOCCONS operations and ensures unlocked readers can
safely use a constty pointer read with atomic_load_consume.
2. Changing constty from nonnull to null, with atomic_cas_ptr, is
allowed in any context -- printf(9) uses this to disable a broken
constty.
3. Reading constty under constty_lock is allowed with
atomic_load_relaxed, because while constty_lock is held, it can
only be made null by some other thread/CPU, never made nonnull.
4. Reading constty outside constty_lock is allowed with
atomic_load_consume in a pserialize read section -- constty is
only ever made nonnull with atomic_store_release, in (1).
ttyclose will wait for all these pserialize read sections to
complete before flushing the tty.
5. To continue to use a struct tty pointer in (4) after the
pserialize read section has completed, caller must use tty_acquire
during the pserialize read section and then tty_release when done.
ttyclose will wait for all these references to drain before
returning.
These access rules allow us to serialize TIOCCONS, and safely destroy
ttys, without putting any locks on the access paths like printf(9)
that use constty. Once we set D_MPSAFE, operations on /dev/console
will contend only with other users of the same tty as constty, which
will be an improvement over contending with all other kernel lock
users in the system.
This causes any current and future ttyopens to fail until ttyclose.
This is necessary for revoke to work reliably for device detach like
ucom(4) removable USB devices. A tty driver for a removable device
needs some way to interrupt a pending .d_open so it returns promptly.
But ttyclose only interrupts ttyopen if it's already sleeping; it
won't cause a concurrent .d_open call which _will call_ but _hasn't
yet called_ ttyopen to avoid sleeping. Using ttycancel in the tty
driver's .d_cancel makes this work.
define a flag FILTEROP_ISFD that has the meaning of the prior f_isfd.
Field and flag name aligned with OpenBSD.
This does not constitute a functional or ABI change, as the field location
and size, and the value placed in that field, are the same as the previous
code, but we're bumping __NetBSD_Version__ so 3rd-party module source code
can adapt, as needed.
NetBSD 9.99.89
The valid sizes of the tty input and output queues (according to the man page)
are between 1024 and 65536 and input values are converted to a power of two.
The check on the validity of the range is done after the input values are
converted, however, which means that a hostile program can attempt to set
the queue size to a negative value, and cause integer overflow before
the range is validated.
Detected by UBSan
Reported-by: syzbot+521b73969fd233c49e58@syzkaller.appspotmail.com
<subsystem>_<function>_<version>_hook
NFCI
XXX Note that although this introduces a change in the kernel-to-
XXX module interface, we are NOT bumping the kernel version number.
XXX We will bump the version number once the interface stabilizes.
These functions are defined on unsigned int. The generic name
min/max should not silently truncate to 32 bits on 64-bit systems.
This is purely a name change -- no functional change intended.
HOWEVER! Some subsystems have
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
even though our standard name for that is MIN/MAX. Although these
may invite multiple evaluation bugs, these do _not_ cause integer
truncation.
To avoid `fixing' these cases, I first changed the name in libkern,
and then compile-tested every file where min/max occurred in order to
confirm that it failed -- and thus confirm that nothing shadowed
min/max -- before changing it.
I have left a handful of bootloaders that are too annoying to
compile-test, and some dead code:
cobalt ews4800mips hp300 hppa ia64 luna68k vax
acorn32/if_ie.c (not included in any kernels)
macppc/if_gm.c (superseded by gem(4))
It should be easy to fix the fallout once identified -- this way of
doing things fails safe, and the goal here, after all, is to _avoid_
silent integer truncations, not introduce them.
Maybe one day we can reintroduce min/max as type-generic things that
never silently truncate. But we should avoid doing that for a while,
so that existing code has a chance to be detected by the compiler for
conversion to uimin/uimax without changing the semantics until we can
properly audit it all. (Who knows, maybe in some cases integer
truncation is actually intended!)
It is unexpected for an unprivileged process to gain privs by
typing to root's tty:
$ cat installer
#!/bin/sh
whoami
/usr/sbin/sti /dev/tty whoami\\n
$ su unprivileged -c ./installer
unprivileged
$ whoami
root
output to drain to five seconds so that exiting processes with
buffered output for a serial port blocked by flow control or a pty
that is not being read do not hang indefinitely. Should fix PRs
kern/12534 and kern/17171. This is an updated version of the change
of tty.c 1.263.
output to drain to five seconds so that exiting processes with
buffered output for a serial port blocked by flow control do not
hang indefinitely. Should fix PR kern/12534. OK christos.