Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

audit: normalize NETFILTER_PKT

Eliminate flipping in and out of message fields, dropping fields in the
process.

Sample raw message format IPv4 UDP:
type=NETFILTER_PKT msg=audit(1487874761.386:228): mark=0xae8a2732 saddr=127.0.0.1 daddr=127.0.0.1 proto=17^]
Sample raw message format IPv6 ICMP6:
type=NETFILTER_PKT msg=audit(1487874761.381:227): mark=0x223894b7 saddr=::1 daddr=::1 proto=58^]

Issue: https://github.com/linux-audit/audit-kernel/issues/11
Test case: https://github.com/linux-audit/audit-testsuite/issues/43

Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>

authored by

Richard Guy Briggs and committed by
Paul Moore
2173c519 0cb88b6f

+28 -98
+28 -98
net/netfilter/xt_AUDIT.c
··· 31 31 MODULE_ALIAS("ebt_AUDIT"); 32 32 MODULE_ALIAS("arpt_AUDIT"); 33 33 34 - static void audit_proto(struct audit_buffer *ab, struct sk_buff *skb, 35 - unsigned int proto, unsigned int offset) 36 - { 37 - switch (proto) { 38 - case IPPROTO_TCP: 39 - case IPPROTO_UDP: 40 - case IPPROTO_UDPLITE: { 41 - const __be16 *pptr; 42 - __be16 _ports[2]; 43 - 44 - pptr = skb_header_pointer(skb, offset, sizeof(_ports), _ports); 45 - if (pptr == NULL) { 46 - audit_log_format(ab, " truncated=1"); 47 - return; 48 - } 49 - 50 - audit_log_format(ab, " sport=%hu dport=%hu", 51 - ntohs(pptr[0]), ntohs(pptr[1])); 52 - } 53 - break; 54 - 55 - case IPPROTO_ICMP: 56 - case IPPROTO_ICMPV6: { 57 - const u8 *iptr; 58 - u8 _ih[2]; 59 - 60 - iptr = skb_header_pointer(skb, offset, sizeof(_ih), &_ih); 61 - if (iptr == NULL) { 62 - audit_log_format(ab, " truncated=1"); 63 - return; 64 - } 65 - 66 - audit_log_format(ab, " icmptype=%hhu icmpcode=%hhu", 67 - iptr[0], iptr[1]); 68 - 69 - } 70 - break; 71 - } 72 - } 73 - 74 - static void audit_ip4(struct audit_buffer *ab, struct sk_buff *skb) 34 + static bool audit_ip4(struct audit_buffer *ab, struct sk_buff *skb) 75 35 { 76 36 struct iphdr _iph; 77 37 const struct iphdr *ih; 78 38 79 39 ih = skb_header_pointer(skb, skb_network_offset(skb), sizeof(_iph), &_iph); 80 - if (!ih) { 81 - audit_log_format(ab, " truncated=1"); 82 - return; 83 - } 40 + if (!ih) 41 + return false; 84 42 85 - audit_log_format(ab, " saddr=%pI4 daddr=%pI4 ipid=%hu proto=%hhu", 86 - &ih->saddr, &ih->daddr, ntohs(ih->id), ih->protocol); 43 + audit_log_format(ab, " saddr=%pI4 daddr=%pI4 proto=%hhu", 44 + &ih->saddr, &ih->daddr, ih->protocol); 87 45 88 - if (ntohs(ih->frag_off) & IP_OFFSET) { 89 - audit_log_format(ab, " frag=1"); 90 - return; 91 - } 92 - 93 - audit_proto(ab, skb, ih->protocol, ih->ihl * 4); 46 + return true; 94 47 } 95 48 96 - static void audit_ip6(struct audit_buffer *ab, struct sk_buff *skb) 49 + static bool audit_ip6(struct audit_buffer *ab, struct sk_buff *skb) 97 50 { 98 51 struct ipv6hdr _ip6h; 99 52 const struct ipv6hdr *ih; 100 53 u8 nexthdr; 101 54 __be16 frag_off; 102 - int offset; 103 55 104 56 ih = skb_header_pointer(skb, skb_network_offset(skb), sizeof(_ip6h), &_ip6h); 105 - if (!ih) { 106 - audit_log_format(ab, " truncated=1"); 107 - return; 108 - } 57 + if (!ih) 58 + return false; 109 59 110 60 nexthdr = ih->nexthdr; 111 - offset = ipv6_skip_exthdr(skb, skb_network_offset(skb) + sizeof(_ip6h), 112 - &nexthdr, &frag_off); 61 + ipv6_skip_exthdr(skb, skb_network_offset(skb) + sizeof(_ip6h), &nexthdr, &frag_off); 113 62 114 63 audit_log_format(ab, " saddr=%pI6c daddr=%pI6c proto=%hhu", 115 64 &ih->saddr, &ih->daddr, nexthdr); 116 65 117 - if (offset) 118 - audit_proto(ab, skb, nexthdr, offset); 66 + return true; 119 67 } 120 68 121 69 static unsigned int 122 70 audit_tg(struct sk_buff *skb, const struct xt_action_param *par) 123 71 { 124 - const struct xt_audit_info *info = par->targinfo; 125 72 struct audit_buffer *ab; 73 + int fam = -1; 126 74 127 75 if (audit_enabled == 0) 128 76 goto errout; 129 - 130 77 ab = audit_log_start(NULL, GFP_ATOMIC, AUDIT_NETFILTER_PKT); 131 78 if (ab == NULL) 132 79 goto errout; 133 80 134 - audit_log_format(ab, "action=%hhu hook=%u len=%u inif=%s outif=%s", 135 - info->type, xt_hooknum(par), skb->len, 136 - xt_in(par) ? xt_inname(par) : "?", 137 - xt_out(par) ? xt_outname(par) : "?"); 138 - 139 - if (skb->mark) 140 - audit_log_format(ab, " mark=%#x", skb->mark); 141 - 142 - if (skb->dev && skb->dev->type == ARPHRD_ETHER) { 143 - audit_log_format(ab, " smac=%pM dmac=%pM macproto=0x%04x", 144 - eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest, 145 - ntohs(eth_hdr(skb)->h_proto)); 146 - 147 - if (xt_family(par) == NFPROTO_BRIDGE) { 148 - switch (eth_hdr(skb)->h_proto) { 149 - case htons(ETH_P_IP): 150 - audit_ip4(ab, skb); 151 - break; 152 - 153 - case htons(ETH_P_IPV6): 154 - audit_ip6(ab, skb); 155 - break; 156 - } 157 - } 158 - } 81 + audit_log_format(ab, "mark=%#x", skb->mark); 159 82 160 83 switch (xt_family(par)) { 161 - case NFPROTO_IPV4: 162 - audit_ip4(ab, skb); 84 + case NFPROTO_BRIDGE: 85 + switch (eth_hdr(skb)->h_proto) { 86 + case htons(ETH_P_IP): 87 + fam = audit_ip4(ab, skb) ? NFPROTO_IPV4 : -1; 88 + break; 89 + case htons(ETH_P_IPV6): 90 + fam = audit_ip6(ab, skb) ? NFPROTO_IPV6 : -1; 91 + break; 92 + } 163 93 break; 164 - 94 + case NFPROTO_IPV4: 95 + fam = audit_ip4(ab, skb) ? NFPROTO_IPV4 : -1; 96 + break; 165 97 case NFPROTO_IPV6: 166 - audit_ip6(ab, skb); 98 + fam = audit_ip6(ab, skb) ? NFPROTO_IPV6 : -1; 167 99 break; 168 100 } 169 101 170 - #ifdef CONFIG_NETWORK_SECMARK 171 - if (skb->secmark) 172 - audit_log_secctx(ab, skb->secmark); 173 - #endif 102 + if (fam == -1) 103 + audit_log_format(ab, " saddr=? daddr=? proto=-1"); 174 104 175 105 audit_log_end(ab); 176 106