netfilter: ipv6: fix crash caused by ipv6_find_hdr()
[firefly-linux-kernel-4.4.55.git] / net / ipv6 / exthdrs_core.c
index 5c5d23e59da598995ff962d069d1e7b6886e31d6..835ec57c233b64dcb8a789975d52cb8f0c749d66 100644 (file)
@@ -166,15 +166,15 @@ EXPORT_SYMBOL_GPL(ipv6_find_tlv);
  * to explore inner IPv6 header, eg. ICMPv6 error messages.
  *
  * If target header is found, its offset is set in *offset and return protocol
- * number. Otherwise, return -1.
+ * number. Otherwise, return -ENOENT or -EBADMSG.
  *
  * If the first fragment doesn't contain the final protocol header or
  * NEXTHDR_NONE it is considered invalid.
  *
  * Note that non-1st fragment is special case that "the protocol number
  * of last header" is "next header" field in Fragment header. In this case,
- * *offset is meaningless and fragment offset is stored in *fragoff if fragoff
- * isn't NULL.
+ * *offset is meaningless. If fragoff is not NULL, the fragment offset is
+ * stored in *fragoff; if it is NULL, return -EINVAL.
  *
  * if flags is not NULL and it's a fragment, then the frag flag
  * IP6_FH_F_FRAG will be set. If it's an AH header, the
@@ -253,9 +253,12 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
                                if (target < 0 &&
                                    ((!ipv6_ext_hdr(hp->nexthdr)) ||
                                     hp->nexthdr == NEXTHDR_NONE)) {
-                                       if (fragoff)
+                                       if (fragoff) {
                                                *fragoff = _frag_off;
-                                       return hp->nexthdr;
+                                               return hp->nexthdr;
+                                       } else {
+                                               return -EINVAL;
+                                       }
                                }
                                return -ENOENT;
                        }