mirror of
https://github.com/ARM-software/devlib.git
synced 2025-01-31 02:00:45 +00:00
Mitigate CVE-2007-4995
Prevent potential directory path traversal attacks (see https://www.trellix.com/en-us/about/newsroom/stories/research/tarfile-exploiting-the-world.html)
This commit is contained in:
parent
678822f9e4
commit
cc3498d315
@ -22,7 +22,7 @@ import tempfile
|
|||||||
from devlib.module import FlashModule
|
from devlib.module import FlashModule
|
||||||
from devlib.exception import HostError
|
from devlib.exception import HostError
|
||||||
from devlib.utils.android import fastboot_flash_partition, fastboot_command
|
from devlib.utils.android import fastboot_flash_partition, fastboot_command
|
||||||
from devlib.utils.misc import merge_dicts
|
from devlib.utils.misc import merge_dicts, safe_extract
|
||||||
|
|
||||||
|
|
||||||
class FastbootFlashModule(FlashModule):
|
class FastbootFlashModule(FlashModule):
|
||||||
@ -86,7 +86,7 @@ class FastbootFlashModule(FlashModule):
|
|||||||
self._validate_image_bundle(image_bundle)
|
self._validate_image_bundle(image_bundle)
|
||||||
extract_dir = tempfile.mkdtemp()
|
extract_dir = tempfile.mkdtemp()
|
||||||
with tarfile.open(image_bundle) as tar:
|
with tarfile.open(image_bundle) as tar:
|
||||||
tar.extractall(path=extract_dir)
|
safe_extract(tar, path=extract_dir)
|
||||||
files = [tf.name for tf in tar.getmembers()]
|
files = [tf.name for tf in tar.getmembers()]
|
||||||
if self.partitions_file_name not in files:
|
if self.partitions_file_name not in files:
|
||||||
extract_dir = os.path.join(extract_dir, files[0])
|
extract_dir = os.path.join(extract_dir, files[0])
|
||||||
|
@ -21,6 +21,7 @@ from subprocess import CalledProcessError
|
|||||||
|
|
||||||
from devlib.module import HardRestModule, BootModule, FlashModule
|
from devlib.module import HardRestModule, BootModule, FlashModule
|
||||||
from devlib.exception import TargetError, TargetStableError, HostError
|
from devlib.exception import TargetError, TargetStableError, HostError
|
||||||
|
from devlib.utils.misc import safe_extract
|
||||||
from devlib.utils.serial_port import open_serial_connection, pulse_dtr, write_characters
|
from devlib.utils.serial_port import open_serial_connection, pulse_dtr, write_characters
|
||||||
from devlib.utils.uefi import UefiMenu, UefiConfig
|
from devlib.utils.uefi import UefiMenu, UefiConfig
|
||||||
from devlib.utils.uboot import UbootMenu
|
from devlib.utils.uboot import UbootMenu
|
||||||
@ -354,7 +355,7 @@ class VersatileExpressFlashModule(FlashModule):
|
|||||||
validate_image_bundle(bundle)
|
validate_image_bundle(bundle)
|
||||||
self.logger.debug('Extracting {} into {}...'.format(bundle, self.vemsd_mount))
|
self.logger.debug('Extracting {} into {}...'.format(bundle, self.vemsd_mount))
|
||||||
with tarfile.open(bundle) as tar:
|
with tarfile.open(bundle) as tar:
|
||||||
tar.extractall(self.vemsd_mount)
|
safe_extract(tar, self.vemsd_mount)
|
||||||
|
|
||||||
def _overlay_images(self, images):
|
def _overlay_images(self, images):
|
||||||
for dest, src in images.items():
|
for dest, src in images.items():
|
||||||
|
@ -61,7 +61,7 @@ from devlib.utils.misc import memoized, isiterable, convert_new_lines, groupby_v
|
|||||||
from devlib.utils.misc import commonprefix, merge_lists
|
from devlib.utils.misc import commonprefix, merge_lists
|
||||||
from devlib.utils.misc import ABI_MAP, get_cpu_name, ranges_to_list
|
from devlib.utils.misc import ABI_MAP, get_cpu_name, ranges_to_list
|
||||||
from devlib.utils.misc import batch_contextmanager, tls_property, _BoundTLSProperty, nullcontext
|
from devlib.utils.misc import batch_contextmanager, tls_property, _BoundTLSProperty, nullcontext
|
||||||
from devlib.utils.misc import strip_bash_colors
|
from devlib.utils.misc import strip_bash_colors, safe_extract
|
||||||
from devlib.utils.types import integer, boolean, bitmask, identifier, caseless_string, bytes_regex
|
from devlib.utils.types import integer, boolean, bitmask, identifier, caseless_string, bytes_regex
|
||||||
import devlib.utils.asyn as asyn
|
import devlib.utils.asyn as asyn
|
||||||
|
|
||||||
@ -827,7 +827,7 @@ class Target(object):
|
|||||||
await self.pull.asyn(tar_file_name, tmpfile)
|
await self.pull.asyn(tar_file_name, tmpfile)
|
||||||
# Decompress
|
# Decompress
|
||||||
with tarfile.open(tmpfile, 'r') as f:
|
with tarfile.open(tmpfile, 'r') as f:
|
||||||
f.extractall(outdir)
|
safe_extract(f, outdir)
|
||||||
os.remove(tmpfile)
|
os.remove(tmpfile)
|
||||||
|
|
||||||
# execution
|
# execution
|
||||||
|
@ -991,3 +991,26 @@ def groupby_value(dct):
|
|||||||
tuple(map(itemgetter(0), _items)): v
|
tuple(map(itemgetter(0), _items)): v
|
||||||
for v, _items in groupby(items, key=key)
|
for v, _items in groupby(items, key=key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def safe_extract(tar, path=".", members=None, *, numeric_owner=False):
|
||||||
|
"""
|
||||||
|
A wrapper around TarFile.extract all to mitigate CVE-2007-4995
|
||||||
|
(see https://www.trellix.com/en-us/about/newsroom/stories/research/tarfile-exploiting-the-world.html)
|
||||||
|
"""
|
||||||
|
|
||||||
|
for member in tar.getmembers():
|
||||||
|
member_path = os.path.join(path, member.name)
|
||||||
|
if not _is_within_directory(path, member_path):
|
||||||
|
raise Exception("Attempted Path Traversal in Tar File")
|
||||||
|
|
||||||
|
tar.extractall(path, members, numeric_owner=numeric_owner)
|
||||||
|
|
||||||
|
def _is_within_directory(directory, target):
|
||||||
|
|
||||||
|
abs_directory = os.path.abspath(directory)
|
||||||
|
abs_target = os.path.abspath(target)
|
||||||
|
|
||||||
|
prefix = os.path.commonprefix([abs_directory, abs_target])
|
||||||
|
|
||||||
|
return prefix == abs_directory
|
||||||
|
Loading…
x
Reference in New Issue
Block a user