Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python310 for openSUSE:Factory checked in at 2026-07-15 16:51:48 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python310 (Old) and /work/SRC/openSUSE:Factory/.python310.new.1991 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python310" Wed Jul 15 16:51:48 2026 rev:78 rq:1365820 version:3.10.20 Changes: -------- --- /work/SRC/openSUSE:Factory/python310/python310.changes 2026-04-28 12:02:39.145162129 +0200 +++ /work/SRC/openSUSE:Factory/.python310.new.1991/python310.changes 2026-07-15 17:08:52.289952650 +0200 @@ -1,0 +2,41 @@ +Tue Jul 14 15:35:47 UTC 2026 - Jiri Slaby <[email protected]> + +- Add test_UDPLITE_support.patch which improves testing for the + support of IPPROTO_UDPLITE, which could be not present although + header files are (bsc#1268375). + +------------------------------------------------------------------- +Sat Jul 4 10:25:43 UTC 2026 - Matej Cepl <[email protected]> + +- CVE-2026-7210: Use XML_SetHashSalt16Bytes in + pyexpat/_elementtree when possible (bsc#1264962, + gh#python/cpython#149018). + CVE-2026-7210-pyexpat-entropy-hash-flooding.patch + +------------------------------------------------------------------- +Thu Jul 2 22:49:04 UTC 2026 - Matej Cepl <[email protected]> + +- CVE-2026-8328: Make ftplib not trust the PASV response + (bsc#1265268) + CVE-2026-8328-ftplib-no-trust-PASV-resp.patch + +------------------------------------------------------------------- +Wed Jul 1 23:10:26 UTC 2026 - Matej Cepl <[email protected]> + +- CVE-2026-11940: fix the symlink escape via tarfile + hardlink-extraction fallback (bsc#1268977) + CVE-2026-11940-tarfile-escape.patch + +------------------------------------------------------------------- +Wed May 13 14:50:25 UTC 2026 - Matej Cepl <[email protected]> + +- Use the system-wide crypto-policies [bsc#1211301] + * Use the system default cipher list instead of hardcoded values + * Add the --with-ssl-default-suites=openssl configure option + +------------------------------------------------------------------- +Fri May 1 16:05:16 UTC 2026 - Matej Cepl <[email protected]> + +- Remove macros.python3. + +------------------------------------------------------------------- Old: ---- macros.python3 New: ---- CVE-2026-11940-tarfile-escape.patch CVE-2026-7210-pyexpat-entropy-hash-flooding.patch CVE-2026-8328-ftplib-no-trust-PASV-resp.patch test_UDPLITE_support.patch ----------(New B)---------- New: hardlink-extraction fallback (bsc#1268977) CVE-2026-11940-tarfile-escape.patch New: gh#python/cpython#149018). CVE-2026-7210-pyexpat-entropy-hash-flooding.patch New: (bsc#1265268) CVE-2026-8328-ftplib-no-trust-PASV-resp.patch New: - Add test_UDPLITE_support.patch which improves testing for the support of IPPROTO_UDPLITE, which could be not present although ----------(New E)---------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python310.spec ++++++ --- /var/tmp/diff_new_pack.w4eSmX/_old 2026-07-15 17:08:53.738001857 +0200 +++ /var/tmp/diff_new_pack.w4eSmX/_new 2026-07-15 17:08:53.738001857 +0200 @@ -117,7 +117,6 @@ Source1: https://www.python.org/ftp/python/%{folderversion}/%{tarname}.tar.xz.sigstore Source2: baselibs.conf Source3: README.SUSE -Source7: macros.python3 Source8: import_failed.py Source9: import_failed.map Source10: pre_checkin.sh @@ -245,9 +244,22 @@ # PATCH-FIX-UPSTREAM CVE-2026-6019-Morsel-js_output.patch bsc#1262654 [email protected] # Base64-encode cookie values embedded in JS Patch51: CVE-2026-6019-Morsel-js_output.patch +# PATCH-FIX-UPSTREAM CVE-2026-11940-tarfile-escape.patch bsc#1268977 [email protected] +# Fix symlink escape via tarfile hardlink-extraction fallback +Patch52: CVE-2026-11940-tarfile-escape.patch +# PATCH-FIX-UPSTREAM CVE-2026-8328-ftplib-no-trust-PASV-resp.patch bsc#1265268 [email protected] +# Make ftplib not trust the PASV response +Patch53: CVE-2026-8328-ftplib-no-trust-PASV-resp.patch +# PATCH-FIX-UPSTREAM CVE-2026-7210-pyexpat-entropy-hash-flooding.patch bsc#1264962 [email protected] +# Use XML_SetHashSalt16Bytes in pyexpat/_elementtree when possible +Patch54: CVE-2026-7210-pyexpat-entropy-hash-flooding.patch +# PATCH-FIX-OPENSUSE test_UDPLITE_support.patch bsc#1268375 [email protected] +# improve testing of the presence of IPPROTO_UDPLITE support +Patch55: test_UDPLITE_support.patch ### END OF PATCHES BuildRequires: autoconf-archive BuildRequires: automake +BuildRequires: crypto-policies-scripts BuildRequires: fdupes BuildRequires: gmp-devel BuildRequires: lzma-devel @@ -262,7 +274,6 @@ BuildRequires: pkgconfig(zlib) #!BuildIgnore: gdk-pixbuf-loader-rsvg %if 0%{?suse_version} >= 1550 && %{without base} -# The provider for python(abi) is in rpm-build-python # Skip for the base flavor: rpm-build-python requires python3-base, which # creates an unresolvable dependency loop when building python3xx-base itself. BuildRequires: rpm-build-python @@ -784,12 +795,6 @@ # Remove -IVendor/ from python-config boo#1231795 sed -i 's/-IVendor\///' %{buildroot}%{_bindir}/python%{python_abi}-config -# RPM macros -%if %{primary_interpreter} -mkdir -p %{buildroot}%{_rpmconfigdir}/macros.d/ -install -m 644 %{SOURCE7} %{buildroot}%{_rpmconfigdir}/macros.d/ # macros.python3 -%endif - # import_failed hooks FAILDIR=%{buildroot}/%{sitedir}/_import_failed mkdir $FAILDIR @@ -930,10 +935,6 @@ %{_mandir}/man1/python%{python_version}.1%{?ext_man} # license text, not a doc because the code can use it at run-time %{sitedir}/LICENSE.txt -# RPM macros -%if %{primary_interpreter} -%{_rpmconfigdir}/macros.d/macros.python3 -%endif # binary parts %dir %{sitedir}/lib-dynload %{dynlib array} ++++++ CVE-2026-11940-tarfile-escape.patch ++++++ >From 2b49ec93e99aa4fa298cfd48eafbdcf42eb66fa9 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <[email protected]> Date: Tue, 23 Jun 2026 14:31:38 +0100 Subject: [PATCH] gh-151558: Fix symlink escape via `tarfile` hardlink-extraction fallback (GH-151559) (cherry picked from commit 27dd970bf6b17ebca7c8ed486a40ab043ed7af8f) --- Lib/tarfile.py | 3 + Lib/test/test_tarfile.py | 23 ++++++++++ Misc/NEWS.d/next/Security/2026-06-10-13-08-19.gh-issue-151558.mL74i2.rst | 3 + 3 files changed, 29 insertions(+) create mode 100644 Misc/NEWS.d/next/Security/2026-06-10-13-08-19.gh-issue-151558.mL74i2.rst Index: Python-3.10.20/Lib/tarfile.py =================================================================== --- Python-3.10.20.orig/Lib/tarfile.py 2026-07-02 12:11:42.783228880 +0200 +++ Python-3.10.20/Lib/tarfile.py 2026-07-02 12:11:42.920540678 +0200 @@ -2660,6 +2660,9 @@ "makelink_with_filter: if filter_function is not None, " + "extraction_root must also not be None") try: + filter_function( + unfiltered.replace(name=tarinfo.name, deep=False), + extraction_root) filtered = filter_function(unfiltered, extraction_root) except _FILTER_ERRORS as cause: raise LinkFallbackError(tarinfo, unfiltered.name) from cause Index: Python-3.10.20/Lib/test/test_tarfile.py =================================================================== --- Python-3.10.20.orig/Lib/test/test_tarfile.py 2026-07-02 12:11:42.784824130 +0200 +++ Python-3.10.20/Lib/test/test_tarfile.py 2026-07-02 12:11:42.922049379 +0200 @@ -3908,6 +3908,29 @@ self.expect_file("boom", symlink_to='../../link_here') self.expect_file("c", symlink_to='b') + def test_sneaky_hardlink_fallback_deep(self): + # (CVE-2026-11940) + with ArchiveMaker() as arc: + arc.add("a/b/s", symlink_to=os.path.join("..", "escape")) + arc.add("s", hardlink_to=os.path.join("a", "b", "s")) + + with self.check_context(arc.open(), 'data'): + e = self.expect_exception( + tarfile.LinkFallbackError, + "link 's' would be extracted as a copy of " + + "'a/b/s', which was rejected") + self.assertIsInstance(e.__cause__, + tarfile.LinkOutsideDestinationError) + + for filter in 'tar', 'fully_trusted': + with self.subTest(filter), self.check_context(arc.open(), filter): + if not os_helper.can_symlink(): + self.expect_file("a/") + self.expect_file("a/b/") + else: + self.expect_file("a/b/s", symlink_to=os.path.join('..', 'escape')) + self.expect_file("s", symlink_to=os.path.join('..', 'escape')) + def test_exfiltration_via_symlink(self): # (CVE-2025-4138) # Test changing symlinks that result in a symlink pointing outside Index: Python-3.10.20/Misc/NEWS.d/next/Security/2026-06-10-13-08-19.gh-issue-151558.mL74i2.rst =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ Python-3.10.20/Misc/NEWS.d/next/Security/2026-06-10-13-08-19.gh-issue-151558.mL74i2.rst 2026-07-02 12:11:42.922567717 +0200 @@ -0,0 +1,3 @@ +Fixed an vulnerability in the :mod:`tarfile` ``data`` and ``tar`` extraction +filters where crafted archives could create a symlink pointing outside the +destination directory. This was a bypass of CVE-2025-4330. ++++++ CVE-2026-7210-pyexpat-entropy-hash-flooding.patch ++++++ >From 47c9d32583821997bb6bf11e6293a4e2d0d590c2 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <[email protected]> Date: Tue, 9 Jun 2026 15:07:36 +0100 Subject: [PATCH] [3.13] gh-149018: Use `XML_SetHashSalt16Bytes` in `pyexpat`/`_elementtree` when possible (GH-149023) (cherry picked from commit eeea765cb9d8f1fc3d8918b272ac3c477983f27a) Co-authored-by: Stan Ulbrych <[email protected]> (cherry picked from commit 24b8f12544468e4cedf5bfbe25442fcd495391e4) --- Include/pyexpat.h | 3 +++ Include/pyhash.h | 7 ++++--- Misc/NEWS.d/next/Security/2026-04-26-19-30-45.gh-issue-149018.a9SqWb.rst | 3 +++ Modules/_elementtree.c | 8 ++++++-- Modules/pyexpat.c | 10 +++++++++- 5 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Security/2026-04-26-19-30-45.gh-issue-149018.a9SqWb.rst Index: Python-3.10.20/Include/pyexpat.h =================================================================== --- Python-3.10.20.orig/Include/pyexpat.h 2026-03-03 01:49:35.000000000 +0100 +++ Python-3.10.20/Include/pyexpat.h 2026-07-07 23:42:58.087418557 +0200 @@ -57,6 +57,9 @@ XML_Parser parser, unsigned long long activationThresholdBytes); XML_Bool (*SetAllocTrackerMaximumAmplification)( XML_Parser parser, float maxAmplificationFactor); + /* might be NULL for expat < 2.8.0 */ + XML_Bool (*SetHashSalt16Bytes)( + XML_Parser parser, const uint8_t entropy[16]); /* always add new stuff to the end! */ }; Index: Python-3.10.20/Include/pyhash.h =================================================================== --- Python-3.10.20.orig/Include/pyhash.h 2026-03-03 01:49:35.000000000 +0100 +++ Python-3.10.20/Include/pyhash.h 2026-07-07 23:42:58.087713984 +0200 @@ -35,7 +35,7 @@ /* hash secret * * memory layout on 64 bit systems - * cccccccc cccccccc cccccccc uc -- unsigned char[24] + * cccccccc cccccccc cccccccc cccccccc cccccccc uc -- unsigned char[40] * pppppppp ssssssss ........ fnv -- two Py_hash_t * k0k0k0k0 k1k1k1k1 ........ siphash -- two uint64_t * ........ ........ ssssssss djbx33a -- 16 bytes padding + one Py_hash_t @@ -53,8 +53,8 @@ */ #ifndef Py_LIMITED_API typedef union { - /* ensure 24 bytes */ - unsigned char uc[24]; + /* ensure 40 bytes */ + unsigned char uc[40]; /* two Py_hash_t for FNV */ struct { Py_hash_t prefix; @@ -73,6 +73,7 @@ struct { unsigned char padding[16]; Py_hash_t hashsalt; + uint8_t hashsalt16[16]; } expat; } _Py_HashSecret_t; PyAPI_DATA(_Py_HashSecret_t) _Py_HashSecret; Index: Python-3.10.20/Misc/NEWS.d/next/Security/2026-04-26-19-30-45.gh-issue-149018.a9SqWb.rst =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ Python-3.10.20/Misc/NEWS.d/next/Security/2026-04-26-19-30-45.gh-issue-149018.a9SqWb.rst 2026-07-07 23:42:58.087903552 +0200 @@ -0,0 +1,3 @@ +Improved protection against XML hash-flooding attacks in +:mod:`xml.parsers.expat` and :mod:`xml.etree.ElementTree` when Python is +compiled with libExpat 2.8.0 or later. Index: Python-3.10.20/Modules/_elementtree.c =================================================================== --- Python-3.10.20.orig/Modules/_elementtree.c 2026-03-03 01:49:35.000000000 +0100 +++ Python-3.10.20/Modules/_elementtree.c 2026-07-07 23:42:58.088396401 +0200 @@ -3663,8 +3663,12 @@ PyErr_NoMemory(); return -1; } - /* expat < 2.1.0 has no XML_SetHashSalt() */ - if (EXPAT(SetHashSalt) != NULL) { + // Prefer 16-byte entropy, only expat >= 2.8.0. See gh-149018 + if (EXPAT(SetHashSalt16Bytes) != NULL) { + EXPAT(SetHashSalt16Bytes)(self->parser, + _Py_HashSecret.expat.hashsalt16); + } + else if (EXPAT(SetHashSalt) != NULL) { EXPAT(SetHashSalt)(self->parser, (unsigned long)_Py_HashSecret.expat.hashsalt); } Index: Python-3.10.20/Modules/pyexpat.c =================================================================== --- Python-3.10.20.orig/Modules/pyexpat.c 2026-07-07 23:42:57.926077481 +0200 +++ Python-3.10.20/Modules/pyexpat.c 2026-07-07 23:42:58.088983398 +0200 @@ -1379,7 +1379,10 @@ Py_DECREF(self); return NULL; } -#if XML_COMBINED_VERSION >= 20100 +#if XML_COMBINED_VERSION >= 20800 + /* This feature was added upstream in libexpat 2.8.0. */ + XML_SetHashSalt16Bytes(self->itself, _Py_HashSecret.expat.hashsalt16); +#elif XML_COMBINED_VERSION >= 20100 /* This feature was added upstream in libexpat 2.1.0. */ XML_SetHashSalt(self->itself, (unsigned long)_Py_HashSecret.expat.hashsalt); @@ -2187,6 +2190,11 @@ #else capi.SetHashSalt = NULL; #endif +#if XML_COMBINED_VERSION >= 20800 + capi.SetHashSalt16Bytes = XML_SetHashSalt16Bytes; +#else + capi.SetHashSalt16Bytes = NULL; +#endif #if XML_COMBINED_VERSION >= 20600 capi.SetReparseDeferralEnabled = XML_SetReparseDeferralEnabled; #else ++++++ CVE-2026-8328-ftplib-no-trust-PASV-resp.patch ++++++ >From 6b799df77c38b5d8907dc2a6be4092898874b61d Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" <[email protected]> Date: Wed, 13 May 2026 10:33:43 -0700 Subject: [PATCH] gh-87451: Apply CVE-2021-4189 PASV fix to ftplib.ftpcp() (GH-149648) ftpcp() called parse227() directly and passed the source server's self-reported PASV IPv4 address to the target server's PORT command, bypassing the CVE-2021-4189 fix that was applied only to FTP.makepasv(). A malicious source FTP server could use this to redirect the target server's data connection to an arbitrary host:port (SSRF). ftpcp() now uses the source server's actual peer address, honoring the existing trust_server_pasv_ipv4_address opt-out, the same as makepasv(). Thanks to Qi Ding at Aurascape AI for the report. (GHSA-w8c5-q2xf-gf7c) (cherry picked from commit eac4fe3b2c77693790a5ef7dfab127c1fee81bf9) Co-authored-by: Gregory P. Smith <[email protected]> --- Lib/ftplib.py | 11 ++- Lib/test/test_ftplib.py | 36 +++++++++- Misc/NEWS.d/next/Security/2026-05-10-18-05-32.gh-issue-87451.XkKB6M.rst | 6 + 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Security/2026-05-10-18-05-32.gh-issue-87451.XkKB6M.rst Index: Python-3.10.20/Lib/ftplib.py =================================================================== --- Python-3.10.20.orig/Lib/ftplib.py 2026-07-03 22:34:56.136433158 +0200 +++ Python-3.10.20/Lib/ftplib.py 2026-07-03 22:35:01.216140203 +0200 @@ -905,7 +905,16 @@ type = 'TYPE ' + type source.voidcmd(type) target.voidcmd(type) - sourcehost, sourceport = parse227(source.sendcmd('PASV')) + # Don't trust the IPv4 address the source server advertises in its PASV + # reply: a malicious source could otherwise point the target's data + # connection at an arbitrary host (SSRF). A caller that needs the old + # behavior can set trust_server_pasv_ipv4_address on the source FTP + # object. See FTP.makepasv(), which applies the same rule. + untrusted_host, sourceport = parse227(source.sendcmd('PASV')) + if source.trust_server_pasv_ipv4_address: + sourcehost = untrusted_host + else: + sourcehost = source.sock.getpeername()[0] target.sendport(sourcehost, sourceport) # RFC 959: the user must "listen" [...] BEFORE sending the # transfer request. Index: Python-3.10.20/Lib/test/test_ftplib.py =================================================================== --- Python-3.10.20.orig/Lib/test/test_ftplib.py 2026-07-03 22:34:57.755196505 +0200 +++ Python-3.10.20/Lib/test/test_ftplib.py 2026-07-03 22:35:01.216331633 +0200 @@ -16,7 +16,7 @@ except ImportError: ssl = None -from unittest import TestCase, skipUnless +from unittest import mock, TestCase, skipUnless from test import support from test.support import threading_helper from test.support import socket_helper @@ -1143,6 +1143,40 @@ ftp.close() +class TestFtpcpSecurity(TestCase): + """ftpcp() must not trust the host a source server advertises in PASV. + + A malicious source server can otherwise redirect the target server's + data connection to an arbitrary host:port (SSRF), so ftpcp() uses the + source server's actual peer address instead, the same as FTP.makepasv(). + """ + + def _make_pair(self, *, advertised_host, real_host, trust=False): + source = mock.Mock(spec=ftplib.FTP) + source.trust_server_pasv_ipv4_address = trust + source.sock.getpeername.return_value = (real_host, 21) + # PASV replies give the host as comma-separated octets, not dotted. + advertised = advertised_host.replace('.', ',') + source.sendcmd.side_effect = lambda cmd: ( + f'227 Entering Passive Mode ({advertised},1,2).' + if cmd == 'PASV' else '150 ok') + target = mock.Mock(spec=ftplib.FTP) + target.sendcmd.return_value = '150 ok' + return source, target + + def test_ftpcp_ignores_untrusted_pasv_host(self): + source, target = self._make_pair(advertised_host='10.0.0.5', + real_host='198.51.100.7') + ftplib.ftpcp(source, 'a', target, 'b') + target.sendport.assert_called_once_with('198.51.100.7', 258) + + def test_ftpcp_trust_server_pasv_ipv4_address(self): + source, target = self._make_pair(advertised_host='10.0.0.5', + real_host='198.51.100.7', trust=True) + ftplib.ftpcp(source, 'a', target, 'b') + target.sendport.assert_called_once_with('10.0.0.5', 258) + + class MiscTestCase(TestCase): def test__all__(self): not_exported = { Index: Python-3.10.20/Misc/NEWS.d/next/Security/2026-05-10-18-05-32.gh-issue-87451.XkKB6M.rst =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ Python-3.10.20/Misc/NEWS.d/next/Security/2026-05-10-18-05-32.gh-issue-87451.XkKB6M.rst 2026-07-03 22:35:01.216475064 +0200 @@ -0,0 +1,6 @@ +The :mod:`ftplib` module's undocumented ``ftpcp`` function no longer trusts +the IPv4 address value returned from the source server in response to the +``PASV`` command by default, completing the fix for CVE-2021-4189. As with +:class:`ftplib.FTP`, the former behavior can be re-enabled by setting the +``trust_server_pasv_ipv4_address`` attribute on the source :class:`ftplib.FTP` +instance to ``True``. Thanks to Qi Deng at Aurascape AI for the report. ++++++ _scmsync.obsinfo ++++++ --- /var/tmp/diff_new_pack.w4eSmX/_old 2026-07-15 17:08:53.930008382 +0200 +++ /var/tmp/diff_new_pack.w4eSmX/_new 2026-07-15 17:08:53.934008518 +0200 @@ -1,6 +1,6 @@ -mtime: 1777308455 -commit: 5bc50c307741eeac7952a643299f31439ef2a3409a0c17a4ba7aa80ba65df8be +mtime: 1784043422 +commit: e7fbc1cb0a65ff2836b5d55d60cef3c526783db3d670d0f5cf7a8a8876a0ef3b url: https://src.opensuse.org/python-interpreters/python310 -revision: 5bc50c307741eeac7952a643299f31439ef2a3409a0c17a4ba7aa80ba65df8be +revision: e7fbc1cb0a65ff2836b5d55d60cef3c526783db3d670d0f5cf7a8a8876a0ef3b projectscmsync: https://src.opensuse.org/python-interpreters/_ObsPrj ++++++ build.specials.obscpio ++++++ --- old/.gitignore 2026-04-27 18:47:35.000000000 +0200 +++ new/.gitignore 2026-07-14 17:37:02.000000000 +0200 @@ -4,4 +4,4 @@ _build.* .pbuild *.rej -python310-*-build/ +python310*-build/ ++++++ build.specials.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/.gitignore new/.gitignore --- old/.gitignore 1970-01-01 01:00:00.000000000 +0100 +++ new/.gitignore 2026-07-14 17:37:02.000000000 +0200 @@ -0,0 +1,7 @@ +.osc +*.obscpio +*.osc +_build.* +.pbuild +*.rej +python310*-build/ ++++++ test_UDPLITE_support.patch ++++++ --- Lib/test/test_socket.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) Index: Python-3.10.20/Lib/test/test_socket.py =================================================================== --- Python-3.10.20.orig/Lib/test/test_socket.py 2026-07-14 17:36:35.840165850 +0200 +++ Python-3.10.20/Lib/test/test_socket.py 2026-07-14 17:36:39.387859870 +0200 @@ -129,6 +129,22 @@ return (cid is not None) +def _have_socket_udplite(): + """Check whether UDPLITE sockets are supported on this host.""" + if not hasattr(socket, "IPPROTO_UDPLITE"): + return False + # Older Android versions block UDPLITE with SELinux. + if support.is_android and platform.android_ver().api_level < 29: + return False + try: + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDPLITE) + except (AttributeError, OSError): + return False + else: + s.close() + return True + + def _have_socket_bluetooth(): """Check whether AF_BLUETOOTH sockets are supported on this host.""" try: @@ -166,7 +182,7 @@ HAVE_SOCKET_VSOCK = _have_socket_vsock() -HAVE_SOCKET_UDPLITE = hasattr(socket, "IPPROTO_UDPLITE") +HAVE_SOCKET_UDPLITE = _have_socket_udplite() HAVE_SOCKET_BLUETOOTH = _have_socket_bluetooth()
