aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2009-06-11 07:46:41 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-11 11:51:01 -0400
commit5f0878acba7db24323f5ba4055ec9a96895bb150 (patch)
tree4e92e6a29ea537b62276d0902b499c3ee6779dd8 /drivers
parent620df3c0a5b70656c4de6049825de214f108218e (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.c13
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;