summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoriedowse <iedowse@FreeBSD.org>2002-12-27 17:43:25 +0000
committeriedowse <iedowse@FreeBSD.org>2002-12-27 17:43:25 +0000
commitf5462007056ca440dfe2c11ce75452bcdab12f57 (patch)
tree72e2f9fa523fd23d9944eaa63a3d75799d4d3c99
parentf6258ba488075f7a4561dbca1e316dd438a7af5c (diff)
downloadFreeBSD-src-f5462007056ca440dfe2c11ce75452bcdab12f57.zip
FreeBSD-src-f5462007056ca440dfe2c11ce75452bcdab12f57.tar.gz
Bridged packets are supplied to the firewall with their IP header
in network byte order, but icmp_error() expects the IP header to be in host order and the code here did not perform the necessary swapping for the bridged case. This bug causes an "icmp_error: bad length" panic when certain length IP packets (e.g. ip_len == 0x100) are rejected by the firewall with an ICMP response. MFC after: 3 days
-rw-r--r--sys/netinet/ip_fw.c7
-rw-r--r--sys/netinet/ip_fw2.c10
2 files changed, 14 insertions, 3 deletions
diff --git a/sys/netinet/ip_fw.c b/sys/netinet/ip_fw.c
index 8a41f99..26f4a04 100644
--- a/sys/netinet/ip_fw.c
+++ b/sys/netinet/ip_fw.c
@@ -1236,7 +1236,6 @@ again:
/* Check if rule only valid for bridged packets */
if ((f->fw_flg & IP_FW_BRIDGED) != 0 && !(BRIDGED))
continue;
-#undef BRIDGED
if (oif) {
/* Check direction outbound */
@@ -1628,6 +1627,11 @@ got_match:
&& (proto != IPPROTO_ICMP || is_icmp_query(ip))
&& !((*m)->m_flags & (M_BCAST|M_MCAST))
&& !IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) {
+ /* Must convert to host order for icmp_error() etc. */
+ if (BRIDGED) {
+ ip->ip_len = ntohs(ip->ip_len);
+ ip->ip_off = ntohs(ip->ip_off);
+ }
switch (f->fw_reject_code) {
case IP_FW_REJECT_RST:
{
@@ -1670,6 +1674,7 @@ dropit:
* Finally, drop the packet.
*/
return(IP_FW_PORT_DENY_FLAG);
+#undef BRIDGED
}
/*
diff --git a/sys/netinet/ip_fw2.c b/sys/netinet/ip_fw2.c
index 1e2b84e..5715587 100644
--- a/sys/netinet/ip_fw2.c
+++ b/sys/netinet/ip_fw2.c
@@ -1136,9 +1136,15 @@ static void
send_reject(struct ip_fw_args *args, int code, int offset, int ip_len)
{
- if (code != ICMP_REJECT_RST) /* Send an ICMP unreach */
+ if (code != ICMP_REJECT_RST) { /* Send an ICMP unreach */
+ /* We need the IP header in host order for icmp_error(). */
+ if (args->eh != NULL) {
+ struct ip *ip = mtod(args->m, struct ip *);
+ ip->ip_len = ntohs(ip->ip_len);
+ ip->ip_off = ntohs(ip->ip_off);
+ }
icmp_error(args->m, ICMP_UNREACH, code, 0L, 0);
- else if (offset == 0 && args->f_id.proto == IPPROTO_TCP) {
+ } else if (offset == 0 && args->f_id.proto == IPPROTO_TCP) {
struct tcphdr *const tcp =
L3HDR(struct tcphdr, mtod(args->m, struct ip *));
if ( (tcp->th_flags & TH_RST) == 0)
OpenPOWER on IntegriCloud