diff --git a/bitbake/lib/bb/fetch2/__init__.py b/bitbake/lib/bb/fetch2/__init__.py index 06f1eb4e81..cd7362c44a 100644 --- a/bitbake/lib/bb/fetch2/__init__.py +++ b/bitbake/lib/bb/fetch2/__init__.py @@ -1420,7 +1420,13 @@ class FetchMethod(object): # If 'subdir' param exists, create a dir and use it as destination for unpack cmd if 'subdir' in urldata.parm: - unpackdir = '%s/%s' % (rootdir, urldata.parm.get('subdir')) + subdir = urldata.parm.get('subdir') + if os.path.isabs(subdir): + if not os.path.realpath(subdir).startswith(os.path.realpath(rootdir)): + raise UnpackError("subdir argument isn't a subdirectory of unpack root %s" % rootdir, urldata.url) + unpackdir = subdir + else: + unpackdir = os.path.join(rootdir, subdir) bb.utils.mkdirhier(unpackdir) else: unpackdir = rootdir diff --git a/bitbake/lib/bb/tests/fetch.py b/bitbake/lib/bb/tests/fetch.py index d7c73dda02..0fd2c02163 100644 --- a/bitbake/lib/bb/tests/fetch.py +++ b/bitbake/lib/bb/tests/fetch.py @@ -508,6 +508,15 @@ class FetcherLocalTest(FetcherTest): tree = self.fetchUnpack(['file://dir/subdir/e;subdir=bar']) self.assertEqual(tree, ['bar/dir/subdir/e']) + def test_local_absolutedir(self): + # Unpacking to an absolute path that is a subdirectory of the root + # should work + tree = self.fetchUnpack(['file://a;subdir=%s' % os.path.join(self.unpackdir, 'bar')]) + + # Unpacking to an absolute path outside of the root should fail + with self.assertRaises(bb.fetch2.UnpackError): + self.fetchUnpack(['file://a;subdir=/bin/sh']) + class FetcherNetworkTest(FetcherTest): if os.environ.get("BB_SKIP_NETTESTS") == "yes":