garvey@cmic.UUCP (Joe Garvey) (02/03/90)
I was doing a little program to read/write from a serial interface on my HP 9000/370 running HP-UX 6.5. To my dismay, a small little software bug screwed the interface to a fair-thee-well. This program can be run by any user with access to the port. There should *not* be a getty running on this port, and a getty running on the other ports. It does not seem to affect the internal serial port (other than to give it a temporarily ridiculous set of settings). The response center considers this a feature. I consider it a bug. You decide for yourself. I call this program wedge.c... because of the effect it has. Consider yourself warned. After all forwarned is forarmed (four armed might actually be better :-) ). -------------------------- cut here ------------------------------------------ /* * This little demo program will cause a 4-port mux in a series 300 computer * to permenantly go out to lunch. In fact, in my case I used it on port 2 * and ports 0, 1, and 2 ceased to function. (You could see the getty issue * a prompt, but could not respond.) /dev/tty13.2 has no getty running on it. * * The only way out of this is to reset (turn the power off) the computer!!! * Any user can do this. Take heed a protect your serial ports accordingly. * * Modification History: * Joe Garvey, Jan 1990: Created to show HP what happened when I made a simple * mistake. * */ #include <stdio.h> #include <termio.h> #include <errno.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> static int RAU_fd; /* file descriptor for RAU line */ main () { /***** Definitions *****/ struct termio RAU_Line_Settings; /***** Code *****/ if ((RAU_fd = open("/dev/tty13.2", O_RDWR)) < 0) { fprintf(stderr, "%s: ", "wedge"); fprintf(stderr, "Couldn't open RAU line \"%s\"\n", "/dev/tty13.2"); exit(1); } RAU_Line_Settings.c_iflag = IGNBRK | PARMRK | INPCK | IXANY; RAU_Line_Settings.c_oflag = ONOCR; /* use of CSTOP instead of CSTOPB screws a 4-port mux up */ /* even the ports you're not using!!! */ /* right */ RAU_Line_Settings.c_cflag = B2400 | CSTOPB | CREAD | CS8 | PARENB | PARODD | HUPCL; */ /* wrong */ RAU_Line_Settings.c_cflag = B2400 | CSTOP | CREAD | CS8 | PARENB | PARODD | HUPCL; RAU_Line_Settings.c_lflag = 0; RAU_Line_Settings.c_line = 0; RAU_Line_Settings.c_cc[VTIME] = 1; RAU_Line_Settings.c_cc[VMIN] = 0; if (ioctl(RAU_fd, TCSETA, &RAU_Line_Settings) < 0) { fprintf(stderr, "%s: ", "wedge"); fprintf(stderr, "Couldn't configure RAU line\n"); exit(1); } sleep(1000); /* use this delay to check settings of line using stty(1) */ /* stty -a < /dev/tty13.2 */ return; } -------------------------- cut here, too ------------------------------------- Joe Garvey UUCP: {apple,backbone}!versatc!mips!cmic!garvey California Microwave Internet: garvey%cmic@mips.com 990 Almanor Ave HP Desk: xxx ("mips!cmic!garvey")/hp1900/ux Sunnyvale, Ca, 94086 800-831-3104 (outside CA) 408-720-6439 (let it ring) 800-824-7814 (inside CA)
rer@hpfcdc.HP.COM (Rob Robason) (02/06/90)
> The response center considers this a feature. I consider it a bug. You > decide for yourself. > /* use of CSTOP instead of CSTOPB screws a 4-port mux up */ > /* even the ports you're not using!!! */ > /* right */ > RAU_Line_Settings.c_cflag = B2400 | CSTOPB | CREAD | CS8 | PARENB | PARODD > /* wrong */ > RAU_Line_Settings.c_cflag = B2400 | CSTOP | CREAD | CS8 | PARENB | PARODD CSTOP is a flow control character definition (^S, get it: Cntl-STOP) and part of a set of predefined default characters in <termio.h>. It has nothing to do with CSTOPB which is a Control operation to set the number of STOP Bits on characters transmitted, totally unrelated to flow control. In the example you cited above, you obviously made a typographical error and should not expect the application to work. Just out of curiosity, and for fun, I tried to disect what you were REALLY doing, from definitions in termio.h: /* default control chars */ # define CSTOP 023 /* cntl s */ /* Control Modes */ # define CSTOPB 0000200 /* Send two stop bits, else one */ /* Baud Rate Values */ # define _CBAUD 0000037 # define B0 0 /* Hang up */ # define B50 0000001 /* 50 baud */ # define B75 0000002 /* 75 baud */ [middle of sequential list deleted...] # define B38400 0000022 /* 38400 baud */ I note that the 023 value you're tring to impose as a command is, in fact, within the masked value of speed control values but is not even a currently defined speed. I would expect such use to result in unpredictable behavior. You are telling the interface to do something we haven't defined. One could argue that some sort of error checking could be invoked. Such error checking would be costly in terms of performance, and would certainly not be consistent with the typical low-level expectations of ioctl() operations. While we take responsibility for our defects, we can't fix the UNIX* out of UNIX. This is one of those elusive bugs like I see so often with programs that get lost in malloc()/free() operations: it is definitely a coding defect and could have resulted from hundreds of potential typos. *UNIX is a trademark of AT&T in the U.S.A. and in other countries. Rob "blame the inventor" Robason
rer@hpfcdc.HP.COM (Rob Robason) (02/07/90)
> Such error checking would be costly in terms of > performance, and would certainly not be consistent with the typical > low-level expectations of ioctl() operations. Sorry, I meant to say "inconsistent", not "consistent". Kind of takes the umph out of my point. Boy, I wish notes had some sort of error checking so it could understand what I MEANT to say :-). Rob "Irony is my middle name" Robason
perry@hpfcdc.HP.COM (Perry Scott) (02/10/90)
Rob explains the externals pretty well. I've worked with the MUX
firmware, so I can guess what really happens to your MUX.
from /usr/include/sys/termio.h:
# define CSTOP 023 /* cntl s */
# define _CBAUD 0000037
# define B2400 0000014 /* 2400 baud */
# define B38400 0000022 /* 38400 baud */
> RAU_Line_Settings.c_cflag = B2400 | CSTOP | CREAD | CS8 | PARENB | PARODD
This sends (023|014 = 037), which is still a baud rate, and gives it to
the MUX. The MUX firmware uses this as an index into a table of values
which it uses to poke its SIO. Apparently, the SIO gets poked with
something that is not-your-usual-baudrate, depending on the whim of the
Zilog link editor.
The problem is exacerbated by an old firmware bug that uses only one
configuration byte instead of four. This causes all the ports to be set
to the never-never-land baud rate, in addition to the victim's. I'll
bet the EPROM on the MUX says 98642-90001. If so, there is a (free?)
upgrade to the latest revision.
So, I have to agree with the Response Center that you are using an
"unsupported" baud rate. :-) Nasty typo you have there.
Perry Scott