Messages in this thread Patch in this message | | | Date | Tue, 30 Jun 1998 21:43:54 -0400 | From | "Theodore Y. Ts'o" <> | Subject | Re: serial module usage-count deficit in 2.1.107 |
| |
Date: Tue, 30 Jun 1998 20:26:45 -0400 (EDT) From: Andrew J Skalski <askalski@acsu.buffalo.edu>
Before I run "setserial /dev/ttyS3 irq 5", the kernel assumes ttyS3 is running on irq 4 (conflicting with ttyS0). Now let's say I start using ttyS0 (for example, gpm). Then I try to access ttyS3 (cat /dev/ttyS3). It spits back an EBUSY, since the irq is already in use. However, it has a side effect of decrementing the module's usage count (without incrementing it in the first place!) If I repeatedly try to "cat /dev/ttyS3" I can get the usage count into negative numbers :-)
Yup, you're right. The reason why it wasn't noticed for so long is probably because the problem doesn't show up if you try to access ttyS3 as root, but only as a non-root user. (This is so that root users can fix the problem by being able to open the device with the TTY_IO_ERROR flag set, so that they can use the setserial program to fix the irq setting.)
Linus, could you please apply this patch to the mainline? The patch fixes the bug, as well as disabling the structure magic number checking code. (In the past couple of years, that code has never caught any problems, so it should be safe to disable it now. It also saves roughly 1800 bytes from the size of the serial driver, or roughly 11% of the size of the driver.)
- Ted
Patch generated: on Tue Jun 30 21:37:42 EDT 1998 by tytso@rsts-11.mit.edu against Linux version 2.1.107
=================================================================== RCS file: drivers/char/RCS/serial.c,v retrieving revision 1.2 diff -u -r1.2 drivers/char/serial.c --- drivers/char/serial.c 1998/07/01 01:12:48 1.2 +++ drivers/char/serial.c 1998/07/01 01:35:34 @@ -62,7 +62,7 @@ * ever possible. */ -#define SERIAL_PARANOIA_CHECK +#undef SERIAL_PARANOIA_CHECK #define CONFIG_SERIAL_NOPAUSE_IO #define SERIAL_DO_RESTART @@ -2567,12 +2567,15 @@ int retval, line; unsigned long page; + MOD_INC_USE_COUNT; line = MINOR(tty->device) - tty->driver.minor_start; if ((line < 0) || (line >= NR_PORTS)) return -ENODEV; retval = get_async_struct(line, &info); if (retval) return retval; + tty->driver_data = info; + info->tty = tty; if (serial_paranoia_check(info, tty->device, "rs_open")) return -ENODEV; @@ -2580,8 +2583,6 @@ printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line, info->state->count); #endif - tty->driver_data = info; - info->tty = tty; info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; if (!tmp_buf) { @@ -2616,7 +2617,6 @@ if (retval) return retval; - MOD_INC_USE_COUNT; retval = block_til_ready(tty, filp, info); if (retval) { #ifdef SERIAL_DEBUG_OPEN
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu
| |