Bug 1373939

Summary: SELinux policy breaks postfix when using TCP for large DNS responses
Product: Red Hat Enterprise Linux 7 Reporter: Paul Bolton <07533467-9032-4659-b65a-e01a40e42996>
Component: selinux-policyAssignee: Lukas Vrabec <lvrabec>
Status: CLOSED WONTFIX QA Contact: BaseOS QE Security Team <qe-baseos-security>
Severity: medium Docs Contact:
Priority: unspecified    
Version: 7.2CC: 07533467-9032-4659-b65a-e01a40e42996, aleksandrs, lvrabec, mgrepl, mmalik, plautrba, pvrabec, ssekidde
Target Milestone: rc   
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:

Description Paul Bolton 2016-09-07 13:18:53 UTC
Description of problem:
When Postfix is configured with pypolicyd-spf to validate the SPF records of incoming mail servers, if the DNS TXT response is too large for UDP it will fallback to TCP. However, the SELinux policy only allows binding to any (>1024) ephemeral port over UDP.

Version-Release number of selected component (if applicable):
CentOS 7.2.1511

How reproducible:
always

Steps to Reproduce:
1. Configure Postfix with pypolicyd-spf.
2. Send a mail to that server from a DNS domain with a large amount of TXT records (for example) redhat.com.

You will see the following error in /var/adm/maillog

Sep  7 10:03:22 tbhext01 policyd-spf[18409]: Temperror; identity=mailfrom; client-ip=209.132.183.28; helo=mx1.redhat.com; envelope-from=XXXXXX; receiver=XXXXXX

The received message may also contain:

Received-SPF: Temperror (SPF Temporary Error: DNS: TCP Fallback error: [Errno 13] Permission denied) identity=mailfrom; client-ip=209.132.183.28; helo=mx1.redhat.com; envelope-from=XXXXXX; receiver=XXXXXX

On searching the SELinux audit logs you will see:

$ sudo ausearch -m avc -ts 10:00:00
type=SYSCALL msg=audit(1473239002.074:56258): arch=c000003e syscall=49 success=no exit=-13 a0=4 a1=7ffd349f4280 a2=10 a3=0 items=0 ppid=18408 pid=18409 auid=4294967295 uid=99 gid=99 euid=99 suid=99 fsuid=99 egid=99 sgid=99 fsgid=99 tty=(none) ses=4294967295 comm="policyd-spf" exe="/usr/bin/python2.7" subj=system_u:system_r:postfix_master_t:s0 key=(null)
type=AVC msg=audit(1473239002.074:56258): avc:  denied  { name_bind } for  pid=18409 comm="policyd-spf" src=10060 scontext=system_u:system_r:postfix_master_t:s0 tcontext=system_u:object_r:unreserved_port_t:s0 tclass=tcp_socket

You can verify the DNS query is too large by running nslookup. e.g.

$ nslookup -query=txt redhat.com.
;; Truncated, retrying in TCP mode.
...

Actual results:
See above

Expected results:
SPF Pass and not TempFail.

Additional info:
To fix, the policy for postfix.pp needs to be updated thus:

*** policy/modules/contrib/postfix.te   2016-09-01 00:44:17.000000000 +0100
--- policy/modules/contrib/postfix.te.bug       2016-09-01 05:02:51.969208579 +0100
***************
*** 176,181 ****
--- 176,182 ----
  corenet_udp_sendrecv_all_ports(postfix_master_t)
  corenet_udp_bind_generic_node(postfix_master_t)
  corenet_udp_bind_all_unreserved_ports(postfix_master_t)
+ corenet_tcp_bind_all_unreserved_ports(postfix_master_t)
  corenet_dontaudit_udp_bind_all_ports(postfix_master_t)
  corenet_tcp_bind_generic_node(postfix_master_t)
  corenet_tcp_bind_amavisd_send_port(postfix_master_t)

The workaround is to compile a local policy thus:

-- snip --
policy_module(mypostfix, 0.1)
gen_require(`
        type postfix_master_t;
        ')

corenet_tcp_bind_all_unreserved_ports(postfix_master_t)
-- snip --

The workaround worked on the server which was experiencing this issue.

Comment 3 Lukas Vrabec 2016-09-12 09:08:29 UTC
Hi, 

Workround for this issue is following: 
# semanage port -a -t smtp_port_t -p tcp 10060

Command will label port 10060 as smtp_port_t and we have rule which allows postfix_master_t to bind on smtp_port_t.

$ sesearch -A -s postfix_master_t -p name_bind -c tcp_socket -C -t smtp_port_t
Found 1 semantic av rules:
   allow postfix_master_t smtp_port_t : tcp_socket name_bind ;

Comment 4 Paul Bolton 2016-09-12 09:15:37 UTC
(In reply to Lukas Vrabec from comment #3)
> Hi, 
> 
> Workround for this issue is following: 
> # semanage port -a -t smtp_port_t -p tcp 10060
> 
> Command will label port 10060 as smtp_port_t and we have rule which allows
> postfix_master_t to bind on smtp_port_t.

Lukas,

I do not believe the proposed workaround will work, a this will only work if the kernel always chooses the random ephemeral (client side) port of 10060/tcp; which it does not (by design).

Here are a few more example ports from the same issue:

type=AVC msg=audit(1472585184.855:43787): avc:  denied  { name_bind } for  pid=121409 comm="policyd-spf" src=7042 scontext=system_u:system_r:postfix_master_t:s0 tcontext=system_u:object_r:unreserved_port_t:s0 tclass=tcp_socket
type=AVC msg=audit(1473244452.916:56410): avc:  denied  { name_bind } for  pid=18724 comm="policyd-spf" src=5459 scontext=system_u:system_r:postfix_master_t:s0 tcontext=system_u:object_r:unreserved_port_t:s0 tclass=tcp_socket

> 
> $ sesearch -A -s postfix_master_t -p name_bind -c tcp_socket -C -t
> smtp_port_t
> Found 1 semantic av rules:
>    allow postfix_master_t smtp_port_t : tcp_socket name_bind ;

Comment 5 Aleksandrs Ļedovskis 2017-01-29 14:56:23 UTC
@Lukas, can you inform us regarding status of this bugfix? Is there anything extra (more info, providing patch, ?) community can do to speedup the progress?

Comment 7 Lukas Vrabec 2017-10-12 12:20:35 UTC
We're going to close this bug as WONTFIX because

 * of limited capacity of selinux-policy developers
 * the bug is related to EPEL component or 3rd party SW only
 * the bug appears in unsupported configuration 

We believe this bug can be fixed via a local policy module.
For more information please see: 

 * https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/selinux_users_and_administrators_guide/sect-security-enhanced_linux-troubleshooting-fixing_problems#sect-Security-Enhanced_Linux-Fixing_Problems-Allowing_Access_audit2allow

If you disagree, please re-open the bug.

Comment 8 Lukas Vrabec 2017-10-12 12:22:05 UTC
We're going to close this bug as WONTFIX because

 * of limited capacity of selinux-policy developers
 * the bug is related to EPEL component or 3rd party SW only
 * the bug appears in unsupported configuration 

We believe this bug can be fixed via a local policy module.
For more information please see: 

 * https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/selinux_users_and_administrators_guide/sect-security-enhanced_linux-troubleshooting-fixing_problems#sect-Security-Enhanced_Linux-Fixing_Problems-Allowing_Access_audit2allow

If you disagree, please re-open the bug.

Comment 9 Aleksandrs Ļedovskis 2017-10-17 08:31:38 UTC
Good news! The patch I have submitted to selinux-policy-contrib repository have been merged into rawhide branch (https://github.com/fedora-selinux/selinux-policy-contrib/commit/2f51ef1db4706bbf0dff30ff1590368b1439aa3c).

@Lukas, think this mandates change of this bug's status from "WONTFIX" to "FIXED"?