diff options
author | Alan Cox <alan@linux.intel.com> | 2009-06-11 07:46:41 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-11 11:51:01 -0400 |
commit | 5f0878acba7db24323f5ba4055ec9a96895bb150 (patch) | |
tree | 4e92e6a29ea537b62276d0902b499c3ee6779dd8 /drivers | |
parent | 620df3c0a5b70656c4de6049825de214f108218e (diff) |
tty: Fix oops when scanning the polling list for kgdb
Costantino Leandro found a bug in tty_find_polling_driver and provided a
patch that fixed the crash but not the underlying bug. This fixes the
underlying bug where the list walk corrupts the values it is using on a
match but then reuses them if the open fails.
Signed-off-by: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/tty_io.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 66b99a2049e3..6c817398232e 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -295,7 +295,7 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line) | |||
295 | struct tty_driver *p, *res = NULL; | 295 | struct tty_driver *p, *res = NULL; |
296 | int tty_line = 0; | 296 | int tty_line = 0; |
297 | int len; | 297 | int len; |
298 | char *str; | 298 | char *str, *stp; |
299 | 299 | ||
300 | for (str = name; *str; str++) | 300 | for (str = name; *str; str++) |
301 | if ((*str >= '0' && *str <= '9') || *str == ',') | 301 | if ((*str >= '0' && *str <= '9') || *str == ',') |
@@ -311,13 +311,14 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line) | |||
311 | list_for_each_entry(p, &tty_drivers, tty_drivers) { | 311 | list_for_each_entry(p, &tty_drivers, tty_drivers) { |
312 | if (strncmp(name, p->name, len) != 0) | 312 | if (strncmp(name, p->name, len) != 0) |
313 | continue; | 313 | continue; |
314 | if (*str == ',') | 314 | stp = str; |
315 | str++; | 315 | if (*stp == ',') |
316 | if (*str == '\0') | 316 | stp++; |
317 | str = NULL; | 317 | if (*stp == '\0') |
318 | stp = NULL; | ||
318 | 319 | ||
319 | if (tty_line >= 0 && tty_line <= p->num && p->ops && | 320 | if (tty_line >= 0 && tty_line <= p->num && p->ops && |
320 | p->ops->poll_init && !p->ops->poll_init(p, tty_line, str)) { | 321 | p->ops->poll_init && !p->ops->poll_init(p, tty_line, stp)) { |
321 | res = tty_driver_kref_get(p); | 322 | res = tty_driver_kref_get(p); |
322 | *line = tty_line; | 323 | *line = tty_line; |
323 | break; | 324 | break; |