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)) {