Bug 1482251
| Summary: | pydns source port selection does not use ephemeral range | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Product: | [Fedora] Fedora EPEL | Reporter: | exions <jbubeck> | ||||||||
| Component: | python-pydns | Assignee: | Paul Wouters <paul.wouters> | ||||||||
| Status: | CLOSED WONTFIX | QA Contact: | Fedora Extras Quality Assurance <extras-qa> | ||||||||
| Severity: | medium | Docs Contact: | |||||||||
| Priority: | unspecified | ||||||||||
| Version: | epel7 | CC: | jbubeck, pwouters | ||||||||
| Target Milestone: | --- | ||||||||||
| Target Release: | --- | ||||||||||
| Hardware: | All | ||||||||||
| OS: | Linux | ||||||||||
| Whiteboard: | |||||||||||
| Fixed In Version: | Doc Type: | If docs needed, set a value | |||||||||
| Doc Text: | Story Points: | --- | |||||||||
| Clone Of: | Environment: | ||||||||||
| Last Closed: | 2023-07-06 19:06:05 UTC | Type: | Bug | ||||||||
| Regression: | --- | Mount Type: | --- | ||||||||
| Documentation: | --- | CRM: | |||||||||
| Verified Versions: | Category: | --- | |||||||||
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||||||
| Cloudforms Team: | --- | Target Upstream Version: | |||||||||
| Embargoed: | |||||||||||
| Attachments: |
|
||||||||||
Created attachment 1314404 [details]
Example TE policy
Created attachment 1314405 [details]
Example file context for policy
This package has changed maintainer in Fedora. Reassigning to the new maintainer of this component. This package is dead since fedora 31. Please use python3-dns or python3-unbound |
Created attachment 1314403 [details] Example script Description of problem: PyDNS randomly binds to TCP or UDP source ports from the range 1024-65535 as a defense against cache poisoning. Some ports in this range are defined as SELinux ports. Someone who is writing an SELinux policy to confine a python script that uses PyDNS will either have to: * Accept that ~1% of TCP queries will fail * Make the SELinux policy allow more than needed (i.e. corenet_tcp_bind_all_ports) Version-Release number of selected component (if applicable): 2.3.6-2.el7 How reproducible: Basic SELinux policy files and python script to demonstrate the issue are attached. Steps to Reproduce: 1. Build and install SELinux policy Place pydnstest.te and pydnstest.fc in ~/pydnstest/ $ cd ~/pydnstest $ make -f /usr/share/selinux/devel/Makefile # semodule -i ~/pydnstest/pydnstest.pp # semanage dontaudit off 2. Install script Place pydnstest.py in /usr/local/bin/ # restorecon /usr/local/bin/pydnstest.py 3. Run script $ runcon system_u:system_r:pydnstest_t:s0 /usr/local/bin/pydnstest.py Actual results: SELinux denials occur during approx. 1% of lookups. $ runcon system_u:system_r:pydnstest_t:s0 /usr/local/bin/pydnstest.py Lookup 107 failed: SocketError(error(13, 'Permission denied'),) Lookup 176 failed: SocketError(error(13, 'Permission denied'),) # ausearch -ts today 20:21 -i -m avc -su pydnstest_t | audit2allow #============= pydnstest_t ============== allow pydnstest_t i18n_input_port_t:tcp_socket name_bind; allow pydnstest_t munin_port_t:tcp_socket name_bind; In this case, ports 4949 and 9010 were among the 200 randomly selected source ports. Since they were already defined as SELinux ports (i18n_input_port_t and munin_port_t), it resulted in denials. Expected results: DNS lookups use source ports in the ephemeral range, avoiding conflicts with defined SELinux ports. Additional info: Changing source_port to 0 makes the kernel assign a random-looking port in the ephemeral range. Making this change resulted in no SELinux denials with the attached script/policy: --- /usr/lib/python2.7/site-packages/DNS/Base.py.orig 2017-05-18 16:17:50.000000000 +0000 +++ /usr/lib/python2.7/site-packages/DNS/Base.py 2017-08-16 20:30:05.717033232 +0000 @@ -181,7 +181,7 @@ "Pick random source port to avoid DNS cache poisoning attack." while True: try: - source_port = random.randint(1024,65535) + source_port = 0 self.s.bind(('', source_port)) break except socket.error, msg: This reduces the pool of random source ports from 64512 to 28232. This shouldn't matter for TCP, but will weaken this defense against DNS cache poisoning attacks for UDP queries.