Hi, I found the link http://www.secfu.net/ in one of sthen@'s mails. There the author mentions that we accept IPv6 hop-by-hop headers after fragment headers. In fact this is a result of my pf fragment reassembly, so add an extra check there.
ok? bluhm Index: net/pf.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/net/pf.c,v retrieving revision 1.998 diff -u -p -r1.998 pf.c --- net/pf.c 14 Nov 2016 13:25:00 -0000 1.998 +++ net/pf.c 16 Nov 2016 20:39:38 -0000 @@ -6207,13 +6207,14 @@ pf_walk_header6(struct pf_pdesc *pd, str struct ip6_ext ext; struct ip6_rthdr rthdr; u_int32_t end; - int fraghdr_cnt = 0, rthdr_cnt = 0; + int hdr_cnt = 0, fraghdr_cnt = 0, rthdr_cnt = 0; pd->off += sizeof(struct ip6_hdr); end = pd->off + ntohs(h->ip6_plen); pd->fragoff = pd->extoff = pd->jumbolen = 0; pd->proto = h->ip6_nxt; for (;;) { + hdr_cnt++; switch (pd->proto) { case IPPROTO_FRAGMENT: if (fraghdr_cnt++) { @@ -6266,8 +6267,15 @@ pf_walk_header6(struct pf_pdesc *pd, str return (PF_DROP); } /* FALLTHROUGH */ - case IPPROTO_AH: case IPPROTO_HOPOPTS: + /* RFC2460 4.1: Hop-by-Hop only after IPv6 header */ + if (pd->proto == IPPROTO_HOPOPTS && hdr_cnt > 1) { + DPFPRINTF(LOG_NOTICE, "IPv6 hopopts not first"); + REASON_SET(reason, PFRES_IPOPTIONS); + return (PF_DROP); + } + /* FALLTHROUGH */ + case IPPROTO_AH: case IPPROTO_DSTOPTS: /* fragments may be short */ if (pd->fragoff != 0 && end < pd->off + sizeof(ext)) {