diff mbox series

irqbalance01: fix out-of-bounds write in collect_irq_info()

Message ID 427788e09f3109fa5e48581058597d6998a08fa5.1705066390.git.jstancek@redhat.com
State Accepted, archived
Headers show
Series irqbalance01: fix out-of-bounds write in collect_irq_info() | expand

Commit Message

Jan Stancek Jan. 12, 2024, 1:33 p.m. UTC
Parse code first counts and allocates memory only for numbered IRQs,
and then proceeds to parse all columns. Problem is in second part,
which can advance "row" counter even for lines which are not parsed
(IRQs not matching [0-9]*). This eventually leads to "row" counter
being too large and going over bounds of irq_ids[]:
  ==2953075== Invalid write of size 4
  ==2953075==    at 0x1005B7A: collect_irq_info (irqbalance01.c:169)
  ==2953075==    by 0x1005D51: setup (irqbalance01.c:294)
  ==2953075==    by 0x1011BBB: do_test_setup (tst_test.c:1354)
  ==2953075==    by 0x1011BBB: testrun (tst_test.c:1479)
  ==2953075==    by 0x1011BBB: fork_testrun (tst_test.c:1627)
  ==2953075==    by 0x10136C1: tst_run_tcases (tst_test.c:1723)
  ==2953075==    by 0x10053A7: main (tst_test.h:402)

Reported issue is for s390x, but it can be reproduced also on x86_64
if you shuffle around lines of /proc/interrupts.

To fix, only advance "row" variable when line is recognized as being
numbered IRQ.

Closes: https://github.com/linux-test-project/ltp/issues/1118
Signed-off-by: Jan Stancek <jstancek@redhat.com>
---
 testcases/kernel/irq/irqbalance01.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

Comments

Cyril Hrubis Jan. 15, 2024, 10:11 a.m. UTC | #1
Hi!
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Jan Stancek Jan. 16, 2024, 10:49 a.m. UTC | #2
On Mon, Jan 15, 2024 at 11:11 AM Cyril Hrubis <chrubis@suse.cz> wrote:
>
> Hi!
> Reviewed-by: Cyril Hrubis <chrubis@suse.cz>

Pushed.

>
> --
> Cyril Hrubis
> chrubis@suse.cz
>
diff mbox series

Patch

diff --git a/testcases/kernel/irq/irqbalance01.c b/testcases/kernel/irq/irqbalance01.c
index a3d29aec2f5c..96bbec6a8f37 100644
--- a/testcases/kernel/irq/irqbalance01.c
+++ b/testcases/kernel/irq/irqbalance01.c
@@ -93,7 +93,7 @@  static void collect_irq_info(void)
 	char path[PATH_MAX];
 	size_t row, col, len;
 	long acc;
-	unsigned int cpu_total, bit;
+	unsigned int cpu_total, bit, row_parsed;
 
 	nr_cpus = 0;
 	nr_irqs = 0;
@@ -136,7 +136,7 @@  static void collect_irq_info(void)
 
 	c = first_row;
 	acc = -1;
-	row = col = 0;
+	row = col = row_parsed = 0;
 	/* Parse columns containing IRQ counts and IRQ IDs into acc. Ignore
 	 * everything else.
 	 */
@@ -154,7 +154,9 @@  static void collect_irq_info(void)
 			if (acc != -1)
 				tst_brk(TBROK, "Unexpected EOL");
 			col = 0;
-			row++;
+			if (row_parsed)
+				row++;
+			row_parsed = 0;
 			break;
 		case '0' ... '9':
 			if (acc == -1)
@@ -168,6 +170,7 @@  static void collect_irq_info(void)
 				tst_brk(TBROK, "Unexpected ':'");
 			irq_ids[row] = acc;
 			acc = -1;
+			row_parsed = 1;
 			break;
 		default:
 			acc = -1;