[PATCH v2] pytest: fix out of bounds access to bad_pattern_ids

Denis Mukhin via U-Boot <[email protected]>
Newsgroups gmane.comp.boot-loaders.u-boot
Message-ID <20260809183643.4163840-3-dmukhin__18671.507509292$1786300802$gmane$org@ford.com>
With 'pattern_lab_mode' at index 1, every bad-pattern index is off by
one, so the wrong id is reported and a match on the final bad pattern
indexes past the end of 'bad_pattern_ids'.

Ensure out of bound access to 'bad_pattern_ids' is handled correctly
while processing test console output.

Also, uniform accesses to 'bad_pattern_ids' throughout the module.

Fixes: 8308a5eed6e6 ("test: Introduce lab mode")
Signed-off-by: Denis Mukhin <[email protected]>
---
Changes since v1:
- updated commit message
- unified access to bad_pattern_ids

v1: https://lore.kernel.org/u-boot/[email protected]/ 
CI: https://github.com/u-boot/u-boot/pull/1035
---
 test/py/console_base.py | 40 +++++++++++++++++++++++++---------------
 1 file changed, 25 insertions(+), 15 deletions(-)

diff --git a/test/py/console_base.py b/test/py/console_base.py
index 88d444b44b88..164a31a9f712 100644
--- a/test/py/console_base.py
+++ b/test/py/console_base.py
@@ -212,29 +212,33 @@ class ConsoleBase(object):
             while not self.lab_mode and loop_num > 0:
                 loop_num -= 1
                 while config_spl_serial and not env_spl_skipped and env_spl_banner_times > 0:
-                    m = self.p.expect([pattern_u_boot_spl_signon,
-                                       pattern_lab_mode] + self.bad_patterns)
+                    extra_patterns = [pattern_u_boot_spl_signon, pattern_lab_mode]
+                    base = len(extra_patterns)
+                    m = self.p.expect(extra_patterns + self.bad_patterns)
                     if m == 1:
                         self.set_lab_mode()
                         break
                     elif m != 0:
                         raise BootFail('Bad pattern found on SPL console: ' +
-                                       self.bad_pattern_ids[m - 1])
+                                       self.bad_pattern_ids[m - base])
                     env_spl_banner_times -= 1
 
                 if not self.lab_mode:
-                    m = self.p.expect([pattern_u_boot_main_signon,
-                                       pattern_lab_mode] + self.bad_patterns)
+                    extra_patterns = [pattern_u_boot_main_signon, pattern_lab_mode]
+                    base = len(extra_patterns)
+                    m = self.p.expect(extra_patterns + self.bad_patterns)
                     if m == 1:
                         self.set_lab_mode()
                     elif m != 0:
                         raise BootFail('Bad pattern found on console: ' +
-                                       self.bad_pattern_ids[m - 1])
+                                       self.bad_pattern_ids[m - base])
             if not self.lab_mode:
                 self.u_boot_version_string = self.p.after
             while True:
-                m = self.p.expect([self.prompt_compiled, pattern_ready_prompt,
-                    pattern_stop_autoboot_prompt] + self.bad_patterns)
+                extra_patterns = [self.prompt_compiled, pattern_ready_prompt,
+                                  pattern_stop_autoboot_prompt]
+                base = len(extra_patterns)
+                m = self.p.expect(extra_patterns + self.bad_patterns)
                 if m == 0:
                     self.log.info(f'Found ready prompt {m}')
                     break
@@ -250,7 +254,7 @@ class ConsoleBase(object):
                     continue
                 if not self.lab_mode:
                     raise BootFail('Missing prompt / ready message on console: ' +
-                                   self.bad_pattern_ids[m - 3])
+                                   self.bad_pattern_ids[m - base])
             self.log.info(f'U-Boot is ready')
 
         finally:
@@ -321,21 +325,25 @@ class ConsoleBase(object):
                         continue
                     chunk = re.escape(chunk)
                     chunk = chunk.replace('\\\n', '[\r\n]')
-                    m = self.p.expect([chunk] + self.bad_patterns)
+                    extra_patterns = [chunk]
+                    base = len(extra_patterns)
+                    m = self.p.expect(extra_patterns + self.bad_patterns)
                     if m != 0:
                         self.at_prompt = False
                         raise BootFail(f"Failed to get echo on console (cmd '{cmd}':rem '{rem}'): " +
-                                        self.bad_pattern_ids[m - 1])
+                                        self.bad_pattern_ids[m - base])
             if not wait_for_prompt:
                 return
             if wait_for_reboot:
                 self.wait_for_boot_prompt()
             else:
-                m = self.p.expect([self.prompt_compiled] + self.bad_patterns)
+                extra_patterns = [self.prompt_compiled]
+                base = len(extra_patterns)
+                m = self.p.expect(extra_patterns + self.bad_patterns)
                 if m != 0:
                     self.at_prompt = False
                     raise BootFail('Missing prompt on console: ' +
-                                    self.bad_pattern_ids[m - 1])
+                                    self.bad_pattern_ids[m - base])
             self.at_prompt = True
             self.at_prompt_logevt = self.logstream.logfile.cur_evt
             # Only strip \r\n; space/TAB might be significant if testing
@@ -412,11 +420,13 @@ class ConsoleBase(object):
 
         if type(text) == type(''):
             text = re.escape(text)
-        m = self.p.expect([text] + self.bad_patterns)
+        extra_patterns = [text]
+        base = len(extra_patterns)
+        m = self.p.expect(extra_patterns + self.bad_patterns)
         if m != 0:
             raise Unexpected(
                 "Unexpected pattern found on console (exp '{text}': " +
-                self.bad_pattern_ids[m - 1])
+                self.bad_pattern_ids[m - base])
 
     def drain_console(self):
         """Read from and log the U-Boot console for a short time.
-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.