diff options
| author | Roel Kluin <roel.kluin@gmail.com> | 2009-10-01 18:44:25 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-10-01 19:11:16 -0400 |
| commit | f23fc156fb4294f678f1913a56da633fa57edb2d (patch) | |
| tree | bc560880e9cf83542a3368963b429912ab218043 | |
| parent | 196b3167efd13a02cdd34acc1a12316b9f45f41d (diff) | |
serial167: fix read buffer overflow
Check whether index is within bounds before grabbing the element.
Also, since NR_PORTS is defined ARRAY_SIZE(cy_port), cy_port[NR_PORTS] is
out of bounds as well.
[akpm@linux-foundation.org: cleanup, remove (long) casts]
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Jiri Slaby <jirislaby@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
| -rw-r--r-- | drivers/char/serial167.c | 7 |
1 files changed, 2 insertions, 5 deletions
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index 5942a9d674c0..452370af95de 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c | |||
| @@ -220,8 +220,7 @@ static inline int serial_paranoia_check(struct cyclades_port *info, char *name, | |||
| 220 | return 1; | 220 | return 1; |
| 221 | } | 221 | } |
| 222 | 222 | ||
| 223 | if ((long)info < (long)(&cy_port[0]) | 223 | if (info < &cy_port[0] || info >= &cy_port[NR_PORTS]) { |
| 224 | || (long)(&cy_port[NR_PORTS]) < (long)info) { | ||
| 225 | printk("Warning: cyclades_port out of range for (%s) in %s\n", | 224 | printk("Warning: cyclades_port out of range for (%s) in %s\n", |
| 226 | name, routine); | 225 | name, routine); |
| 227 | return 1; | 226 | return 1; |
| @@ -520,15 +519,13 @@ static irqreturn_t cd2401_tx_interrupt(int irq, void *dev_id) | |||
| 520 | panic("TxInt on debug port!!!"); | 519 | panic("TxInt on debug port!!!"); |
| 521 | } | 520 | } |
| 522 | #endif | 521 | #endif |
| 523 | |||
| 524 | info = &cy_port[channel]; | ||
| 525 | |||
| 526 | /* validate the port number (as configured and open) */ | 522 | /* validate the port number (as configured and open) */ |
| 527 | if ((channel < 0) || (NR_PORTS <= channel)) { | 523 | if ((channel < 0) || (NR_PORTS <= channel)) { |
| 528 | base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); | 524 | base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); |
| 529 | base_addr[CyTEOIR] = CyNOTRANS; | 525 | base_addr[CyTEOIR] = CyNOTRANS; |
| 530 | return IRQ_HANDLED; | 526 | return IRQ_HANDLED; |
| 531 | } | 527 | } |
| 528 | info = &cy_port[channel]; | ||
| 532 | info->last_active = jiffies; | 529 | info->last_active = jiffies; |
| 533 | if (info->tty == 0) { | 530 | if (info->tty == 0) { |
| 534 | base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); | 531 | base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); |
