fix: ignore MSYS mount-table symlink in bundled Git archive
This commit is contained in:
11
pm/store.py
11
pm/store.py
@@ -160,8 +160,8 @@ def _tar_filter(member, dest: str):
|
||||
def extract_tar(archive: Path, dest: Path, *, git_msys: bool = False) -> None:
|
||||
"""Extract a tarball with one containment policy for PM's tar consumers.
|
||||
|
||||
MSYS Git ships dev/fd links into /proc; those aren't usable on Windows.
|
||||
Skip only those known links, never a filter error or failed file write.
|
||||
MSYS Git ships dev/fd links and etc/mtab into /proc; those aren't usable
|
||||
on Windows. Skip only those known links, never a filter error or failed file write.
|
||||
"""
|
||||
import tarfile
|
||||
|
||||
@@ -169,9 +169,10 @@ def extract_tar(archive: Path, dest: Path, *, git_msys: bool = False) -> None:
|
||||
real_dest = os.path.realpath(dest)
|
||||
with tarfile.open(archive) as tf:
|
||||
if git_msys:
|
||||
members = (m for m in tf if not (
|
||||
m.issym() and m.name.lstrip("./").startswith("dev/")
|
||||
and m.linkname.startswith("/proc/")))
|
||||
members = (m for m in tf if not (m.issym() and (
|
||||
(m.name.lstrip("./").startswith("dev/") and m.linkname.startswith("/proc/"))
|
||||
or (m.name == "etc/mtab" and m.linkname == "/proc/mounts")
|
||||
)))
|
||||
for member in members:
|
||||
tf.extract(member, dest, filter=lambda item, path: _tar_filter(item, real_dest))
|
||||
else:
|
||||
|
||||
@@ -42,6 +42,35 @@ def test_symlinks_escaping_the_destination_are_rejected(tmp_path, linkname):
|
||||
extract(archive, tmp_path / "out")
|
||||
assert not (tmp_path / "out" / "python/bin/evil").is_symlink()
|
||||
|
||||
def test_git_tar_ignores_msys_mount_table_link(tmp_path):
|
||||
from pm.packages import Git
|
||||
|
||||
archive = tmp_path / "git.tar.bz2"
|
||||
with tarfile.open(archive, "w:bz2") as tf:
|
||||
mtab = tarfile.TarInfo("etc/mtab")
|
||||
mtab.type, mtab.linkname = tarfile.SYMTYPE, "/proc/mounts"
|
||||
tf.addfile(mtab)
|
||||
binary = tarfile.TarInfo("cmd/git.exe")
|
||||
binary.size = 1
|
||||
tf.addfile(binary, io.BytesIO(b"x"))
|
||||
dest = tmp_path / "out"
|
||||
Git().unpack(archive, dest, "win32-x64")
|
||||
assert (dest / "cmd/git.exe").read_bytes() == b"x"
|
||||
assert not (dest / "etc/mtab").is_symlink()
|
||||
|
||||
|
||||
def test_git_tar_rejects_unrelated_mount_table_links(tmp_path):
|
||||
from pm.packages import Git
|
||||
|
||||
archive = tmp_path / "git.tar.bz2"
|
||||
with tarfile.open(archive, "w:bz2") as tf:
|
||||
mtab = tarfile.TarInfo("etc/mtab")
|
||||
mtab.type, mtab.linkname = tarfile.SYMTYPE, "/etc/passwd"
|
||||
tf.addfile(mtab)
|
||||
with pytest.raises(tarfile.FilterError):
|
||||
Git().unpack(archive, tmp_path / "out", "win32-x64")
|
||||
|
||||
|
||||
def test_git_tar_skips_only_msys_proc_links_and_rejects_other_unsafe_entries(tmp_path):
|
||||
from pm.packages import Git
|
||||
|
||||
|
||||
Reference in New Issue
Block a user