Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 15 Aug 2018 09:34:17 +1000 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Warner Losh <imp@freebsd.org>
Cc:        src-committers@freebsd.org, svn-src-all@freebsd.org,  svn-src-head@freebsd.org
Subject:   Re: svn commit: r337750 - head/share/man/man4
Message-ID:  <20180815084045.O1014@besplex.bde.org>
In-Reply-To: <201808141352.w7EDqA6F001954@repo.freebsd.org>
References:  <201808141352.w7EDqA6F001954@repo.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 14 Aug 2018, Warner Losh wrote:

> Log:
>  Add good description of init and lock devices from sio to uart.

I thought at first that this was for the callin and callout devices.
These have been completely broken since FreeBSD-8.
   (A few hundred bugs collateral bugs in the tty driver are fixed in my
    version, including the big fat lock which prevents even stty -f on not
    only the complementary device but on the same device when another
    thread is sleeping in open.
    (The normal use of callout devices is when you have a callin device
    being opened by getty.  With working callout devices, you can open
    the complementary callout device.  In -current, this hangs on the
    big fat lock.  Even stty -f on the callin device to possibly set
    CLOCAL to unblock the open hangs on the big fat lock.))

The init and lock devices are only partly broken in uart.  They used to
be broken for console devices for the most important terminal attributes.
These were "fixated" in a hard-coded way instead of using the lock devices.
CLOCAL is broken for callout devices by ignoring the initial state device
and forcing it on.

> Modified: head/share/man/man4/uart.4
> ==============================================================================
> --- head/share/man/man4/uart.4	Tue Aug 14 13:52:08 2018	(r337749)
> +++ head/share/man/man4/uart.4	Tue Aug 14 13:52:10 2018	(r337750)
> @@ -225,6 +225,52 @@ Generally speaking, a connection to a DB-9 style conne
> level signal at up to 12 volts.
> A connection to header pins or an edge-connector on an embedded board
> is typically a TTL signal at 3.3 or 5 volts.
> +.Sh Special Devices
> +The
> +.Nm
> +driver also supports an initial-state and a lock-state control
> +device for each of the callin and the callout "data" devices.
> +The termios settings of a data device are copied
> +from those of the corresponding initial-state device
> +on first opens and are not inherited from previous opens.

Bug: CLOCAL is forced on initially for callout devices and perhaps also
for callin console devices.  The setting in the initial state is ignored.
Applications can change int later.  This makes little difference for
open, but affects the behaviour later.

> +Use
> +.Xr stty 1
> +in the normal way on the initial-state devices to program
> +initial termios states suitable for your setup.
> +.Pp
> +The lock termios state acts as flags to disable changing
> +the termios state.
> +E.g., to lock a flag variable such as CRTSCTS, use
> +.Em stty crtscts
> +on the lock-state device.
> +Speeds and special characters
> +may be locked by setting the corresponding value in the lock-state
> +device to any nonzero value.
> +E.g., to lock a speed to 115200, use
> +.Dq Li stty 115200
> +on the initial-state device and
> +.Dq Li stty 1
> +on the lock-state device.

Uart useed to fix speeds, and lock state setting was silently ignored.
Similarly for CLOCAL.  It works right now, except gettytab has mounds
of entries to work around the previous misbehaviour.

HUPCL is still broken in uart.  The initial and lock state settings for
it are silently ignored, and it is fixated in a hard-coded way to set
for non-consoles and unset for consoles.  Part of silently ignoring it
is to accept changes to it via tcsetattr() but then ignore the setting.
tcsetattr() is difficult enough to use without such bugs.  It is document
to succeed if it made _any_ setting successfully.  So it must always
succeed if it can reach the driver, since null changes to unimportant
settings are always possible.  And applications must call tcgetattr()
after tcsetattr() to determine which settings succeeded.  But when
settings are silently ignored later, the ones reported by tcsetattr()
can't be trusted either.


> +.Pp
> +Correct programs talking to correctly wired external devices
> +work with almost arbitrary initial states and almost no locking,
> +but other setups may benefit from changing some of the default
> +initial state and locking the state.

Not since a little before FreeBSD-8 or ever with uart.  The tty layer
sets wrong states in the initial and lock state devices.  The initial
state should be raw for non-consoles and sane for consoles.  The lock
state should be none for non-consoles and a few things (mainly the speed,
CLOCAL and HUPCL, and possibly CRTSCTS) for consoles.  This was broken
to sane for all cases and some missing lock settings for console.

> +In particular, the initial states for non (POSIX) standard flags
> +should be set to suit the devices attached and may need to be
> +locked to prevent buggy programs from changing them.
> +E.g., CRTSCTS should be locked on for devices that support
> +RTS/CTS handshaking at all times and off for devices that do not
> +support it at all.

This man page describes all of the delicate settings.

CRTSCTS might need to be locked off for consoles since flow control can
hang console output, which can cause an unbounded number of threads
waiting in ttymsg() (ttymsg() is clueless about terminals and is missing
all the necessary flow control and O_NONBLOCK handling).  Even software
xon/xoff might need to be locked off foc consoles.

> +CLOCAL should be locked on for devices that do not support carrier.
> +HUPCL may be locked off if you do not
> +want to hang up for some reason.

These are broken as described above.  HUPCL is broken in sio too, except
in my version.  dg broke it in ~1993 to work around bugs in his modems.
   (They locked up if RTS and/or DTR was dropped too quickly in close, and
    perhaps there should be a timeout.  Dropping of at least RTS was
    turned off to work around this.)
When RTS is dropped in close, flow control normally prevents the output
being done.  The output tends to bite the next open().  This is the
correct behaviour, except it gives security holes.  When RTS is not
dropped in close, flow-controlled output is normally done soon and acts
like it is dropped.

The broken HUPCL in uart results in RTS being forcibly dropped on last
close for non-consoles, and never dropped on last close for consoles.
Both behaviours are sometimes useful, but there is no way to control
them.

> +In general, very bad things happen
> +if something is locked to the wrong state, and things should not
> +be locked for devices that support more than one setting.
> +The CLOCAL flag on callin ports should be locked off for logins
> +to avoid certain security holes, but this needs to be done by
> +getty if the callin port is used for anything else.

I still sometimes forget this and lock myself out using CRTSCTS.

Even my correct initial states sometimes cause problems.  I often run
statistics programs like netstat instead of getty on vtys.  The correct
initial state of raw doesn't work for these programs, and it requires
tricky sttys to set a suitable cooked mode.  E.g.:

ttyv4	"/bin/sh -c '/home/bde/bin/scripts/systat -v 1 </dev/ttyv4 >/dev/ttyv4 2>&1'"					cons25	on  secure
ttyv8	"/bin/sh -c '(stty sane; /home/bde/bin/scripts/netstat -d -I sk0 1) </dev/ttyv8 >/dev/ttyv8 2>&1"'		cons25	on  secure

systat uses curses so has clues about terminal handling so it doesn't need a
stty.

> .Sh FILES
> .Bl -tag -width "/dev/ttyu?.init" -compact
> .It Pa /dev/ttyu?

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20180815084045.O1014>