normalize symlinks by relying on purepath

This commit is contained in:
Abyss Watcher
2025-02-15 15:24:53 +01:00
parent 51b66f7573
commit c2f8697cc5
@@ -10,9 +10,10 @@ import tarfile
from dataclasses import dataclass, astuple
from typing import IO, List, Set, Type, Iterable, Tuple
from io import BytesIO
from pathlib import PurePath
from volatility3.framework.constants import architectures
from volatility3.framework import renderers, interfaces, exceptions
from volatility3.framework import constants, renderers, interfaces, exceptions
from volatility3.framework.renderers import format_hints
from volatility3.framework.interfaces import plugins
from volatility3.framework.configuration import requirements
@@ -730,6 +731,7 @@ class RecoverFs(plugins.PluginInterface):
tar: tarfile.TarFile,
symlink_source: str,
symlink_dest: str,
symlink_source_prefix: str = "",
mtime: float = None,
) -> None:
"""Adds a symlink to a TarFile object.
@@ -738,15 +740,21 @@ class RecoverFs(plugins.PluginInterface):
tar: The TarFile object to write to
symlink_source: The symlink source path
symlink_dest: The symlink target/destination
symlink_source_prefix: A custom path prefix to prepend the symlink source with
mtime: The modification time to set the TarInfo object to
"""
# Patch symlinks pointing to absolute paths,
# to prevent referencing the host filesystem.
if symlink_dest.startswith("/"):
inode_depth = symlink_source.strip("/").count("/")
symlink_dest = "../" * inode_depth + symlink_dest.lstrip("/")
tar_info = tarfile.TarInfo(symlink_source)
relative_dest = PurePath(symlink_dest).relative_to(PurePath("/"))
# Remove the leading "/" to prevent an extra undesired "../" in the output
symlink_dest = (
PurePath(
*[".."] * len(PurePath(symlink_source.lstrip("/")).parent.parts)
)
/ relative_dest
).as_posix()
tar_info = tarfile.TarInfo(symlink_source_prefix + symlink_source)
tar_info.type = tarfile.SYMTYPE
tar_info.linkname = symlink_dest
tar_info.mode = 0o444
@@ -820,7 +828,7 @@ class RecoverFs(plugins.PluginInterface):
symlink_dest = inode_in.inode.i_link.dereference().cast(
"string", max_length=255, encoding="utf-8", errors="replace"
)
self._tar_add_lnk(tar, prefixed_path, symlink_dest, mtime)
self._tar_add_lnk(tar, inode_in.path, symlink_dest, prefix, mtime)
# Set path to a user friendly representation before yielding
inode_in.path = InodeUser.format_symlink(inode_in.path, symlink_dest)
else: