Skip to content

Unpacking CPIO filesystem fails on MacOS because of permissions #616

@paulnoalhyt

Description

@paulnoalhyt

What is the problem? (Here is where you provide a complete Traceback.)

On MacOS, unpacking a CpioFilesystem fails with a Permission Denied error:

python3 -m ofrak gui -b angr -H 0 -p 8877
GUI is being served on http://0:8877/
[     iso9660.py:  194] El Torito images are not currently supported
[      server.py:  122] Exception raised in aiohttp endpoint
ofrak.service.job_service_i.ComponentAutoRunFailure: Component CpioUnpacker failed when running on bea2e5503bad4d95a53155fcb8562211. Component was chosen because it matched filters (((ComponentTypeFilter(Unpacker) or ComponentTypeFilter(Identifier))) and ((ComponentTypeFilter(Identifier) and ComponentTargetFilter(FilesystemRoot, CpioFilesystem)) or (ComponentTypeFilter(Analyzer) and ComponentTargetFilter(FilesystemRoot, CpioFilesystem)) or (not ComponentTypeFilter(Identifier) and not ComponentTypeFilter(Analyzer) and (ComponentTargetFilter(CpioFilesystem) then ComponentTargetFilter(FilesystemRoot)))))

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/ofrak/ofrak_core/ofrak/gui/server.py", line 120, in wrapper
    return await func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/ofrak/ofrak_core/ofrak/gui/server.py", line 486, in unpack
    raise e
  File "/ofrak/ofrak_core/ofrak/gui/server.py", line 482, in unpack
    result = await resource.unpack()
             ^^^^^^^^^^^^^^^^^^^^^^^
  File "/ofrak/ofrak_core/ofrak/resource.py", line 461, in unpack
    return await self.auto_run(all_identifiers=True, all_unpackers=True)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/ofrak/ofrak_core/ofrak/resource.py", line 434, in auto_run
    components_result = await self._job_service.run_components(
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/ofrak/ofrak_core/ofrak/service/job_service.py", line 277, in run_components
    individual_component_results = await self._auto_run_components(
                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/ofrak/ofrak_core/ofrak/service/job_service.py", line 471, in _auto_run_components
    raise component_run_error from ComponentAutoRunFailure(
  File "/ofrak/ofrak_core/ofrak/service/job_service.py", line 133, in _run_component
    result = await component.run(
             ^^^^^^^^^^^^^^^^^^^^
  File "/ofrak/ofrak_core/ofrak/component/abstract.py", line 94, in run
    await self._run(resource, config)
  File "/ofrak/ofrak_core/ofrak/component/unpacker.py", line 83, in _run
    await self.unpack(resource, config)
  File "/ofrak/ofrak_core/ofrak/core/cpio.py", line 105, in unpack
    await cpio_v.initialize_from_disk(temp_flush_dir)
  File "/ofrak/ofrak_core/ofrak/core/filesystem.py", line 457, in initialize_from_disk
    file_attributes_xattr = self._get_xattr_map(absolute_path)
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/ofrak/ofrak_core/ofrak/core/filesystem.py", line 721, in _get_xattr_map
    for attr in xattr.listxattr(path, symlink=True):  # Don't follow links
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/ofrak/venv/lib/python3.11/site-packages/xattr/__init__.py", line 174, in listxattr
    return tuple(xattr(f).list(options=symlink and XATTR_NOFOLLOW or 0))
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/ofrak/venv/lib/python3.11/site-packages/xattr/__init__.py", line 96, in list
    res = self._call(_listxattr, _flistxattr, options | self.options).split(b'\x00')
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/ofrak/venv/lib/python3.11/site-packages/xattr/__init__.py", line 60, in _call
    return name_func(self.value, *args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/ofrak/venv/lib/python3.11/site-packages/xattr/lib.py", line 124, in _listxattr
    raise error(path)
          ^^^^^^^^^^^
  File "/ofrak/venv/lib/python3.11/site-packages/xattr/lib.py", line 33, in error
    raise IOError(errno, strerror, path)
PermissionError: [Errno 13] Permission denied: b'/var/folders/xd/vwvhg3g14kbfvzl82w905pnc0000gn/T/tmplq4xvj9o/usr/bin/sudo'

Please provide some information about your environment.

Platform: MacOS, python3.11

If you've discovered it, what is the root cause of the problem?

How often does the issue happen?

Always, when triggered through the steps below.

What are the steps to reproduce the issue?

Start the OFRAK GUI. Then load this binary: http://www.tinycorelinux.net/16.x/x86/release/TinyCore-current.iso. Click unpack, select boot/core.gz, click unpack. Finally click unpack on the child of that.

Script from the OFRAK GUI:

from ofrak import *
from ofrak.core import *
from ofrak.gui.script_builder import get_child_by_range


async def main(ofrak_context: OFRAKContext, root_resource: Optional[Resource] = None):
    if root_resource is None:
        root_resource = await ofrak_context.create_root_resource_from_file(
            "TinyCore-current.iso"
        )

    await root_resource.unpack()

    folder_boot = await root_resource.get_only_child(
        r_filter=ResourceFilter(
            tags={Folder, ISO9660Entry},
            attribute_filters=[
                ResourceAttributeValueFilter(
                    attribute=AttributesType[FilesystemEntry].Name, value="boot"
                )
            ],
        )
    )

    file_core_gz = await folder_boot.get_only_child(
        r_filter=ResourceFilter(
            tags={File, ISO9660Entry},
            attribute_filters=[
                ResourceAttributeValueFilter(
                    attribute=AttributesType[FilesystemEntry].Name, value="core.gz"
                )
            ],
        )
    )

    await file_core_gz.unpack()


if __name__ == "__main__":
    ofrak = OFRAK()
    if False:
        import ofrak_angr
        import ofrak_capstone

        ofrak.discover(ofrak_capstone)
        ofrak.discover(ofrak_angr)

    if False:
        import ofrak_binary_ninja
        import ofrak_capstone

        ofrak.discover(ofrak_capstone)
        ofrak.discover(ofrak_binary_ninja)

    if False:
        import ofrak_ghidra

        ofrak.discover(ofrak_ghidra)

    ofrak.run(main)

How would you implement this fix?

Are there any (reasonable) alternative approaches?

Are you interested in implementing it yourself?

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions