[LTP] [PATCH] irqbalance01: fix out-of-bounds write in collect_irq_info()

Jan Stancek jstancek@redhat.com
Fri Jan 12 14:33:26 CET 2024


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(-)

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;
-- 
2.31.1



More information about the ltp mailing list