<p>pespin has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-ggsn/+/17764">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">sgsnemu: Pass array of in64_addr to in46a_from_eua()<br><br>Let's avoid buffer-overflow writing into out-of-bounds memory in the<br>event the GGSN sends us 2 EUAs in Create PDP Context Respose. It should<br>theoretically happen since we don't yet support ipv4v6 APNs in sgsnemu,<br>but who knows.<br><br>Change-Id: I8becd90ce1f0e8bb6e21438c04da4a9cab845492<br>---<br>M sgsnemu/sgsnemu.c<br>1 file changed, 34 insertions(+), 30 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-ggsn refs/changes/64/17764/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/sgsnemu/sgsnemu.c b/sgsnemu/sgsnemu.c</span><br><span>index 01bdf9b..679f3c2 100644</span><br><span>--- a/sgsnemu/sgsnemu.c</span><br><span>+++ b/sgsnemu/sgsnemu.c</span><br><span>@@ -1409,8 +1409,8 @@</span><br><span> </span><br><span> static int create_pdp_conf(struct pdp_t *pdp, void *cbp, int cause)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-        int rc;</span><br><span style="color: hsl(0, 100%, 40%);">- struct in46_addr addr;</span><br><span style="color: hsl(120, 100%, 40%);">+        int rc, i, num_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct in46_addr addr[2];</span><br><span> #if defined(__linux__)</span><br><span>  sigset_t oldmask;</span><br><span> #endif</span><br><span>@@ -1442,7 +1442,7 @@</span><br><span>          return EOF;     /* Not what we expected */</span><br><span>   }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   if (in46a_from_eua(&pdp->eua, &addr) < 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+     if ((num_addr = in46a_from_eua(&pdp->eua, addr)) < 1) {</span><br><span>            printf</span><br><span>                   ("Received create PDP context response. Cause value: %d\n",</span><br><span>                 cause);</span><br><span>@@ -1452,20 +1452,7 @@</span><br><span>                return EOF;     /* Not a valid IP address */</span><br><span>         }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   printf("Received create PDP context response. IP address: %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-             in46a_ntoa(&addr));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  switch (addr.len) {</span><br><span style="color: hsl(0, 100%, 40%);">-     case 16: /* IPv6 */</span><br><span style="color: hsl(0, 100%, 40%);">-             /* we have to enable the kernel to perform stateless autoconfiguration,</span><br><span style="color: hsl(0, 100%, 40%);">-          * i.e. send a router solicitation using the lover 64bits of the allocated</span><br><span style="color: hsl(0, 100%, 40%);">-               * EUA as interface identifier, as per 3GPP TS 29.061 Section 11.2.1.3.2 */</span><br><span style="color: hsl(0, 100%, 40%);">-             memcpy(addr.v6.s6_addr, ll_prefix, sizeof(ll_prefix));</span><br><span style="color: hsl(0, 100%, 40%);">-          printf("Derived IPv6 link-local address: %s\n", in46a_ntoa(&addr));</span><br><span style="color: hsl(0, 100%, 40%);">-               break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case 4: /* IPv4 */</span><br><span style="color: hsl(0, 100%, 40%);">-              break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("Received create PDP context response.\n");</span><br><span> </span><br><span> #if defined(__linux__)</span><br><span>   if ((options.createif) && (options.netns)) {</span><br><span>@@ -1477,19 +1464,37 @@</span><br><span>       }</span><br><span> #endif</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if ((options.createif) && (!options.net.len)) {</span><br><span style="color: hsl(0, 100%, 40%);">-         size_t prefixlen = 32;</span><br><span style="color: hsl(0, 100%, 40%);">-          if (addr.len == 16)</span><br><span style="color: hsl(0, 100%, 40%);">-                     prefixlen = 64;</span><br><span style="color: hsl(0, 100%, 40%);">-         /* printf("Setting up interface and routing\n"); */</span><br><span style="color: hsl(0, 100%, 40%);">-           tun_addaddr(tun, &addr, &addr, prefixlen);</span><br><span style="color: hsl(0, 100%, 40%);">-              if (options.defaultroute) {</span><br><span style="color: hsl(0, 100%, 40%);">-                     struct in_addr rm;</span><br><span style="color: hsl(0, 100%, 40%);">-                      rm.s_addr = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                  netdev_addroute(&rm, &addr.v4, &rm);</span><br><span style="color: hsl(120, 100%, 40%);">+      for (i = 0; i < num_addr; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+           printf("PDP ctx: received EUA with IP address: %s\n",  in46a_ntoa(&addr[i]));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         switch (addr[i].len) {</span><br><span style="color: hsl(120, 100%, 40%);">+                case 16: /* IPv6 */</span><br><span style="color: hsl(120, 100%, 40%);">+                   /* we have to enable the kernel to perform stateless autoconfiguration,</span><br><span style="color: hsl(120, 100%, 40%);">+                        * i.e. send a router solicitation using the lover 64bits of the allocated</span><br><span style="color: hsl(120, 100%, 40%);">+                     * EUA as interface identifier, as per 3GPP TS 29.061 Section 11.2.1.3.2 */</span><br><span style="color: hsl(120, 100%, 40%);">+                   memcpy(addr[i].v6.s6_addr, ll_prefix, sizeof(ll_prefix));</span><br><span style="color: hsl(120, 100%, 40%);">+                     printf("Derived IPv6 link-local address: %s\n", in46a_ntoa(&addr[i]));</span><br><span style="color: hsl(120, 100%, 40%);">+                  break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case 4: /* IPv4 */</span><br><span style="color: hsl(120, 100%, 40%);">+                    break;</span><br><span>               }</span><br><span style="color: hsl(0, 100%, 40%);">-               if (options.ipup)</span><br><span style="color: hsl(0, 100%, 40%);">-                       tun_runscript(tun, options.ipup);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           if ((options.createif) && (!options.net.len)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       size_t prefixlen = 32;</span><br><span style="color: hsl(120, 100%, 40%);">+                        if (addr[i].len == 16)</span><br><span style="color: hsl(120, 100%, 40%);">+                                prefixlen = 64;</span><br><span style="color: hsl(120, 100%, 40%);">+                       /* printf("Setting up interface and routing\n"); */</span><br><span style="color: hsl(120, 100%, 40%);">+                 tun_addaddr(tun, &addr[i], &addr[i], prefixlen);</span><br><span style="color: hsl(120, 100%, 40%);">+                      if (options.defaultroute) {</span><br><span style="color: hsl(120, 100%, 40%);">+                           struct in_addr rm;</span><br><span style="color: hsl(120, 100%, 40%);">+                            rm.s_addr = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                                netdev_addroute(&rm, &addr[i].v4, &rm);</span><br><span style="color: hsl(120, 100%, 40%);">+                   }</span><br><span style="color: hsl(120, 100%, 40%);">+                     if (options.ipup)</span><br><span style="color: hsl(120, 100%, 40%);">+                             tun_runscript(tun, options.ipup);</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           ipset(iph, &addr[i]);</span><br><span>    }</span><br><span> </span><br><span>        /* now that ip-up has been executed, check if we are configured to</span><br><span>@@ -1526,7 +1531,6 @@</span><br><span>   }</span><br><span> #endif</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- ipset(iph, &addr);</span><br><span> </span><br><span>   state = 2;              /* Connected */</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-ggsn/+/17764">change 17764</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-ggsn/+/17764"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-ggsn </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I8becd90ce1f0e8bb6e21438c04da4a9cab845492 </div>
<div style="display:none"> Gerrit-Change-Number: 17764 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>