| From 7127d24372bf23675a36edc64d092dc7fd92ebe8 Mon Sep 17 00:00:00 2001 |
| From: Jiri Slaby <jslaby@suse.cz> |
| Date: Fri, 17 Apr 2020 12:59:59 +0200 |
| Subject: tty: rocket, avoid OOB access |
| |
| From: Jiri Slaby <jslaby@suse.cz> |
| |
| commit 7127d24372bf23675a36edc64d092dc7fd92ebe8 upstream. |
| |
| init_r_port can access pc104 array out of bounds. pc104 is a 2D array |
| defined to have 4 members. Each member has 8 submembers. |
| * we can have more than 4 (PCI) boards, i.e. [board] can be OOB |
| * line is not modulo-ed by anything, so the first line on the second |
| board can be 4, on the 3rd 12 or alike (depending on previously |
| registered boards). It's zero only on the first line of the first |
| board. So even [line] can be OOB, quite soon (with the 2nd registered |
| board already). |
| |
| This code is broken for ages, so just avoid the OOB accesses and don't |
| try to fix it as we would need to find out the correct line number. Use |
| the default: RS232, if we are out. |
| |
| Generally, if anyone needs to set the interface types, a module parameter |
| is past the last thing that should be used for this purpose. The |
| parameters' description says it's for ISA cards anyway. |
| |
| Signed-off-by: Jiri Slaby <jslaby@suse.cz> |
| Cc: stable <stable@vger.kernel.org> |
| Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") |
| Link: https://lore.kernel.org/r/20200417105959.15201-2-jslaby@suse.cz |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/tty/rocket.c | 25 ++++++++++++++----------- |
| 1 file changed, 14 insertions(+), 11 deletions(-) |
| |
| --- a/drivers/tty/rocket.c |
| +++ b/drivers/tty/rocket.c |
| @@ -632,18 +632,21 @@ init_r_port(int board, int aiop, int cha |
| tty_port_init(&info->port); |
| info->port.ops = &rocket_port_ops; |
| info->flags &= ~ROCKET_MODE_MASK; |
| - switch (pc104[board][line]) { |
| - case 422: |
| - info->flags |= ROCKET_MODE_RS422; |
| - break; |
| - case 485: |
| - info->flags |= ROCKET_MODE_RS485; |
| - break; |
| - case 232: |
| - default: |
| + if (board < ARRAY_SIZE(pc104) && line < ARRAY_SIZE(pc104_1)) |
| + switch (pc104[board][line]) { |
| + case 422: |
| + info->flags |= ROCKET_MODE_RS422; |
| + break; |
| + case 485: |
| + info->flags |= ROCKET_MODE_RS485; |
| + break; |
| + case 232: |
| + default: |
| + info->flags |= ROCKET_MODE_RS232; |
| + break; |
| + } |
| + else |
| info->flags |= ROCKET_MODE_RS232; |
| - break; |
| - } |
| |
| info->intmask = RXF_TRIG | TXFIFO_MT | SRC_INT | DELTA_CD | DELTA_CTS | DELTA_DSR; |
| if (sInitChan(ctlp, &info->channel, aiop, chan) == 0) { |