alt-python38 (3.8.20-32) stable; urgency=medium

  * SECURITY UPDATE: use-after-free of a server-side ssl.SSLContext when an
    sni_callback switches the connection to another context.
    _servername_callback() in Modules/_ssl.c reached the _SSLContext through
    the borrowed pointer stored with SSL_CTX_set_tlsext_servername_arg() and
    held no reference to it or to its callback. Assigning a new context to
    SSLSocket.context from the callback could drop the original context's
    last reference, after which the C code used freed memory - via
    PyErr_WriteUnraisable() after a raising callback, and on a second
    ClientHello (TLS 1.3 HelloRetryRequest) through the stale session_ctx.
    - debian/patches/CVE-2026-19445.patch: backport of cpython
      ec44b5a3258cbda947d5e07242ee562ed05ef24b (3.10 branch, gh-156293,
      GH-158504): look the context up from the SSL object and hold strong
      references to it and to the callback, stop installing the borrowed
      servername arg, and unregister the servername callback in
      context_dealloc(). Py_NewRef()/Py_IS_TYPE()/module state do not exist
      in 3.8 and were replaced by Py_INCREF()/PySSLSocket_Check(). Includes
      the upstream regression tests in Lib/test/test_ssl.py.
    - CVE-2026-19445

  * SECURITY UPDATE: ssl.SSLContext.wrap_bio() skipped hostname verification
    when check_hostname was enabled but no server_hostname was given
    (CWE-295). SSLObject._create() lacked the "check_hostname requires
    server_hostname" check that wrap_socket() performs, so memory-BIO users
    such as asyncio loop.start_tls() and create_connection(...,
    server_hostname='') verified the certificate chain but never the peer's
    identity.
    - debian/patches/CVE-2026-19553.patch: backport of cpython
      1697ea386c707142555d98a1263176bbbc014a96 (gh-156793, GH-158503; 3.13
      f4e43ba525187282f2011da0e6ffc0d2b08d8062), which adds
      _check_sslobject_params() to Lib/ssl.py and calls it from both
      SSLObject._create() and SSLSocket._create(), so wrap_bio() raises
      ValueError like wrap_socket(). The 3.10-3.12 branches only warn with a
      DeprecationWarning, which still skips the check, so the ValueError
      behaviour was taken. Includes the upstream test_ssl tests and
      test_sslproto tests rewritten for 3.8's connection_made()-time
      wrap_bio().
    - CVE-2026-19553

 -- Juan Carlos Garcia <jgarcia@cloudlinux.com>  Mon, 05 Oct 2026 12:00:00 +0000

alt-python38 (3.8.20-31) stable; urgency=medium

  * SECURITY UPDATE: urllib.request HTTPPasswordMgr handed out credentials
    across URL schemes (CWE-523, unprotected transport of credentials).
    reduce_uri() reduces a URI to (authority, path) and drops the scheme, so
    add_password() and find_user_password() - and HTTPPasswordMgrWithPriorAuth
    update_authenticated()/is_authenticated() - treated "https://host/" and
    "http://host/" as the same URI. Credentials registered only for the
    TLS-protected origin were therefore sent in cleartext to an http:// URL
    reached through a downgrade or redirect.
    - debian/patches/CVE-2026-15806.patch: backport of cpython
      a2773a34183b7d94a243bb98fd658926cc5348ce (gh-155694, GH-155696), which
      adds _reduce_uri_with_scheme() and _is_suburi_with_scheme() and uses them
      in the password managers; a URI registered without a scheme still
      matches any scheme, keeping proxy authentication working. Includes the
      upstream regression tests in Lib/test/test_urllib2.py.
    - CVE-2026-15806

  * SECURITY UPDATE: stringprep (the "idna" codec, IDNA 2003) case-folded
    characters using post-Unicode-3.2.0 data. RFC 3454 mandates Unicode 3.2.0,
    but map_table_b3() falls back to str.lower() for any codepoint missing from
    the generated b3_exceptions table, and str.lower() uses the interpreter's
    bundled Unicode (12.1.0 here). Characters that gained a lowercase mapping
    later - Cherokee, Cyrillic Palochka, Georgian Mtavruli, Adlam, ... - were
    folded, so different Python versions derived different A-labels for the
    same U-label.
    - debian/patches/CVE-2026-17084.patch: backport of cpython
      1e54caa096678a38afcabecabb1ff72400dd6bae (gh-155292, GH-155293), which
      pins every such codepoint to itself in b3_exceptions, renames the 3.2.0
      alias to unicodedata_320 and asserts the bundled unidata_version, plus
      the generator change in Tools/unicode/mkstringprep.py and the new idna
      test in Lib/test/test_codecs.py. The upstream table is specific to its
      UCD, so Lib/stringprep.py was regenerated with this version's own
      interpreter (UCD 12.1.0: 641 identity entries added).
    - CVE-2026-17084

 -- Juan Carlos Garcia <jgarcia@cloudlinux.com>  Thu, 24 Sep 2026 12:00:00 +0000

alt-python38 (3.8.20-30) stable; urgency=medium

  * SECURITY UPDATE: tarfile ignored a filter's None ("skip this member")
    answer in the hard-link extraction fallback (CWE-59, link following). The
    guard CVE-2026-11940 added to TarFile.makelink_with_filter() re-runs the
    filter on the referenced member re-rooted at the link's own, shallower
    name before the fallback extracts it there, but it only reacted to the
    exceptions that extra call could raise and discarded its return value. A
    PEP 706 filter is also allowed to return None to mean "skip this member",
    and that answer was ignored: the second call, made with the member's own
    name, still succeeded and the member was written at the link's path
    anyway. A custom filter that downgrades FilterError to None - the
    documented way to skip unsafe members instead of aborting the whole
    extraction - therefore did not stop the escape CVE-2026-11940 was meant
    to close. Reproduced on the patched 3.8.20 tree with a two-member archive
    ('a/b/s' symlink -> '../escape', 'q' hard link -> 'a/b/s') extracted with
    a filter returning None on FilterError: before the fix dest/q is
    materialised as a symlink to '../escape', whose body points outside the
    destination; after it, 'q' is skipped and only a/b/s is extracted.
    - debian/patches/CVE-2026-87910.patch: backport of cpython
      9c17bace90f88dfba6d0e2fe23c8e7ae35f83955 (gh-157265, GH-157266,
      GH-157308, squashing the test follow-up GH-157334), which keeps the
      first filter call's result and returns early when it is None, plus its
      regression test test_extract_filters_target_none in
      Lib/test/test_tarfile.py. Applied after CVE-2026-11940.patch, whose
      guard it fixes; the two must not be separated or reordered.
    - CVE-2026-87910

  * SECURITY UPDATE: tarfile 'tar'/'data' extraction filters created
    directories outside the destination for a member whose name leaves the
    destination and comes back (CWE-22, path traversal). _get_filtered_attrs()
    checks containment by resolving the member name against the destination
    and comparing with os.path.commonpath(); a name such as
    '../evil/../dest/sub/file' resolves back inside and passes the check, but
    the intermediate directories are created from the name as given and walk
    out of the destination on the way. Extracting an untrusted archive into a
    scratch directory therefore left attacker-chosen directories next to it,
    under the very filters meant to prevent that. Reproduced on the patched
    3.8.20 tree with a one-member archive named
    '../escaped.evil/../dest/sub/file' extracted into outerdir/dest: before
    the fix outerdir/escaped.evil is created under both filter='data' and
    filter='tar'; after it nothing is created outside the destination and
    dest/sub/file still holds its content. POSIX only.
    - debian/patches/CVE-2026-19672.patch: backport of cpython
      97688346ada2df3e5b9c279348862c3d64ab0823 (gh-155999, GH-156000), which
      normalizes a member name containing a '..' component before the
      containment check so the directories actually created match the path
      that was validated, plus its regression test
      test_parent_dir_out_and_back in Lib/test/test_tarfile.py. Applied after
      CVE-2026-87910.patch.
    - Behaviour change: under the 'tar' and 'data' filters a member name
      containing '..' is now normalized with os.path.normpath(), which removes
      internal '..' components and may change the meaning of the name if it
      traverses symbolic links.
    - CVE-2026-19672

 -- Juan Carlos Garcia <jgarcia@cloudlinux.com>  Tue, 22 Sep 2026 12:00:00 +0000

alt-python38 (3.8.20-29) stable; urgency=medium

  * SECURITY UPDATE: tarfile 'data'/'tar' extraction filter bypass via a hard
    link to a symbolic link (CWE-59, link following). TarFile.makelink_with_filter()
    passed tarinfo._link_target straight to os.link(); link(2) does not follow
    symbolic links, so an archive storing a hard link whose target is an
    archived symlink got the *same symlink inode* materialised one directory
    shallower than the symlink the filter had validated. Its relative body then
    re-based outside the destination directory, and the chmod()/utime() that
    extraction performs on the newly created name followed the link onto the
    outside file, changing its permissions and modification time; its contents
    also became readable through the in-tree path. Reproduced on the patched
    3.8.20 tree with a four-member archive ('x' regular decoy, 'sub/'
    directory, 'sub/link' -> '../x' symlink, 'escape' hard link to 'sub/link'
    with mode 0777 and mtime 946684800) extracted with filter='data': a file
    outside the destination went 0600 -> 0755, its mtime was rewritten to
    946684800 and its contents were readable through dest/escape. After the
    fix the outside file is untouched and dest/escape is a genuine in-tree hard
    link to the extracted decoy.
    - debian/patches/CVE-2026-82049.patch: backport of cpython
      b8f23e307097552eaea2604383a12ab280520d0d (gh-157190, GH-157191,
      GH-157192), which resolves the hard-link source with os.path.realpath()
      before calling os.link(), plus its regression test
      test_sneaky_hardlink_relocation in Lib/test/test_tarfile.py. This
      one-liner is sufficient only because CVE-2026-11940 is already applied:
      it closes the variant where the archive carries a decoy at the symlink's
      in-destination target so os.path.exists() is true and os.link() runs,
      while the no-decoy variant skips os.link() entirely and is closed by the
      guard CVE-2026-11940.patch added to makelink_with_filter(). The two must
      not be separated.
    - CVE-2026-82049

 -- Juan Carlos Garcia <jgarcia@cloudlinux.com>  Fri, 18 Sep 2026 12:00:00 +0000

alt-python38 (3.8.20-28) stable; urgency=medium

  * SECURITY UPDATE: CPU denial-of-service in csv.Sniffer. Two independent
    regexes in Sniffer._guess_quote_and_delimiter() ran in super-linear time
    on samples reachable from the public csv.Sniffer.sniff() API (CWE-1176,
    algorithmic complexity). The quoted-field probe matched a field body with
    a lazy ".*?" under re.DOTALL, so a closing quote not followed by a
    delimiter was retried against every later quote in the sample: quadratic.
    The doubled-quote probe dq_regexp was unanchored, rescanned leading
    whitespace and ran even when no delimiter had been found, which is
    exponential on a sample carrying a run of quote characters.
    - debian/patches/CVE-2026-18503.patch: backport of cpython 19e5024518
      (gh-109638, GH-154868) and fd78b565 (gh-98820, GH-154867), both in
      their upstream 3.10-branch form. Both commits are part of Python
      3.10.21, the release the CVE record names as fixing the "0 to <
      3.10.21" range, and gh-98820 alone leaves the doubled-quote probe
      exponential: with it applied on its own, sniff() on
      '"",'*100 + '"'*100 + '0' + '"'*100 + '0', on '"a"\n' + ' '*100000
      with delimiters=',;', and on '"a" "b"\n' + ' '*100000 each still runs
      unbounded inside a single C-level re call. Field bodies are now matched
      by unrolled, unambiguous loops that cannot backtrack, the doubled-quote
      probe is anchored on whole fields and skipped when no delimiter was
      found, and sniff() normalises CRLF and CR to LF first so the probe's
      "$" means end of record. The 3.10 commits are used rather than the
      3.11+ ones, which express the same fix with a possessive quantifier
      that Python 3.8's re module does not support.
    - CVE-2026-18503

 -- Juan Carlos Garcia <jgarcia@cloudlinux.com>  Mon, 31 Aug 2026 12:15:00 +0000

alt-python38 (3.8.20-27) stable; urgency=medium

  * SECURITY UPDATE: the import machinery read legacy .pyc files through a
    plain file object rather than io.open_code().  FileLoader.get_data()
    special-cased only SourceLoader and ExtensionFileLoader, so a
    sourceless import never raised the "open_code" audit event and audit
    hooks could neither observe nor veto the file being read.
    - debian/patches/CVE-2026-2297.patch: backport of cpython
      a51b1b51 (gh-145506, 3.13 branch).  SourcelessFileLoader is added to
      the isinstance() check, so .pyc loads go through io.open_code() like
      every other import path.
    - CVE-2026-2297
  * SECURITY UPDATE: positional predicates in xml.etree.ElementPath
    rebuilt the parent's child list once for every candidate element, so
    an expression such as ".//tag[last()]" cost time quadratic in the
    number of matches and an attacker-supplied document could drive a CPU
    denial of service.
    - debian/patches/CVE-2026-6879.patch: backport of cpython
      2ffab083 (gh-152674).  The (parent, tag) sibling lookup is now
      memoised for the duration of the selection.
    - CVE-2026-6879
  * SECURITY UPDATE: base64.b64decode() and base64.urlsafe_b64decode()
    silently accepted the standard "+" and "/" characters even when an
    alternative alphabet was in use, reinterpreting them instead of
    rejecting them, so two different inputs could decode to the same
    bytes.
    - debian/patches/CVE-2025-12781.patch: backport of cpython
      9060b4ab (gh-125346).  Both functions now emit a DeprecationWarning
      in strict mode and a FutureWarning otherwise, and a malformed
      altchars raises ValueError instead of tripping an assertion that
      disappears under -O.  Decoded output is unchanged.
    - CVE-2025-12781

 -- Viktor Borzov <vborzov@cloudlinux.com>  Wed, 12 Aug 2026 06:07:58 -0400

alt-python38 (3.8.20-26) stable; urgency=medium

  * SECURITY UPDATE: tarfile.data_filter could be bypassed using crafted
    link entries, including symlinks with empty or directory-like names,
    to redirect later archive members outside the intended extraction
    directory, so tarfile.extractall() could write files outside the
    destination directory.
    - debian/patches/CVE-2026-7774.patch: backport of cpython c063191c
      (gh-149486, [3.10] branch).  data_filter now validates the
      normalised linkname that is actually written to disk, strips
      trailing separators from a symlink member's name before resolving
      its directory, and rejects link members that resolve to the
      destination directory itself.
    - CVE-2026-7774
  * debian/patches/CVE-2026-8328.patch: register the TestFtpcpSecurity
    test class in test_ftplib's test_main so regrtest actually runs it
    (fixes an omission in the original backport; no functional change
    to the CVE fix itself).

 -- Tamar Zerekidze <tzerekidze@cloudlinux.com>  Mon, 10 Aug 2026 02:45:25 -0400

alt-python38 (3.8.20-25) stable; urgency=medium

  * SECURITY UPDATE: unicodedata.normalize() used an O(n^2) insertion
    sort for canonical ordering of combining characters, so a crafted
    Unicode string with many combining characters in alternating
    canonical-combining-class order caused a CPU denial of service.
    - debian/patches/CVE-2026-3276.patch: backport of cpython
      991224b1 + 90748760 (gh-149079).  Canonical ordering now sorts
      each combining-character run in the Py_UCS4 output buffer with a
      hybrid insertion/counting sort (insertion sort below 20
      characters, counting sort from 20 up), reducing the worst case
      to O(n).
    - CVE-2026-3276

 -- Tamar Zerekidze <tzerekidze@cloudlinux.com>  Fri, 07 Aug 2026 04:33:40 -0400

alt-python38 (3.8.20-24) stable; urgency=medium

  * SECURITY UPDATE: the tarfile extraction filters ('data' and 'tar')
    could be bypassed by a crafted archive whose hardlink references a
    symlink stored at a deeper name than the hardlink itself.  The
    hardlink-extraction fallback validated the symlink at its archived
    location but recreated it at the hardlink's shallower path, so a
    relative target could escape the destination directory.  Incomplete
    fix of CVE-2025-4330.
    - debian/patches/CVE-2026-11940.patch: backport of cpython
      be13e86f (gh-151558, 3.11 branch).  makelink_with_filter now
      re-runs the filter on the member re-rooted at the link's own path
      before using the fallback, so an escaping target is rejected with
      LinkFallbackError.
    - CVE-2026-11940
  * SECURITY UPDATE: configparser wrote multi-line values containing
    carriage return characters without escaping them, so a value under
    attacker control could inject unexpected keys, values and sections
    into the written configuration file.
    - debian/patches/CVE-2026-0864.patch: backport of cpython
      5858e42c (gh-143927).  RawConfigParser.write() now normalizes all
      line endings (CR, CRLF and LF) to "\n\t".
    - CVE-2026-0864
  * SECURITY UPDATE: tarfile did not handle EOF in _Stream.seek() for
    files opened in streaming mode ("r|"), so a small forged archive
    whose member header declares a huge size made archive parsing loop
    once per declared block against an already-exhausted stream,
    causing a CPU denial of service.
    - debian/patches/CVE-2026-11972.patch: backport of cpython
      f50bf135 (gh-151981).  The block loop in _Stream.seek() now
      breaks when read() returns no data, so parsing fails fast with
      ReadError instead of spinning.
    - CVE-2026-11972

  * SECURITY UPDATE: TarFile.extract() did not pass the extraction filter
    down to _extract_one(), so on the single-member extract() path the
    hardlink/symlink extraction fallback recreated the link target without
    applying the filter: attacker-controlled mode, uid and gid were
    applied verbatim even with filter='data', and the
    CVE-2025-4330/CVE-2026-11940 fallback checks never ran there.
    - debian/patches/CVE-2026-4360.patch: backport of cpython 7ccdbaba
      (gh-151987, Petr Viktorin).  extract() now forwards filter_function
      to _extract_one().  Adapted to 3.8: fix hunk identical to upstream;
      the regression tests' parenthesized multi-item "with" blocks are
      rewritten as backslash-continued statements (3.8 syntax).
    - CVE-2026-4360

 -- Tamar Zerekidze <tzerekidze@cloudlinux.com>  Tue, 04 Aug 2026 10:25:55 -0400

alt-python38 (3.8.20-23) stable; urgency=medium

  * CVE-2026-15308: fix quadratic-complexity CPU denial-of-service in
    html.parser.HTMLParser incremental parsing. When an unterminated
    construct (tag or comment) spanned many feed() calls, the growing
    buffer was rescanned and concatenated on every call. New data is now
    accumulated in a list and only joined and parsed once enough has piled
    up; close() flushes any buffered data before the final parse.
    - debian/patches/CVE-2026-15308.patch: backport upstream
      bcf98ddbc40ec9b3ee87da0124a5660b19b7e606 (gh-153030 / gh-153031).

 -- Juan Carlos Garcia <jgarcia@cloudlinux.com>  Mon, 20 Jul 2026 12:00:00 +0200

alt-python38 (3.8.20-22) stable; urgency=medium

  * Fix build on Ubuntu 24.04 (noble): drop the libmpdec-dev build
    dependency there (it was removed from noble) and fall back to the
    bundled _decimal, matching the existing Debian >= 11 handling.
    - buildsys-pre-build: unset the MPDEC flag for Ubuntu >= 24 as well as
      Debian >= 11; bionic/jammy still use system libmpdec.

  * Skip the expat reparse-deferral tests on Ubuntu 22.04 (jammy): its
    system expat carries the 2.6 reparse-deferral backport but still
    reports an older version, so the version-gated test_xml_etree tests
    (test_flush_reparse_deferral_disabled, test_simple_xml_chunk_1/_5) fail.
    - buildsys-pre-build: set the XMLREPARSE flag for Ubuntu 22.04.
    - debian/rules: under XMLREPARSE, apply 06002 and 06004 (the same test
      removals already applied in the RPM/Alpine builds). bionic/noble are
      unaffected.

 -- Lizi Ekseulidze <lekseulidze@cloudlinux.com>  Thu, 09 Jul 2026 11:18:18 +0400

alt-python38 (3.8.20-21) stable; urgency=medium

  * SECURITY UPDATE: bz2.BZ2Decompressor could write out of bounds (stack
    buffer overflow, CWE-121) when reused after a decompression error.
    Re-entering BZ2_bzDecompress() on a stream that libbz2 had already
    reported an error on left the internal state inconsistent.
    - debian/patches/CVE-2026-9669.patch: backport of cpython
      5755d0f083949ff3c5bf3a37e673e24e306b036e (gh-150599). Records the
      libbz2 error in a new bzerror field and marks the decompressor
      unusable, so a subsequent decompress() raises ValueError instead of
      re-entering the corrupted stream.
    - CVE-2026-9669

 -- Juan Carlos Garcia <jgarcia@cloudlinux.com>  Mon, 23 Jun 2026 12:00:00 +0200

alt-python38 (3.8.20-20) stable; urgency=medium

  * SECURITY UPDATE: imaplib.IMAP4._command() concatenated each argument
    into the wire command without validation, so an argument embedding
    CR/LF (or any other C0 control / DEL byte) could inject a second IMAP
    command.
    - debian/patches/CVE-2025-15366.patch: backport of cpython
      6262704b13 (gh-143921). Adds the _control_chars [\x00-\x1F\x7F]
      regex and raises ValueError in _command() before appending an
      offending argument.
    - CVE-2025-15366

  * SECURITY UPDATE: poplib.POP3._putcmd() wrote its argument to the POP3
    socket without validation, allowing the same CR/LF command-injection
    via the POP3 command API.
    - debian/patches/CVE-2025-15367.patch: backport of cpython
      b234a2b675 (gh-143923). Rejects lines matching [\x00-\x1F\x7F] with
      ValueError in _putcmd() before they are written.
    - CVE-2025-15367

 -- Juan Carlos Garcia <jgarcia@cloudlinux.com>  Mon, 08 Jun 2026 12:00:00 +0200

alt-python38 (3.8.20-19) stable; urgency=medium

  * SECURITY UPDATE: zipfile did not validate the ZIP64 End-of-Central-
    Directory Locator relative-offset, assuming the EOCD64 record sat
    immediately before the locator, allowing ambiguous-parsing ZIP
    archives (parser confusion vs. other ZIP tools).
    - debian/patches/CVE-2025-8291.patch: backport of cpython
      d11e69d620 (gh-139700, PSF-2025-12). Validates the locator offset
      and raises BadZipFile when it disagrees.
    - CVE-2025-8291

  * SECURITY UPDATE: tarfile applied the V7 AREGTYPE -> DIRTYPE
    normalization in frombuf() even when the header was a sub-block of
    a multi-block GNUTYPE_LONGNAME/LONGLINK member, causing parser
    confusion.
    - debian/patches/CVE-2025-13462.patch: backport of cpython
      42d754e34c (gh-141707). Skips the normalization on continuation
      blocks (dircheck=False on follow-up headers in _proc_gnulong and
      _proc_pax).
    - CVE-2025-13462

  * SECURITY UPDATE: wsgiref.headers.Headers did not reject control
    characters in header names/values, allowing HTTP header injection.
    - debian/patches/CVE-2026-0865.patch: backport of cpython
      22e4d55285 (gh-143916, initial reject of [\x00-\x1F\x7F] in
      _convert_string_type) plus follow-up 83ecd18779 (gh-144762,
      relax to allow HTAB \x09 in header values per RFC 9110). The
      merged patch splits the regex into _name_disallowed_re and
      _value_disallowed_re and threads a `name` keyword through
      _convert_string_type call sites.
    - CVE-2026-0865

  * SECURITY UPDATE: http.client.HTTPConnection did not sanitize CR/LF
    in the proxy CONNECT tunnel host or in set_tunnel() headers,
    enabling request/header splitting.
    - debian/patches/CVE-2026-1502.patch: backport of cpython
      b1cf901633 (gh-146211). Applies _is_legal_header_name/
      _is_illegal_header_value and control-char checks in
      _tunnel()/set_tunnel().
    - CVE-2026-1502

  * SECURITY UPDATE: http.cookies.Morsel.js_output() emitted the cookie
    value inside <script> ... </script> only escaping `"`, so a value
    containing </script> could break out of the script element (XSS).
    - debian/patches/CVE-2026-6019.patch: backport of cpython
      76b3923d68 (gh-90309). Base64-encodes the embedded cookie value;
      composes with the existing CVE-2026-3644 patch on the same
      function.
    - CVE-2026-6019

  * SECURITY UPDATE: ftplib.ftpcp() called parse227() directly and
    passed the attacker-controllable PASV host/port to target.sendport()
    (SSRF). The CVE-2021-4189 PASV fix had been applied to makepasv()
    but not ftpcp().
    - debian/patches/CVE-2026-8328.patch: backport of cpython
      eac4fe3b2c (gh-87451). Mirrors the getpeername() /
      trust_server_pasv_ipv4_address logic in ftpcp().
    - CVE-2026-8328

 -- Juan Carlos Garcia <jgarcia@cloudlinux.com>  Thu, 28 May 2026 16:00:00 +0200

alt-python38 (3.8.20-18) stable; urgency=medium

  * SECURITY UPDATE: urllib.parse.urlsplit()/urlparse() did not validate
    that bracketed [...] hosts were valid IPv6 or IPvFuture, enabling
    SSRF-relevant differential parsing.
    - debian/patches/CVE-2024-11168.patch: backport of cpython
      29f348e232 (gh-103848, John James Utley). Adds _check_bracketed_host()
      and calls it from urlsplit(); also backports ipaddress.IPv6Address
      scope-id support (_split_scope_id) needed by the new check.
    - CVE-2024-11168

  * SECURITY UPDATE: follow-up to CVE-2024-11168; urlsplit()/urlparse()
    still accepted square brackets in non-IPv6 hostnames, enabling
    differential parsing across URL parsers.
    - debian/patches/CVE-2025-0938.patch: backport of cpython
      d89a5f6a6e (gh-105704, Seth Larson). Adds _check_bracketed_netloc()
      to reject brackets that don't enclose a valid IPv6/IPvFuture host.
    - CVE-2025-0938

  * SECURITY UPDATE: email._header_value_parser folded address-list
    separator commas through encoded-word, so the separating comma could
    be unicode-encoded and misinterpreted by mail servers.
    - debian/patches/CVE-2025-1795.patch: backport of cpython
      09fab93c3d (gh-100884) plus the bundled regression follow-up
      858b9e85fc (gh-118643) which fixes the AttributeError that
      gh-100884 introduced when re-folding long address lists. Sets
      ListSeparator.as_ew_allowed to False and routes the list-
      separator token through the named constant.
    - CVE-2025-1795

  * SECURITY UPDATE: when folding a long email-header comment composed
    of unfoldable characters, email._header_value_parser dropped the
    enclosing parenthesis (and could omit the required leading space),
    enabling header injection.
    - debian/patches/CVE-2025-11468.patch: backport of cpython
      61614a5e50 (gh-143935). Adds make_parenthesis_pairs() and a
      comment-folding branch in _refold_parse_tree() that re-emits
      parentheses around comment subparts.
    - CVE-2025-11468

  * SECURITY UPDATE: use-after-free in the unicode-escape decoder when
    an error handler ('ignore'/'replace') was used.
    - debian/patches/CVE-2025-4516.patch: backport of cpython
      0d5d68f707 (gh-133767, Serhiy Storchaka). Replaces the buffer
      pointer with an integer (first_invalid_escape_char) plus a
      starts==initial_starts guard; adds binary-compat wrappers
      _PyBytes_DecodeEscape2 and _PyUnicode_DecodeUnicodeEscapeInternal2.
    - CVE-2025-4516

  * SECURITY UPDATE: html.parser.HTMLParser had worst-case quadratic
    complexity on crafted malformed input (e.g. unterminated tags or
    comments at EOF), enabling amplified DoS.
    - debian/patches/CVE-2025-6069.patch: backport of cpython
      8d1b3dfa09 (gh-135462). Replaces the EOF-handling branch with
      starttagopen.match/endtagopen.match/bogus-comment handling.
    - CVE-2025-6069

 -- Juan Carlos Garcia <jgarcia@cloudlinux.com>  Thu, 28 May 2026 14:00:00 +0200

alt-python38 (3.8.20-17) stable; urgency=medium

  * SECURITY UPDATE: xml.parsers.expat and xml.etree.ElementTree used
    insufficient entropy for the Expat hash-flooding salt (only the
    8-byte Py_hash_t field _Py_HashSecret.expat.hashsalt was passed
    to XML_SetHashSalt), allowing a crafted XML document to trigger
    hash flooding in Expat's internal hash tables. Full mitigation
    requires libexpat 2.8.0+ at runtime (or a distro-backported
    equivalent that exports XML_SetHashSalt16Bytes).
    - debian/patches/CVE-2026-7210.patch: backport of cpython
      24b8f12544 (gh-149018, Stan Ulbrych). Adds a 16-byte
      hashsalt16 field to _Py_HashSecret.expat and prefers the new
      XML_SetHashSalt16Bytes API in both Modules/pyexpat.c
      (newxmlparseobject + capi export) and Modules/_elementtree.c
      (XMLParser.__init__); the legacy XML_SetHashSalt path is kept
      as fallback when the loaded libexpat does not export the new
      symbol. The symbol is declared __attribute__((weak)) in
      Modules/pyexpat.c so the same source path works whether the
      build links against bundled libexpat 2.8.0+ or a distro
      libexpat 2.5/2.7 that backports the entropy fix without
      bumping XML_COMBINED_VERSION (Debian, Ubuntu, RHEL/CL,
      Alpine).
    - CVE-2026-7210

 -- Juan Carlos Garcia <jgarcia@cloudlinux.com>  Thu, 28 May 2026 11:18:00 +0200

alt-python38 (3.8.20-16) stable; urgency=medium

  * SECURITY UPDATE: urllib.request.DataHandler accepted data: URLs whose
    mediatype contained control characters, allowing newline-based HTTP
    header injection downstream.
    - debian/patches/CVE-2025-15282.patch: backport of cpython
      f25509e78e (gh-143925, Seth Larson). Adds a [\\x00-\\x1F\\x7F]
      regex check in data_open() and a matching test_invalid_mediatype.
    - CVE-2025-15282

  * SECURITY UPDATE: http.cookies.Morsel did not reject control characters
    in keys / values / coded_value, allowing cookie injection via
    __setitem__, setdefault, set, and BaseCookie.output.
    - debian/patches/CVE-2026-0672.patch: backport of cpython
      95746b3a13 (gh-143919, Seth Larson). Adds _has_control_character
      helper and inserts validation in __setitem__, setdefault, set,
      plus a wrap of BaseCookie.OutputString / output.
    - CVE-2026-0672

  * SECURITY UPDATE: the CVE-2026-0672 fix was incomplete; control
    characters could still bypass via Morsel.update(), |=, __setstate__
    (pickle), and BaseCookie.js_output().
    - debian/patches/CVE-2026-3644.patch: backport of cpython
      57e88c1cf9 (gh-145599, Stan Ulbrych + Victor Stinner). Adds
      validation to Morsel.update(), defines explicit Morsel.__ior__
      (was inherited from dict and bypassed validation), validates
      __setstate__ before assigning attributes, and re-validates the
      assembled output string in js_output().
    - CVE-2026-3644

  * SECURITY UPDATE: Modules/pyexpat.c conv_content_model could overflow
    the C stack when an Expat parser with a registered ElementDeclHandler
    parsed a deeply nested DTD content model, causing a denial-of-service.
    - debian/patches/CVE-2026-4224.patch: backport of cpython
      eb0e8be3a7 (gh-145986, Stan Ulbrych + Bénédikt Tran). Wraps
      conv_content_model with Py_EnterRecursiveCall / Py_LeaveRecursiveCall
      so deep nesting raises RecursionError instead of crashing.
    - CVE-2026-4224

 -- Juan Carlos Garcia <jgarcia@cloudlinux.com>  Mon, 11 May 2026 10:00:00 +0200

alt-python38 (3.8.20-15) stable; urgency=medium

  * SECURITY UPDATE: binascii.a2b_base64 / base64.b64decode stop decoding
    after the first padded quad, silently dropping any excess data. The
    behaviour can lead to data being accepted that other implementations
    process differently.
    - debian/patches/CVE-2026-3446.patch: backport of upstream commits
      4561f6418a (main), e31c55121620 (3.14), 1f9958f909c1 (3.13). Treats
      the pad character as non-alphabet data per RFC 4648 section 3.3:
      the loop in binascii_a2b_base64_impl no longer breaks out on a pad
      sequence; a `pads` counter is added so post-loop validation still
      raises "Incorrect padding" / "Invalid base64-encoded string" for
      inputs that do not satisfy `quad_pos + pads == 4`. The unused
      `binascii_find_valid` helper is removed.
    - CVE-2026-3446

 -- Juan Carlos Garcia <jgarcia@cloudlinux.com>  Mon, 04 May 2026 09:30:00 +0200

alt-python38 (3.8.20-14) stable; urgency=medium

  * SECURITY UPDATE: email.generator.BytesGenerator does not validate folded
    headers, allowing header injection via crafted Header subclasses
    - debian/patches/CVE-2026-1299.patch: extend verify_generated_headers
      check to BytesGenerator._write_headers() in Lib/email/generator.py
      so unsafely folded or delimited headers raise HeaderWriteError on
      as_bytes() too. Adds matching test coverage in
      Lib/test/test_email/test_generator.py and test_policy.py.
    - CVE-2026-1299

 -- Juan Carlos Garcia <jgarcia@cloudlinux.com>  Wed, 29 Apr 2026 09:30:00 +0200

alt-python38 (3.8.20-13) stable; urgency=medium

  * SECURITY UPDATE: use-after-free in lzma/bz2/gzip decompressors
    - debian/patches/CVE-2026-6100.patch: null next_in at the error:
      label of decompress() in Modules/_bz2module.c and
      Modules/_lzmamodule.c so the decompressor cannot be re-used
      with a stale buffer pointer after a MemoryError.
    - CVE-2026-6100

 -- Juan Carlos Garcia <jgarcia@cloudlinux.com>  Mon, 27 Apr 2026 12:00:00 +0200

alt-python38 (3.8.20-12) stable; urgency=medium

  * SECURITY UPDATE: webbrowser.open() allows command-line option injection
    via URLs with leading dashes
    - debian/patches/CVE-2026-4519.patch: reject leading dashes in
      webbrowser.open() URLs to prevent command-line option injection in
      browser subprocesses
    - CVE-2026-4519

 -- Juan Carlos Garcia <jgarcia@cloudlinux.com>  Tue, 14 Apr 2026 12:20:00 +0200

alt-python38 (3.8.20-11) stable; urgency=medium

  * SECURITY UPDATE: defect in 'tarfile' module leads to infinite loop and
    deadlock in parsing of maliciously crafted tar archives
    - debian/patches/CVE-2025-8194.patch: Validate archives to ensure member
      offsets are non-negative
    - CVE-2025-8194

 -- Juan Carlos García <jgarcia@cloudlinux.com>  Fri, 27 Feb 2026 10:38:00 +0100

alt-python38 (3.8.20-10) stable; urgency=medium

  * SECURITY UPDATE: Quadratic complexity in os.path.expandvars()
    - debian/patches/CVE-2025-6075.patch: fix quadratic complexity in
      os.path.expandvars() by replacing the character-by-character loop
      with regex-based substitution in both posixpath and ntpath modules.
    - CVE-2025-6075

 -- Juan Carlos García <jgarcia@cloudlinux.com>  Thu, 26 Feb 2026 14:51:00 +0100

alt-python38 (3.8.20-9) stable; urgency=medium

  * ALTPYTH-586: Initial build for arm64

 -- Levon Matshkalyan <lmatshkalyan@corp.cloudlinux.com>  Thu, 26 Feb 2026 17:00:00 +0400

alt-python38 (3.8.20-8) stable; urgency=medium

  * SECURITY UPDATE: Traversing outside chmod directory
    - debian/patches/CVE-2024-12718-CVE-2025-4138-CVE-2025-4330-CVE
      -2025-4435-CVE-2025-4517.patch: re-filters directory members
      before chmod/chown
    - CVE-2024-12718
  * SECURITY UPDATE: Symlink exfiltration
    - debian/patches/CVE-2024-12718-CVE-2025-4138-CVE-2025-4330-CVE
      -2025-4435-CVE-2025-4517.patch: properly handles different link
      semantics
    - CVE-2025-4138
  * SECURITY UPDATE: Hardlink Fallback Attack
    - debian/patches/CVE-2024-12718-CVE-2025-4138-CVE-2025-4330-CVE
      -2025-4435-CVE-2025-4517.patch: re-filter the source if hardlink
      extraction falls back to copying
    - CVE-2025-4330
  * SECURITY UPDATE: Errorlevel=0 Extracts Rejected Members
    - debian/patches/CVE-2024-12718-CVE-2025-4138-CVE-2025-4330-CVE
      -2025-4435-CVE-2025-4517.patch: account errorlevel
    - CVE-2025-4435
  * SECURITY UPDATE: PATH_MAX Attack
    - debian/patches/CVE-2024-12718-CVE-2025-4138-CVE-2025-4330-CVE
      -2025-4435-CVE-2025-4517.patch: prevents PATH_MAX overflow
      attacks
    - CVE-2025-4517

 -- Juan Carlos García <jgarcia@cloudlinux.com>  Tue, 17 Feb 2026 11:21:00 +0100

alt-python38 (3.8.20-7) stable; urgency=medium

  * SECURITY UPDATE: Memory denial of service in plistlib
    - debian/patches/CVE-2025-13837.patch: read large data by chunks,
      therefore the upper limit of consumed memory is proportional to the
      size of the input file.
    - CVE-2025-13837

 -- Juan Carlos García <jgarcia@cloudlinux.com>  Thu, 12 Feb 2026 08:04:42 +0100

alt-python38 (3.8.20-6) stable; urgency=medium

  * ALTNJS-243: Add ARM64 build support for Debian 12 and Debian 13

 -- Levon Matshkalyan <lmatshkalyan@corp.cloudlinux.com>  Mon, 09 Feb 2026 19:00:00 +0400

alt-python38 (3.8.20-5) stable; urgency=medium

  * SECURITY UPDATE: Potential denial of service in http.client
    - debian/patches/CVE-2025-13836.patch: Read large data by
      chunks instead of allocating memory based on Content-Length
    - CVE-2025-13836
  * SECURITY UPDATE: Quadratic complexity in xml.minidom node ID cache
    clearing
    - debian/patches/CVE-2025-12084.patch: Remove quadratic behavior in
      xml.minidom node ID cache clearing
    - CVE-2025-12084

 -- Juan Carlos García <jgarcia@cloudlinux.com>  Mon, 12 Jan 2026 12:54:00 +0100

alt-python38 (3.8.20-4) stable; urgency=medium

  * SECURITY UPDATE: Command injection vulnerability in venv module activation
    scripts when virtual environment paths contain special shell characters
    - debian/patches/CVE-2024-9287.patch: Properly quote template
      strings in venv activation scripts

 -- Azat Nurgaliev <anurgaliev@cloudlinux.com>  Thu, 18 Nov 2025 10:22:00 +0200

alt-python38 (3.8.20-3) stable; urgency=medium

  * ALTPYTH-575: Build alt-python38 for Debian12/13

 -- Eduard Chiganov <echiganov@cloudlinux.com>  Thu, 13 Nov 2025 14:20:00 +0200

alt-python38 (3.8.20-1) stable; urgency=medium

  * Update to 3.8.20 version

 -- CloudLinux Packaging Team <packager@cloudlinux.com>  Sat, 07 Sep 2024 00:23:25 +0000

alt-python38 (3.8.19-3) stable; urgency=medium

  * ALTPYTH-518: Resolve conflicts with idle3.appdata.xml with other alt-pythonXX-idle packages

 -- Ilya Voyskovsky <ivoyskovsky@cloudlinux.com>  Thu, 25 Jul 2024 17:03:00 +0200  

alt-python38 (3.8.19-2) stable; urgency=medium

  * ALTPYTH-509: Always use alt-sqlite

 -- Ilya Voyskovsky <ivoyskovsky@cloudlinux.com>  Wed, 10 Apr 2024 15:05:00 +0200  

alt-python38 (3.8.19-1) stable; urgency=medium

  * ALTPYTH-511: Update to 3.8.19 version

 -- CloudLinux Packaging Team <packager@cloudlinux.com>  Tue, 19 Mar 2024 18:23:21 +0000

alt-python38 (3.8.18-1) stable; urgency=medium

  * ALTPYTH-476: Build missing alt-python packages for CL ubuntu.
  * ALTPYTH-485: Updated to 3.8.17
  * ALTPYTH-483: Updated to 3.8.18

 -- Eduard Chiganov <echiganov@cloudlinux.com>  Mon, 21 Aug 2023 14:20:00 +0200

alt-python38 (3.8.16-1) stable; urgency=medium

  * Updated to 3.8.16

 -- Ilya Voyskovsky <ivoyskovsky@cloudlinux.com>  Mon, 30 Jan 2023 11:48:00 +0200

alt-python38 (3.8.15-1) stable; urgency=medium

  * Updated to 3.8.15

 -- Ilya Voyskovsky <ivoyskovsky@cloudlinux.com>  Mon, 24 Oct 2022 11:48:00 +0200

alt-python38 (3.8.13-1) stable; urgency=medium

  * ALTPYTH-438: Updated to 3.8.13, build fixes for bootstrap variant

 -- Ilya Voyskovsky <ivoyskovsky@cloudlinux.com>  Fri, 15 Apr 2022 18:48:00 +0200

alt-python38 (3.8.12-2) stable; urgency=medium

  * ALTPYTH-413: move -fno-semantic-interposition to CFLAGS_NODIST

 -- Sergey Fokin <sfokin@cloudlinux.com>  Fri, 15 Apr 2022 18:48:00 +0200

alt-python38 (3.8.12-1) stable; urgency=medium

  * ALTPYTH-401: update to 3.8.12

 -- Sergey Fokin <sfokin@cloudlinux.com>  Wed, 02 Feb 2022 10:57:00 +0300

alt-python38 (3.8.6-9) stable; urgency=medium

  * ALTPYTH-358: Enable -fno-semantic-interposition flag

 -- Eduard Abdullin <eabdullin@cloudlinux.com>  Fri, 03 Sep 2021 13:55:56 +0300

alt-python38 (3.8.6-5) stable; urgency=medium

  * Fix site-packages and dist-packages

 -- Ivan Danilov <idanilov@cloudlinux.com>  Tue, 02 Feb 2021 22:22:22 +0300

alt-python38 (3.8.6-4) stable; urgency=medium

  * Fix permissions for base64.py

 -- Ivan Danilov <idanilov@cloudlinux.com>  Tue, 02 Feb 2021 22:22:22 +0300

alt-python38 (3.8.6-3) stable; urgency=medium

  * ALTPYTH-295: Build against alt-sqlite

 -- Ivan Danilov <idanilov@cloudlinux.com>  Tue, 26 Jan 2021 22:22:22 +0300

alt-python38 (3.8.6-2) stable; urgency=medium

  * ALTPYTH-321: Fix installation path

 -- Ivan Danilov <idanilov@cloudlinux.com>  Fri, 11 Dec 2020 22:22:22 +0300

alt-python38 (3.8.6-1) stable; urgency=medium

  * ALTPYTH-293: Update python to 3.8.6 version

 -- Eduard Abdullin <eabdullin@cloudlinux.com>  Fri, 20 Nov 2020 11:18:32 +0300

alt-python38 (3.8.1-5) stable; urgency=medium

  * Change wheel default directory for ensurepip

 -- Ivan Danilov <idanilov@cloudlinux.com>  Tue, 17 Nov 2020 22:22:22 +0300

alt-python38 (3.8.1-3) stable; urgency=medium

  * fix pyconfig.h
  * fix path to dist-packages

 -- Anatholy Scryabin <ascryabin@cloudlinux.com>  Mon, 07 Sep 2020 17:57:34 +0300

alt-python38 (3.8.1-2) stable; urgency=medium

  * initial build

 -- Anatholy Scryabin <ascryabin@cloudlinux.com>  Thu, 23 Jun 2020 19:01:21 +0300
