untrusted comment: verify with openbsd-63-base.pub
RWRxzbLwAd76ZeXJ4+O6l1UcypT2D0NY3Vpu/Xf9jtESRHY4PfT07CK/YPYN0EABdBlRgMrrUDNiwQTj9PpOaVUlAuVMpCD2zgc=
OpenBSD 6.3 errata 031, March 22, 2019:
A state in pf could pass ICMP packets to a destination IP address
that did not match the state.
Apply by doing:
signify -Vep /etc/signify/openbsd-63-base.pub -x 031_pficmp.patch.sig \
-m - | (cd /usr/src && patch -p0)
And then rebuild and install a new kernel:
KK=`sysctl -n kern.osversion | cut -d# -f1`
cd /usr/src/sys/arch/`machine`/compile/$KK
make obj
make config
make
make install
Index: sys/net/pf.c
===================================================================
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.1063
diff -u -p -r1.1063 pf.c
--- sys/net/pf.c 6 Mar 2018 17:35:53 -0000 1.1063
+++ sys/net/pf.c 20 Mar 2019 20:24:15 -0000
@@ -4947,7 +4947,7 @@ pf_test_state_icmp(struct pf_pdesc *pd,
u_short *reason)
{
u_int16_t virtual_id, virtual_type;
- u_int8_t icmptype;
+ u_int8_t icmptype, icmpcode;
int icmp_dir, iidx, ret, copyback = 0;
struct pf_state_key_cmp key;
@@ -4955,10 +4955,12 @@ pf_test_state_icmp(struct pf_pdesc *pd,
switch (pd->proto) {
case IPPROTO_ICMP:
icmptype = pd->hdr.icmp.icmp_type;
+ icmpcode = pd->hdr.icmp.icmp_code;
break;
#ifdef INET6
case IPPROTO_ICMPV6:
icmptype = pd->hdr.icmp6.icmp6_type;
+ icmpcode = pd->hdr.icmp6.icmp6_code;
break;
#endif /* INET6 */
default:
@@ -5134,6 +5136,24 @@ pf_test_state_icmp(struct pf_pdesc *pd,
unhandled_af(pd->af);
}
+ if (PF_ANEQ(pd->dst, pd2.src, pd->af)) {
+ if (pf_status.debug >= LOG_NOTICE) {
+ log(LOG_NOTICE,
+ "pf: BAD ICMP %d:%d outer dst: ",
+ icmptype, icmpcode);
+ pf_print_host(pd->src, 0, pd->af);
+ addlog(" -> ");
+ pf_print_host(pd->dst, 0, pd->af);
+ addlog(" inner src: ");
+ pf_print_host(pd2.src, 0, pd2.af);
+ addlog(" -> ");
+ pf_print_host(pd2.dst, 0, pd2.af);
+ addlog("\n");
+ }
+ REASON_SET(reason, PFRES_BADSTATE);
+ return (PF_DROP);
+ }
+
switch (pd2.proto) {
case IPPROTO_TCP: {
struct tcphdr *th = &pd2.hdr.tcp;
@@ -5199,7 +5219,7 @@ pf_test_state_icmp(struct pf_pdesc *pd,
if (pf_status.debug >= LOG_NOTICE) {
log(LOG_NOTICE,
"pf: BAD ICMP %d:%d ",
- icmptype, pd->hdr.icmp.icmp_code);
+ icmptype, icmpcode);
pf_print_host(pd->src, 0, pd->af);
addlog(" -> ");
pf_print_host(pd->dst, 0, pd->af);
@@ -5213,7 +5233,7 @@ pf_test_state_icmp(struct pf_pdesc *pd,
if (pf_status.debug >= LOG_DEBUG) {
log(LOG_DEBUG,
"pf: OK ICMP %d:%d ",
- icmptype, pd->hdr.icmp.icmp_code);
+ icmptype, icmpcode);
pf_print_host(pd->src, 0, pd->af);
addlog(" -> ");
pf_print_host(pd->dst, 0, pd->af);