bitter-ability-32190
10/27/2022, 8:16 PMpytest.param(
CreateDigest(
[
FileContent("file.txt", b"four\n"),
SymlinkEntry("a/dirlink", "../b/c/d"),
SymlinkEntry("b/c/d/link", "../../file.txt"),
]
),
# NOTE: No "b/c/d/link", because that'd result in "a/file.txt"
("a/dirlink/link", "file.txt"),
("a", "a/dirlink", "b", "b/c", "b/c/d"),
id="symlink-makes-updir-valid",
),
Please let me know your favorite evil symlink scenario, and we'll turn the testing up to 11.broad-processor-92400
10/27/2022, 11:03 PMlhs -> rhs
is a link called lhs
pointing to a file rhs
, i.e. created via ln -s rhs lhs
)
.
├── broken -> doesnt_exist
├── dir
│ ├── parent -> ..
│ ├── self -> .
│ ├── self_obtusely -> ../dir
│ └── self_very_obtusely -> self/self/self/self/self_obtusely/parent/dir/parent/dir/parent/dir/self
├── escape
│ ├── absolute -> /etc/passwd
│ └── traversal -> ../../../../../../../../../../../../etc/passwd
└── loop
├── chain1 -> chain2
├── chain2 -> chain3
├── chain3 -> chain1
├── self -> self
├── via_chain -> chain1/file.txt
└── via_self -> self/file.txt
Most of these are ... going out of my way to be difficult, but:
• I imagine the escape/absolute
one could come in practice, e.g. a Python venv seems to have an absolute symlink to its interpreter.
• readlink -f dir/self_very_obtusely
confirms that it is pointing to dir/
• Naive tooling may infinite-loop on some of the loop
ones too.bitter-ability-32190
10/28/2022, 1:31 AMbitter-ability-32190
11/02/2022, 2:23 PMself_obtusely
is gnarly. Since the preceder is .
, you can't just go resolve the parent directory but lopping off the component above it. You need to resolve that, then go up one!bitter-ability-32190
11/02/2022, 2:31 PM"."
is the evilest symlink in existance