This project is archived. Its data is read-only.

BuildStream chokes when staging tarfiles with hardlinks that point outside of a chosen base directory

Summary

When BuildStream stages a tarfile, it will remove the first couple of characters from certain file names to extract things correctly. This is all fine and dandy, however, the code as-is, fails to extract certain kinds of hardlinks, as duly documented in the plugin itself.

Steps to reproduce

  1. Create a tarfile with a hardlink that points outside its base directory.
  2. Stage it.

What is the current bug behavior?

BuildStream reports a BUG and stops building.

What is the expected correct behavior?

BuildStream should continue building!

Relevant logs and/or screenshots

py37 develop-inst-noop: /home/tlater/Documents/Work/buildstream/buildstream
py37 installed: apipkg==1.5,arpy==1.1.1,astroid==2.1.0,atomicwrites==1.3.0,attrs==18.2.0,-e git+git@gitlab.com:BuildStream/buildstream.git@f61f47cd519fa2402ff0b7d7e4a91ce63b84b0c3#egg=BuildStream,Click==7.0,coverage==4.4,Cython==0.29.7,execnet==1.5.0,grpcio==1.17.1,isort==4.3.9,Jinja2==2.10,lazy-object-proxy==1.3.1,MarkupSafe==1.1.0,mccabe==0.6.1,more-itertools==6.0.0,pathlib2==2.3.3,pluggy==0.9.0,pluginbase==0.7,protobuf==3.6.1,psutil==5.4.8,py==1.8.0,pycodestyle==2.5.0,pyftpdlib==1.5.4,pylint==2.2.2,pyroaring==0.2.6,pytest==4.3.0,pytest-cov==2.6.1,pytest-datafiles==2.0,pytest-env==0.6.2,pytest-forked==1.0.2,pytest-timeout==1.3.3,pytest-xdist==1.26.1,ruamel.yaml==0.15.51,six==1.12.0,typed-ast==1.3.1,ujson==1.35,wrapt==1.11.1
py37 run-test-pre: PYTHONHASHSEED='2994009352'
py37 run-test: commands[0] | pytest --basetemp /home/tlater/Documents/Work/buildstream/buildstream/.tox/py37/tmp --cov=buildstream --cov-config .coveragerc --integration -m integration --no-cov -x --lf
============================= test session starts ==============================
platform linux -- Python 3.7.3, pytest-4.3.0, py-1.8.0, pluggy-0.9.0 -- /home/tlater/Documents/Work/buildstream/buildstream/.tox/py37/bin/python
cachedir: .tox/py37/.pytest_cache
rootdir: /home/tlater/Documents/Work/buildstream/buildstream, inifile: setup.cfg
plugins: xdist-1.26.1, timeout-1.3.3, forked-1.0.2, env-0.6.2, datafiles-2.0, cov-2.6.1
collecting ... collected 1292 items / 1291 deselected / 1 selected
run-last-failure: rerun previous 2 failures

tests/examples/autotools.py::test_autotools_build FAILED                 [100%]

=================================== FAILURES ===================================
_____________________________ test_autotools_build _____________________________

cli = <buildstream.testing.runcli.CliIntegration object at 0x7f9b78f73828>
datafiles = local('/home/tlater/Documents/Work/buildstream/buildstream/.tox/py37/tmp/test_autotools_build0')

    @pytest.mark.skipif(MACHINE_ARCH != 'x86-64',
                        reason='Examples are written for x86-64')
    @pytest.mark.skipif(not IS_LINUX or not HAVE_BWRAP, reason='Only available on linux with bubblewrap')
    @pytest.mark.datafiles(DATA_DIR)
    def test_autotools_build(cli, datafiles):
        project = str(datafiles)
        checkout = os.path.join(cli.directory, 'checkout')
    
        # Check that the project can be built correctly.
        result = cli.run(project=project, args=['build', 'hello.bst'])
>       result.assert_success()

tests/examples/autotools.py:29: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <buildstream.testing.runcli.Result object at 0x7f9b78f7dda0>
fail_message = ''

    def assert_success(self, fail_message=''):
>       assert self.exit_code == 0, fail_message
E       AssertionError

src/buildstream/testing/runcli.py:115: AssertionError
----------------------------- Captured stdout call -----------------------------
BuildStream exited with code -1 for invocation:
	bst --no-colors --config /home/tlater/Documents/Work/buildstream/buildstream/.tox/py37/tmp/test_autotools_build0/cache/buildstream.conf --directory /home/tlater/Documents/Work/buildstream/buildstream/.tox/py37/tmp/test_autotools_build0 build hello.bst
Program stderr was:
[--:--:--][        ][    main:core activity                 ] START   Build
[--:--:--][        ][    main:core activity                 ] START   Loading elements
[00:00:00][        ][    main:core activity                 ] SUCCESS Loading elements
[--:--:--][        ][    main:core activity                 ] START   Resolving elements
[00:00:00][        ][    main:core activity                 ] SUCCESS Resolving elements
[--:--:--][        ][    main:core activity                 ] START   Resolving cached state
[00:00:00][        ][    main:core activity                 ] SUCCESS Resolving cached state
[--:--:--][        ][    main:core activity                 ] START   Checking sources
[00:00:00][        ][    main:core activity                 ] SUCCESS Checking sources

BuildStream Version 1.3.0+2355.gf61f47cd.dirty
  Session Start: Monday, 24-06-2019 at 13:40:01
  Project:       autotools (/home/tlater/Documents/Work/buildstream/buildstream/.tox/py37/tmp/test_autotools_build0)
  Targets:       hello.bst
  Cache Usage:   12K / None (0%)

User Configuration
  Configuration File:      /home/tlater/Documents/Work/buildstream/buildstream/.tox/py37/tmp/test_autotools_build0/cache/buildstream.conf
  Cache Directory:         /home/tlater/Documents/Work/buildstream/buildstream/integration-cache/cache-9kfotmgf
  Log Files:               /home/tlater/Documents/Work/buildstream/buildstream/.tox/py37/tmp/test_autotools_build0/cache/logs
  Source Mirrors:          /home/tlater/Documents/Work/buildstream/buildstream/integration-cache/sources
  Build Area:              /home/tlater/Documents/Work/buildstream/buildstream/integration-cache/cache-9kfotmgf/build
  Strict Build Plan:       Yes
  Maximum Fetch Tasks:     10
  Maximum Build Tasks:     4
  Maximum Push Tasks:      4
  Maximum Network Retries: 2

Pipeline
   buildable 7ea72715664f3125eac3063c5120c47ffe4327f90b61af0d809b6f153f617b49 base/freedesktop.bst 
     waiting d098691a4af90e544427c18b3c051a738fc81558cb7b664287a43fa82a0fff61 base.bst 
     waiting b4cda6988d11b1606e330a55aad1d2e9f1468b623e448bd09ae7e931f3e60d81 hello.bst 
===============================================================================
[--:--:--][7ea72715][   fetch:base/freedesktop.bst          ] START   autotools/base-freedesktop/7ea72715-fetch.5780.log
[--:--:--][b4cda698][   fetch:hello.bst                     ] START   autotools/hello/b4cda698-fetch.5782.log
[00:00:00][b4cda698][   fetch:hello.bst                     ] SUCCESS autotools/hello/b4cda698-fetch.5782.log
[00:00:18][7ea72715][   fetch:base/freedesktop.bst          ] BUG     Fetch

    An unhandled exception occured:
    
    Traceback (most recent call last):
      File "/home/tlater/Documents/Work/buildstream/buildstream/src/buildstream/_scheduler/jobs/job.py", line 699, in child_action
        result = self.child_process()  # pylint: disable=assignment-from-no-return
      File "/home/tlater/Documents/Work/buildstream/buildstream/src/buildstream/_scheduler/jobs/elementjob.py", line 108, in child_process
        return self._action_cb(self._element)
      File "/home/tlater/Documents/Work/buildstream/buildstream/src/buildstream/_scheduler/queues/fetchqueue.py", line 45, in process
        element._fetch(fetch_original=self._fetch_original)
      File "/home/tlater/Documents/Work/buildstream/buildstream/src/buildstream/element.py", line 2183, in _fetch
        self.__cache_sources()
      File "/home/tlater/Documents/Work/buildstream/buildstream/src/buildstream/element.py", line 2932, in __cache_sources
        self.__sourcecache.commit(source, [])
      File "/home/tlater/Documents/Work/buildstream/buildstream/src/buildstream/_sourcecache.py", line 160, in commit
        source._stage(tmpdir)
      File "/home/tlater/Documents/Work/buildstream/buildstream/src/buildstream/source.py", line 740, in _stage
        self.stage(directory)
      File "/home/tlater/Documents/Work/buildstream/buildstream/src/buildstream/plugins/sources/tar.py", line 117, in stage
        tar.extractall(path=directory, members=self._extract_members(tar, base_dir))
      File "/home/tlater/Documents/Work/buildstream/buildstream/.tox/py37/lib/python3.7/tarfile.py", line 2002, in extractall
        numeric_owner=numeric_owner)
      File "/home/tlater/Documents/Work/buildstream/buildstream/.tox/py37/lib/python3.7/tarfile.py", line 2044, in extract
        numeric_owner=numeric_owner)
      File "/home/tlater/Documents/Work/buildstream/buildstream/.tox/py37/lib/python3.7/tarfile.py", line 2122, in _extract_member
        self.makelink(tarinfo, targetpath)
      File "/home/tlater/Documents/Work/buildstream/buildstream/.tox/py37/lib/python3.7/tarfile.py", line 2210, in makelink
        self._extract_member(self._find_link_target(tarinfo),
      File "/home/tlater/Documents/Work/buildstream/buildstream/.tox/py37/lib/python3.7/tarfile.py", line 2380, in _find_link_target
        raise KeyError("linkname %r not found" % linkname)
    KeyError: "linkname 'c/ssl/ct_log_list.cnf' not found"

[00:00:18][        ][    main:core activity                 ] FAILURE Build

Failure Summary
  base/freedesktop.bst:
    [00:00:18][7ea72715][   fetch:base/freedesktop.bst          ] BUG     Fetch

        An unhandled exception occured:
    
        Traceback (most recent call last):
          File "/home/tlater/Documents/Work/buildstream/buildstream/src/buildstream/_scheduler/jobs/job.py", line 699, in child_action
            result = self.child_process()  # pylint: disable=assignment-from-no-return
          File "/home/tlater/Documents/Work/buildstream/buildstream/src/buildstream/_scheduler/jobs/elementjob.py", line 108, in child_process
            return self._action_cb(self._element)
          File "/home/tlater/Documents/Work/buildstream/buildstream/src/buildstream/_scheduler/queues/fetchqueue.py", line 45, in process
            element._fetch(fetch_original=self._fetch_original)
          File "/home/tlater/Documents/Work/buildstream/buildstream/src/buildstream/element.py", line 2183, in _fetch
            self.__cache_sources()
          File "/home/tlater/Documents/Work/buildstream/buildstream/src/buildstream/element.py", line 2932, in __cache_sources
            self.__sourcecache.commit(source, [])
          File "/home/tlater/Documents/Work/buildstream/buildstream/src/buildstream/_sourcecache.py", line 160, in commit
            source._stage(tmpdir)
          File "/home/tlater/Documents/Work/buildstream/buildstream/src/buildstream/source.py", line 740, in _stage
            self.stage(directory)
          File "/home/tlater/Documents/Work/buildstream/buildstream/src/buildstream/plugins/sources/tar.py", line 117, in stage
            tar.extractall(path=directory, members=self._extract_members(tar, base_dir))
          File "/home/tlater/Documents/Work/buildstream/buildstream/.tox/py37/lib/python3.7/tarfile.py", line 2002, in extractall
            numeric_owner=numeric_owner)
          File "/home/tlater/Documents/Work/buildstream/buildstream/.tox/py37/lib/python3.7/tarfile.py", line 2044, in extract
            numeric_owner=numeric_owner)
          File "/home/tlater/Documents/Work/buildstream/buildstream/.tox/py37/lib/python3.7/tarfile.py", line 2122, in _extract_member
            self.makelink(tarinfo, targetpath)
          File "/home/tlater/Documents/Work/buildstream/buildstream/.tox/py37/lib/python3.7/tarfile.py", line 2210, in makelink
            self._extract_member(self._find_link_target(tarinfo),
          File "/home/tlater/Documents/Work/buildstream/buildstream/.tox/py37/lib/python3.7/tarfile.py", line 2380, in _find_link_target
            raise KeyError("linkname %r not found" % linkname)
        KeyError: "linkname 'c/ssl/ct_log_list.cnf' not found"

Pipeline Summary
  Total:       3
  Session:     3
  Fetch Queue: processed 1, skipped 1, failed 1 
  Build Queue: processed 0, skipped 0, failed 0 



=============================== warnings summary ===============================
.tox/py37/lib/python3.7/site-packages/pluginbase.py:439
  /home/tlater/Documents/Work/buildstream/buildstream/.tox/py37/lib/python3.7/site-packages/pluginbase.py:439: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
    fromlist, level)

-- Docs: https://docs.pytest.org/en/latest/warnings.html
WARNING: Coverage disabled via --no-cov switch!
========================== slowest 20 test durations ===========================
18.60s call     tests/examples/autotools.py::test_autotools_build
0.06s teardown tests/examples/autotools.py::test_autotools_build

(0.00 durations hidden.  Use -vv to show these durations.)
=========================== warnings summary (final) ===========================
.tox/py37/lib/python3.7/site-packages/pytest_cov/plugin.py:253
  /home/tlater/Documents/Work/buildstream/buildstream/.tox/py37/lib/python3.7/site-packages/pytest_cov/plugin.py:253: PytestWarning: Coverage disabled via --no-cov switch!
    warnings.warn(pytest.PytestWarning(message))

-- Docs: https://docs.pytest.org/en/latest/warnings.html
============ 1 failed, 1291 deselected, 2 warnings in 25.13 seconds ============
ERROR: InvocationError for command /home/tlater/Documents/Work/buildstream/buildstream/.tox/py37/bin/pytest --basetemp .tox/py37/tmp --cov=buildstream --cov-config .coveragerc --integration -m integration --no-cov -x --lf (exited with code 1)
___________________________________ summary ____________________________________
ERROR:   py37: commands failed

Other relevant information

  • BuildStream version affected: /milestone %BuildStream_v1.2 BuildStream_v2.0

Edited Jun 24, 2019 by Tristan Maat
Assignee Loading
Time tracking Loading