aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Sperling <ssperling@sysmocom.de>2018-11-21 14:52:43 +0100
committerStefan Sperling <ssperling@sysmocom.de>2018-11-22 13:16:29 +0000
commite405c2f196ea77ba74438ec90545fda56f8f0444 (patch)
tree4e3c58c152518b26d22a9311decf1eb3727028bf
parent411ff3b9842bdc49d833da5682fb71c9cbcbcb8f (diff)
replace bogus memcpy() call in ippool_newip()
When copying an address to a reused static hash table member with memcpy(), this code mistakenly passed the size of a pointer as the amount of bytes to be copied, rather than the actual size of the address. This means the IP pool could contain bogus IP addresses because only addr->len (a uint8_t) and 3 further bytes of the address were actually copied on 32 bit platforms. On 64 bit platforms, a sufficient amount of bytes were copied for IPv4 to work correctly, but too few bytes were copied for IPv6. This problem was found by Coverity. Replace the bogus memcpy() call with direct assignments to the appropriate struct in64addr union members, and assert that the length recorded for the address actually corresponds to the length used by the address family (IP4, IPv6). Change-Id: Ic21560f7519e776107485a8779702fb1279d065c Related: CID#57921
-rw-r--r--lib/ippool.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/lib/ippool.c b/lib/ippool.c
index 6ce3cda..36121ee 100644
--- a/lib/ippool.c
+++ b/lib/ippool.c
@@ -512,7 +512,15 @@ int ippool_newip(struct ippool_t *this, struct ippoolm_t **member,
p2->next = NULL;
p2->prev = NULL;
p2->inuse = 2; /* Static address in use */
- memcpy(&p2->addr, addr, sizeof(addr));
+ /* p2->addr.len and addr->len already match (see above). */
+ if (p2->addr.len == sizeof(struct in_addr))
+ p2->addr.v4 = addr->v4;
+ else if (p2->addr.len == sizeof(struct in6_addr))
+ p2->addr.v6 = addr->v6;
+ else {
+ SYS_ERR(DIP, LOGL_ERROR, 0, "MS requested unsupported PDP context type");
+ return -GTPCAUSE_UNKNOWN_PDP;
+ }
*member = p2;
(void)ippool_hashadd(this, *member);
if (0)