sgsnemu: Pass array of in64_addr to in46a_from_eua()
Let's avoid buffer-overflow writing into out-of-bounds memory in the event the GGSN sends us 2 EUAs in Create PDP Context Respose. It should theoretically happen since we don't yet support ipv4v6 APNs in sgsnemu, but who knows. Change-Id: I8becd90ce1f0e8bb6e21438c04da4a9cab845492
This commit is contained in:
parent
107c813eee
commit
28c6a32677
|
@ -1409,8 +1409,8 @@ static int cb_tun_ind(struct tun_t *tun, void *pack, unsigned len)
|
|||
|
||||
static int create_pdp_conf(struct pdp_t *pdp, void *cbp, int cause)
|
||||
{
|
||||
int rc;
|
||||
struct in46_addr addr;
|
||||
int rc, i, num_addr;
|
||||
struct in46_addr addr[2];
|
||||
#if defined(__linux__)
|
||||
sigset_t oldmask;
|
||||
#endif
|
||||
|
@ -1442,7 +1442,7 @@ static int create_pdp_conf(struct pdp_t *pdp, void *cbp, int cause)
|
|||
return EOF; /* Not what we expected */
|
||||
}
|
||||
|
||||
if (in46a_from_eua(&pdp->eua, &addr) < 1) {
|
||||
if ((num_addr = in46a_from_eua(&pdp->eua, addr)) < 1) {
|
||||
printf
|
||||
("Received create PDP context response. Cause value: %d\n",
|
||||
cause);
|
||||
|
@ -1452,20 +1452,7 @@ static int create_pdp_conf(struct pdp_t *pdp, void *cbp, int cause)
|
|||
return EOF; /* Not a valid IP address */
|
||||
}
|
||||
|
||||
printf("Received create PDP context response. IP address: %s\n",
|
||||
in46a_ntoa(&addr));
|
||||
|
||||
switch (addr.len) {
|
||||
case 16: /* IPv6 */
|
||||
/* we have to enable the kernel to perform stateless autoconfiguration,
|
||||
* i.e. send a router solicitation using the lover 64bits of the allocated
|
||||
* EUA as interface identifier, as per 3GPP TS 29.061 Section 11.2.1.3.2 */
|
||||
memcpy(addr.v6.s6_addr, ll_prefix, sizeof(ll_prefix));
|
||||
printf("Derived IPv6 link-local address: %s\n", in46a_ntoa(&addr));
|
||||
break;
|
||||
case 4: /* IPv4 */
|
||||
break;
|
||||
}
|
||||
printf("Received create PDP context response.\n");
|
||||
|
||||
#if defined(__linux__)
|
||||
if ((options.createif) && (options.netns)) {
|
||||
|
@ -1477,19 +1464,37 @@ static int create_pdp_conf(struct pdp_t *pdp, void *cbp, int cause)
|
|||
}
|
||||
#endif
|
||||
|
||||
if ((options.createif) && (!options.net.len)) {
|
||||
size_t prefixlen = 32;
|
||||
if (addr.len == 16)
|
||||
prefixlen = 64;
|
||||
/* printf("Setting up interface and routing\n"); */
|
||||
tun_addaddr(tun, &addr, &addr, prefixlen);
|
||||
if (options.defaultroute) {
|
||||
struct in_addr rm;
|
||||
rm.s_addr = 0;
|
||||
netdev_addroute(&rm, &addr.v4, &rm);
|
||||
for (i = 0; i < num_addr; i++) {
|
||||
printf("PDP ctx: received EUA with IP address: %s\n", in46a_ntoa(&addr[i]));
|
||||
|
||||
switch (addr[i].len) {
|
||||
case 16: /* IPv6 */
|
||||
/* we have to enable the kernel to perform stateless autoconfiguration,
|
||||
* i.e. send a router solicitation using the lover 64bits of the allocated
|
||||
* EUA as interface identifier, as per 3GPP TS 29.061 Section 11.2.1.3.2 */
|
||||
memcpy(addr[i].v6.s6_addr, ll_prefix, sizeof(ll_prefix));
|
||||
printf("Derived IPv6 link-local address: %s\n", in46a_ntoa(&addr[i]));
|
||||
break;
|
||||
case 4: /* IPv4 */
|
||||
break;
|
||||
}
|
||||
if (options.ipup)
|
||||
tun_runscript(tun, options.ipup);
|
||||
|
||||
if ((options.createif) && (!options.net.len)) {
|
||||
size_t prefixlen = 32;
|
||||
if (addr[i].len == 16)
|
||||
prefixlen = 64;
|
||||
/* printf("Setting up interface and routing\n"); */
|
||||
tun_addaddr(tun, &addr[i], &addr[i], prefixlen);
|
||||
if (options.defaultroute) {
|
||||
struct in_addr rm;
|
||||
rm.s_addr = 0;
|
||||
netdev_addroute(&rm, &addr[i].v4, &rm);
|
||||
}
|
||||
if (options.ipup)
|
||||
tun_runscript(tun, options.ipup);
|
||||
}
|
||||
|
||||
ipset(iph, &addr[i]);
|
||||
}
|
||||
|
||||
/* now that ip-up has been executed, check if we are configured to
|
||||
|
@ -1526,7 +1531,6 @@ static int create_pdp_conf(struct pdp_t *pdp, void *cbp, int cause)
|
|||
}
|
||||
#endif
|
||||
|
||||
ipset(iph, &addr);
|
||||
|
||||
state = 2; /* Connected */
|
||||
|
||||
|
|
Loading…
Reference in New Issue