Bug 222670 - Reinitialize mtod derived protocol header pointers in icmp_error after calling m_pullup
Summary: Reinitialize mtod derived protocol header pointers in icmp_error after callin...
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Only Me
Assignee: Andrey V. Elsukov
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-09-28 22:15 UTC by Prabhakar Lakhera
Modified: 2018-02-02 09:22 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Prabhakar Lakhera 2017-09-28 22:15:53 UTC
Header pointers needs to be reinitialized in icmp_error after m_pullup calls:

Date:   Thu Sep 28 15:06:28 2017 -0700

    Reinitialize mtod derived protocol header pointers in icmp_error after calling m_pullup

diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index 5983b3386af..4f466236864 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -237,6 +237,12 @@ icmp_error(struct mbuf *n, int type, int code, uint32_t dest, int mtu)
                if (n->m_len < oiphlen + sizeof(struct tcphdr) &&
                    ((n = m_pullup(n, oiphlen + sizeof(struct tcphdr))) == NULL))
                        goto freeit;
+
+               /*
+                * Reinitialize pointers derived from mbuf data pointer,
+                * after calling m_pullup
+                */
+               oip = mtod(n, struct ip *);
                th = (struct tcphdr *)((caddr_t)oip + oiphlen);
                tcphlen = th->th_off << 2;
                if (tcphlen < sizeof(struct tcphdr))
@@ -248,6 +254,14 @@ icmp_error(struct mbuf *n, int type, int code, uint32_t dest, int mtu)
                if (n->m_len < oiphlen + tcphlen && 
                    ((n = m_pullup(n, oiphlen + tcphlen)) == NULL))
                        goto freeit;
+
+               /*
+                * Reinitialize pointers derived from mbuf data pointer,
+                * after calling m_pullup
+                */
+               oip = mtod(n, struct ip *);
+               th = (struct tcphdr *)((caddr_t)oip + oiphlen);
+
                icmpelen = max(tcphlen, min(V_icmp_quotelen,
                    ntohs(oip->ip_len) - oiphlen));
        } else if (oip->ip_p == IPPROTO_SCTP) {
@@ -262,6 +276,12 @@ icmp_error(struct mbuf *n, int type, int code, uint32_t dest, int mtu)
                if (n->m_len < oiphlen + sizeof(struct sctphdr) &&
                    (n = m_pullup(n, oiphlen + sizeof(struct sctphdr))) == NULL)
                        goto freeit;
+
+               /*
+                * Reinitialize pointers derived from mbuf data pointer,
+                * after calling m_pullup
+                */
+               oip = mtod(n, struct ip *);
                icmpelen = max(sizeof(struct sctphdr),
                    min(V_icmp_quotelen, ntohs(oip->ip_len) - oiphlen));
                sh = (struct sctphdr *)((caddr_t)oip + oiphlen);
@@ -272,7 +292,15 @@ icmp_error(struct mbuf *n, int type, int code, uint32_t dest, int mtu)
                        if (n->m_len < oiphlen + sizeof(struct sctphdr) + 8 &&
                            (n = m_pullup(n, oiphlen + sizeof(struct sctphdr) + 8)) == NULL)
                                goto freeit;
+
+                       /*
+                        * Reinitialize pointers derived from mbuf data pointer,
+                        * after calling m_pullup
+                        */
+                       oip = mtod(n, struct ip *);
+                       sh = (struct sctphdr *)((caddr_t)oip + oiphlen);
                        ch = (struct sctp_chunkhdr *)(sh + 1);
+
                        if (ch->chunk_type == SCTP_INITIATION) {
                                icmpelen = max(sizeof(struct sctphdr) + 8,
                                    min(V_icmp_quotelen, ntohs(oip->ip_len) - oiphlen));
Comment 1 commit-hook freebsd_committer 2017-09-29 06:25:45 UTC
A commit references this bug:

Author: ae
Date: Fri Sep 29 06:24:45 UTC 2017
New revision: 324098
URL: https://svnweb.freebsd.org/changeset/base/324098

Log:
  Some mbuf related fixes in icmp_error()

  * check mbuf length before doing mtod() and accessing to IP header;
  * update oip pointer and all depending pointers after m_pullup();
  * remove extra checks and extra parentheses, wrap long lines;

  PR:		222670
  Reported by:	Prabhakar Lakhera
  MFC after:	1 week

Changes:
  head/sys/netinet/ip_icmp.c
Comment 2 commit-hook freebsd_committer 2017-10-09 08:50:47 UTC
A commit references this bug:

Author: ae
Date: Mon Oct  9 08:50:04 UTC 2017
New revision: 324426
URL: https://svnweb.freebsd.org/changeset/base/324426

Log:
  MFC r324098:
    Some mbuf related fixes in icmp_error()

    * check mbuf length before doing mtod() and accessing to IP header;
    * update oip pointer and all depending pointers after m_pullup();
    * remove extra checks and extra parentheses, wrap long lines;

    PR:		222670

Changes:
_U  stable/11/
  stable/11/sys/netinet/ip_icmp.c