[3.12] gh-135034: Normalize link targets in tarfile, add os.path.realpath(strict='allow_missing') (GH-135037) (GH-135066)

Addresses CVEs 2024-12718, 2025-4138, 2025-4330, and 2025-4517.

(cherry picked from commit 3612d8f517)

Co-authored-by: Łukasz Langa <lukasz@langa.pl>
Signed-off-by: Łukasz Langa <lukasz@langa.pl>
Co-authored-by: Petr Viktorin <encukou@gmail.com>
Co-authored-by: Seth Michael Larson <seth@python.org>
Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
T. Wouters 2025-06-03 16:00:21 +02:00 committed by GitHub
parent f3272d8630
commit 19de092deb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 1067 additions and 142 deletions

View file

@ -35,7 +35,7 @@ __all__ = ["normcase","isabs","join","splitdrive","splitroot","split","splitext"
"samefile","sameopenfile","samestat",
"curdir","pardir","sep","pathsep","defpath","altsep","extsep",
"devnull","realpath","supports_unicode_filenames","relpath",
"commonpath", "isjunction"]
"commonpath", "isjunction", "ALLOW_MISSING"]
def _get_sep(path):
@ -438,6 +438,15 @@ def _joinrealpath(path, rest, strict, seen):
sep = '/'
curdir = '.'
pardir = '..'
getcwd = os.getcwd
if strict is ALLOW_MISSING:
ignored_error = FileNotFoundError
elif strict:
ignored_error = ()
else:
ignored_error = OSError
maxlinks = None
if isabs(rest):
rest = rest[1:]
@ -460,9 +469,7 @@ def _joinrealpath(path, rest, strict, seen):
newpath = join(path, name)
try:
st = os.lstat(newpath)
except OSError:
if strict:
raise
except ignored_error:
is_link = False
else:
is_link = stat.S_ISLNK(st.st_mode)