Re: Bug in serial line hangup code ? (Final solution [maybe])

Peter Fox (fox@roestock.demon.co.uk)
Thu, 9 May 96 19:51 BST


> Date: Wed, 8 May 1996 15:09:25 -0400
> From: "Theodore Y. Ts'o" <tytso@MIT.EDU>
>
> Date: Wed, 8 May 96 07:47 BST
> From: Peter Fox <fox@roestock.demon.co.uk>
>
> But that's what I don't want. After hangup, if I catch SIGHUP, I want
> to keep the port open so I can do ioctls on it.
>
> I fail to see how it is any more of a security risk than a monitor
> program simply reopening the port. Even though the patches allow
> the monitor program to do ioctls on the hung up port, it doesn't allow
> any data access while the port is hungup.
>
> That's assuming that the program still has privileges to reopen the
> port. getty is supposed chown the port and then call vhangup() to force
> off any users....
>
> You can do an awful lot of damange using ioctl()'s. You can force
> characters to appear on the tty as if the user had typed them,
> etc. etc.
>
> The basic paradigm of a hangup is that *all* open file descriptors get
> forced off (the POSIX standard uses the language of "revoking access"),
> and from the point of the kernel, it's as if no one has the port open
> any more. That's why rs_hangup() forcibly shuts down the UART at this
> point; those file descriptors don't matter when considering whether or
> not the serial port is open.
>
> You want to fundamentually break this paradigm for the convenience of
> your port monitoring program, and I'm still not convinced that (a) it's
> worth the effort, and I _know_ that (b) doing so will disrupt a lot of
> assumptions made by both kernel programs and user-mode getty and login
> programs.

Ok. I've now greatly simplified the kernel patches, and they don't touch
the hangup code. I've simply added the character count variables for
each direction. I've appended the patch below, any chance of including
these ?

My serial monitor program has been modified to simply reopen the port if
it detects the line has hung up, which means the line must be specified.
If anyone's interested, the program has been uploaded, and should appear
at ftp://ftp.demon.co.uk/pub/unix/linux/utils/serialmon-0.13.tgz
within the next few days.

Peter.

------------------------------------------
diff -P -r -u -X diffexcl linux.1.3.99/drivers/char/serial.c linux.1.3.99.pf/drivers/char/serial.c
--- linux.1.3.99/drivers/char/serial.c Tue May 7 22:22:50 1996
+++ linux.1.3.99.pf/drivers/char/serial.c Thu May 9 19:19:10 1996
@@ -396,6 +396,7 @@

do {
ch = serial_inp(info, UART_RX);
+ info->rx_char_count++;
if (*status & info->ignore_status_mask) {
if (++ignored > 100)
break;
@@ -433,6 +434,7 @@

if (info->x_char) {
serial_outp(info, UART_TX, info->x_char);
+ info->tx_char_count++;
info->x_char = 0;
if (intr_done)
*intr_done = 0;
@@ -448,6 +450,7 @@
count = info->xmit_fifo_size;
do {
serial_out(info, UART_TX, info->xmit_buf[info->xmit_tail++]);
+ info->tx_char_count++;
info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
if (--info->xmit_cnt <= 0)
break;
@@ -1001,6 +1004,11 @@
(void) serial_inp(info, UART_IIR);
(void) serial_inp(info, UART_MSR);

+ /*
+ * Initialise the byte counters
+ */
+ info->rx_char_count = 0;
+ info->tx_char_count = 0;
/*
* Now, initialize the UART
*/
diff -P -r -u -X diffexcl linux.1.3.99/include/linux/serial.h linux.1.3.99.pf/include/linux/serial.h
--- linux.1.3.99/include/linux/serial.h Thu Mar 21 08:05:06 1996
+++ linux.1.3.99.pf/include/linux/serial.h Tue May 7 22:29:50 1996
@@ -170,6 +170,8 @@
struct async_icount icount; /* kernel counters for the 4 input interrupts */
struct async_struct *next_port; /* For the linked list */
struct async_struct *prev_port;
+ unsigned long rx_char_count; /* Total no of chars received */
+ unsigned long tx_char_count; /* Total no of chars transmitted */
};

#define SERIAL_MAGIC 0x5301