pf.c: IPv6 Fragmentation Tag Not Cleared after Reassembly

Zixu Wu <[email protected]>
Newsgroups gmane.os.openbsd.bugs
Message-ID <[email protected]>
Currently, the IPv6 fragmentation tag is not cleared after reassembly 
unless as part of refragmentation when direction is `PF_FWD`. As a 
result, `PF_IN` packets handled by if_wg.c retain the fragmentation tag 
even after the encapsulation is removed, as long as the outer 
encapsulation was originally fragmented. pf.c will then fragment the 
encapsulated inner packets under the false belief that it had previously 
reassembled them. This behavior is incorrect, so is the MTU calculation 
during refragmentation in such case.

The proposed fix proactively removes the fragmentation tag if 
refragmentation is deemed unnecessary. It also removes the check 
condition on `pf_status.reass` as it should have no bearing on whether 
packets previously reassembled need to be refragmented.

diff --git a/sys/net/pf.c b/sys/net/pf.c
index 0fd00c0dbf3..493b7385730 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -8785,13 +8785,17 @@ done:
   }

  #ifdef INET6
- /* if reassembled packet passed, create new fragments */
- if (pf_status.reass && action == PF_PASS && pd.m && fwdir == PF_FWD &&
-     pd.af == AF_INET6) {
+ /* create new fragments if necessary */
+ if (pd.m && pd.af == AF_INET6) {
     struct m_tag  *mtag;

-   if ((mtag = m_tag_find(pd.m, PACKET_TAG_PF_REASSEMBLED, NULL)))
-     action = pf_refragment6(&pd.m, mtag, NULL, NULL, NULL);
+   if ((mtag = m_tag_find(pd.m, PACKET_TAG_PF_REASSEMBLED, NULL))) {
+     if (action == PF_PASS && fwdir == PF_FWD) {
+       action = pf_refragment6(&pd.m, mtag, NULL, NULL, NULL);
+     } else {
+       m_tag_delete(pd.m, mtag);
+     }
+   }
   }
  #endif /* INET6 */
   if (st && action != PF_DROP) {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.