]> git.proxmox.com Git - pve-firewall.git/commitdiff
fix #2178: endless loop on ipv6 extension headers
authorMira Limbeck <m.limbeck@proxmox.com>
Wed, 17 Apr 2019 14:44:16 +0000 (16:44 +0200)
committerWolfgang Bumiller <w.bumiller@proxmox.com>
Thu, 18 Apr 2019 11:24:16 +0000 (13:24 +0200)
increment header and decrement payload size by the extensions size. the
length calculation is different for some extensions. in our case only
IPPROTO_FRAGMENT requires a different size calculation than the rest. in
addition 'proto' is now set in the loop when advancing from an
extension header. it moves on to the next extension or protocol now
instead of looping on the same 'proto' while advancing the payload.

Signed-off-by: Mira Limbeck <m.limbeck@proxmox.com>
src/pvefw-logger.c

index f77f56f7f71be1e9eafa5f997639e3770e6e82aa..181d5f1e8b7520b008b7761943ce9d04f6e3b6cc 100644 (file)
@@ -575,6 +575,7 @@ print_nexthdr(struct log_entry *le, char *hdr, int payload_len, u_int8_t proto)
             return 0;
 
         struct ip6_ext *exthdr = (struct ip6_ext*)hdr;
             return 0;
 
         struct ip6_ext *exthdr = (struct ip6_ext*)hdr;
+        int ext_len = 0;
 
         switch (proto) {
         /* protocols (these return) */
 
         switch (proto) {
         /* protocols (these return) */
@@ -601,6 +602,7 @@ print_nexthdr(struct log_entry *le, char *hdr, int payload_len, u_int8_t proto)
                 return -1;
             if (print_fragment(le, (struct ip6_frag*)hdr, payload_len) < 0)
                 return -1;
                 return -1;
             if (print_fragment(le, (struct ip6_frag*)hdr, payload_len) < 0)
                 return -1;
+            ext_len = sizeof(struct ip6_frag);
             break;
         case IPPROTO_HOPOPTS:
             LEPRINTF("NEXTHDR=HOPOPTS ");
             break;
         case IPPROTO_HOPOPTS:
             LEPRINTF("NEXTHDR=HOPOPTS ");
@@ -628,8 +630,12 @@ print_nexthdr(struct log_entry *le, char *hdr, int payload_len, u_int8_t proto)
         /* next header: */
         if (check_ip6ext(le, exthdr, payload_len) < 0)
             return -1;
         /* next header: */
         if (check_ip6ext(le, exthdr, payload_len) < 0)
             return -1;
-        hdr += exthdr->ip6e_len;
-        payload_len -= exthdr->ip6e_len;
+        if(ext_len == 0) {
+            ext_len = (exthdr->ip6e_len+1) * 8;
+        }
+        hdr += ext_len;
+        payload_len -= ext_len;
+        proto = exthdr->ip6e_nxt;
     }
 }
 
     }
 }