[bitbake][scarthgap][2.8][PATCH 2/4] fetch2: validate striplevel parameter

Yoann Congal <[email protected]> Sat, 6 Jun 2026 00:12:26 +0200
Newsgroups org.openembedded.lists.bitbake-devel
Message-ID <3a8937cc4b6513f9ed54fee0b0347589a892c8d7.1780697470.git.yoann.congal@smile.fr>
From: Anders Heimer <[email protected]>

The striplevel URL parameter is appended to tar_cmd, which is later run
through the shell. Validate it as a decimal count before using it in the
tar arguments.

Signed-off-by: Anders Heimer <[email protected]>
Signed-off-by: Richard Purdie <[email protected]>
(cherry picked from commit 934fe718bfe29c7ec921e6b598d81ec2ebe8f7c7)
[YC: Removed the striplevel="1\n" subtest case. The URL-decoding regex
in decodeurl uses `.*` without `re.DOTALL`, causing literal newlines in
parameters to be silently truncated during parsing.]
Signed-off-by: Yoann Congal <[email protected]>
---
 lib/bb/fetch2/__init__.py |  5 ++++-
 lib/bb/tests/fetch.py     | 11 +++++++++++
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/lib/bb/fetch2/__init__.py b/lib/bb/fetch2/__init__.py
index 2f54cb86e..7f6cf8ba9 100644
--- a/lib/bb/fetch2/__init__.py
+++ b/lib/bb/fetch2/__init__.py
@@ -1520,7 +1520,10 @@ class FetchMethod(object):
         if unpack:
             tar_cmd = 'tar --extract --no-same-owner'
             if 'striplevel' in urldata.parm:
-                tar_cmd += ' --strip-components=%s' %  urldata.parm['striplevel']
+                striplevel = urldata.parm['striplevel']
+                if not striplevel.isdigit():
+                    raise UnpackError("Invalid striplevel parameter: %s" % striplevel, urldata.url)
+                tar_cmd += ' --strip-components=%s' % striplevel
             if file.endswith('.tar'):
                 cmd = '%s -f %s' % (tar_cmd, file)
             elif file.endswith('.tgz') or file.endswith('.tar.gz') or file.endswith('.tar.Z'):
diff --git a/lib/bb/tests/fetch.py b/lib/bb/tests/fetch.py
index 5735cf8f4..37e4eb9f4 100644
--- a/lib/bb/tests/fetch.py
+++ b/lib/bb/tests/fetch.py
@@ -7,6 +7,7 @@
 #
 
 import contextlib
+import shutil
 import unittest
 import hashlib
 import tempfile
@@ -853,6 +854,16 @@ class FetcherLocalTest(FetcherTest):
 
         self.assertIn("does not contain supported data.tar* file", str(context.exception))
 
+    def assertInvalidStriplevel(self, value):
+        with self.assertRaises(bb.fetch2.UnpackError) as context:
+            self.fetchUnpack(['file://archive.tar;subdir=bar;striplevel=%s' % value])
+        self.assertIn("Invalid striplevel parameter", str(context.exception))
+
+    def test_local_striplevel_rejects_invalid_values(self):
+        for value in ("abc", "", "-1", "1 2"):
+            with self.subTest(striplevel=repr(value)):
+                self.assertInvalidStriplevel(value)
+
     def dummyGitTest(self, suffix):
         # Create dummy local Git repo
         src_dir = tempfile.mkdtemp(dir=self.tempdir,