Skip to content

Commit

Permalink
Fix bad VP array type value accesses
Browse files Browse the repository at this point in the history
  • Loading branch information
arr2036 committed Dec 15, 2014
1 parent b3abe1f commit 11ce79d
Show file tree
Hide file tree
Showing 9 changed files with 47 additions and 49 deletions.
16 changes: 8 additions & 8 deletions src/lib/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ int fr_pton4(fr_ipaddr_t *out, char const *value, ssize_t inlen, bool resolve, b
} else if (is_integer(value) || ((value[0] == '0') && (value[1] == 'x'))) {
out->ipaddr.ip4addr.s_addr = htonl(strtoul(value, NULL, 0));
} else if (!resolve) {
if (inet_pton(AF_INET, value, &(out->ipaddr.ip4addr.s_addr)) <= 0) {
if (inet_pton(AF_INET, value, &out->ipaddr.ip4addr.s_addr) <= 0) {
fr_strerror_printf("Failed to parse IPv4 address string \"%s\"", value);
return -1;
}
Expand All @@ -279,7 +279,7 @@ int fr_pton4(fr_ipaddr_t *out, char const *value, ssize_t inlen, bool resolve, b
buffer[p - value] = '\0';

if (!resolve) {
if (inet_pton(AF_INET, buffer, &(out->ipaddr.ip4addr.s_addr)) <= 0) {
if (inet_pton(AF_INET, buffer, &out->ipaddr.ip4addr.s_addr) <= 0) {
fr_strerror_printf("Failed to parse IPv4 address string \"%s\"", value);
return -1;
}
Expand All @@ -297,7 +297,7 @@ int fr_pton4(fr_ipaddr_t *out, char const *value, ssize_t inlen, bool resolve, b
}

if (prefix < 32) {
out->ipaddr.ip4addr = fr_inaddr_mask(&(out->ipaddr.ip4addr), prefix);
out->ipaddr.ip4addr = fr_inaddr_mask(&out->ipaddr.ip4addr, prefix);
}

out->prefix = (uint8_t) prefix;
Expand Down Expand Up @@ -342,9 +342,9 @@ int fr_pton6(fr_ipaddr_t *out, char const *value, ssize_t inlen, bool resolve, b
* Allow '*' as the wildcard address
*/
if ((value[0] == '*') && (value[1] == '\0')) {
memset(&out->ipaddr.ip6addr.s6_addr, 0, sizeof(out->ipaddr.ip6addr.s6_addr));
memset(out->ipaddr.ip6addr.s6_addr, 0, sizeof(out->ipaddr.ip6addr.s6_addr));
} else if (!resolve) {
if (inet_pton(AF_INET6, value, &(out->ipaddr.ip6addr.s6_addr)) <= 0) {
if (inet_pton(AF_INET6, value, out->ipaddr.ip6addr.s6_addr) <= 0) {
fr_strerror_printf("Failed to parse IPv6 address string \"%s\"", value);
return -1;
}
Expand All @@ -368,7 +368,7 @@ int fr_pton6(fr_ipaddr_t *out, char const *value, ssize_t inlen, bool resolve, b
buffer[p - value] = '\0';

if (!resolve) {
if (inet_pton(AF_INET6, buffer, &(out->ipaddr.ip6addr.s6_addr)) <= 0) {
if (inet_pton(AF_INET6, buffer, out->ipaddr.ip6addr.s6_addr) <= 0) {
fr_strerror_printf("Failed to parse IPv6 address string \"%s\"", value);
return -1;
}
Expand All @@ -388,8 +388,8 @@ int fr_pton6(fr_ipaddr_t *out, char const *value, ssize_t inlen, bool resolve, b
if (prefix < 128) {
struct in6_addr addr;

addr = fr_in6addr_mask(&(out->ipaddr.ip6addr), prefix);
memcpy(&(out->ipaddr.ip6addr.s6_addr), &addr, sizeof(addr));
addr = fr_in6addr_mask(&out->ipaddr.ip6addr, prefix);
memcpy(out->ipaddr.ip6addr.s6_addr, addr.s6_addr, sizeof(out->ipaddr.ip6addr.s6_addr));
}

out->prefix = (uint8_t) prefix;
Expand Down
8 changes: 4 additions & 4 deletions src/lib/radius.c
Original file line number Diff line number Diff line change
Expand Up @@ -3747,15 +3747,15 @@ ssize_t data2vp(TALLOC_CTX *ctx,
break;

case PW_TYPE_ETHERNET:
memcpy(&vp->vp_ether, data, 6);
memcpy(vp->vp_ether, data, 6);
break;

case PW_TYPE_IPV4_ADDR:
memcpy(&vp->vp_ipaddr, data, 4);
break;

case PW_TYPE_IFID:
memcpy(&vp->vp_ifid, data, 8);
memcpy(vp->vp_ifid, data, 8);
break;

case PW_TYPE_IPV6_ADDR:
Expand All @@ -3767,7 +3767,7 @@ ssize_t data2vp(TALLOC_CTX *ctx,
* FIXME: double-check that
* (vp->vp_octets[1] >> 3) matches vp->vp_length + 2
*/
memcpy(&vp->vp_ipv6prefix, data, vp->vp_length);
memcpy(vp->vp_ipv6prefix, data, vp->vp_length);
if (vp->vp_length < 18) {
memset(((uint8_t *)vp->vp_ipv6prefix) + vp->vp_length, 0,
18 - vp->vp_length);
Expand All @@ -3776,7 +3776,7 @@ ssize_t data2vp(TALLOC_CTX *ctx,

case PW_TYPE_IPV4_PREFIX:
/* FIXME: do the same double-check as for IPv6Prefix */
memcpy(&vp->vp_ipv4prefix, data, vp->vp_length);
memcpy(vp->vp_ipv4prefix, data, vp->vp_length);

/*
* /32 means "keep all bits". Otherwise, mask
Expand Down
40 changes: 20 additions & 20 deletions src/lib/value.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ int value_data_cmp(PW_TYPE a_type, value_data_t const *a, size_t a_len,
break;

case PW_TYPE_ETHERNET:
compare = memcmp(&a->ether, &b->ether, sizeof(a->ether));
compare = memcmp(a->ether, b->ether, sizeof(a->ether));
break;

case PW_TYPE_IPV4_ADDR: {
Expand All @@ -131,15 +131,15 @@ int value_data_cmp(PW_TYPE a_type, value_data_t const *a, size_t a_len,
break;

case PW_TYPE_IPV6_PREFIX:
compare = memcmp(&a->ipv6prefix, &b->ipv6prefix, sizeof(a->ipv6prefix));
compare = memcmp(a->ipv6prefix, b->ipv6prefix, sizeof(a->ipv6prefix));
break;

case PW_TYPE_IPV4_PREFIX:
compare = memcmp(&a->ipv4prefix, &b->ipv4prefix, sizeof(a->ipv4prefix));
compare = memcmp(a->ipv4prefix, b->ipv4prefix, sizeof(a->ipv4prefix));
break;

case PW_TYPE_IFID:
compare = memcmp(&a->ifid, &b->ifid, sizeof(a->ifid));
compare = memcmp(a->ifid, b->ifid, sizeof(a->ifid));
break;

/*
Expand Down Expand Up @@ -312,7 +312,7 @@ int value_data_cmp_op(FR_TOKEN op,

case PW_TYPE_IPV4_PREFIX: /* IPv4 and IPv4 Prefix */
return value_data_cidr_cmp_op(op, 4, 32, (uint8_t const *) &a->ipaddr,
b->ipv4prefix[1], (uint8_t const *) &b->ipv4prefix + 2);
b->ipv4prefix[1], (uint8_t const *) &b->ipv4prefix[2]);

default:
fr_strerror_printf("Cannot compare IPv4 with IPv6 address");
Expand All @@ -324,13 +324,13 @@ int value_data_cmp_op(FR_TOKEN op,
switch (b_type) {
case PW_TYPE_IPV4_ADDR:
return value_data_cidr_cmp_op(op, 4, a->ipv4prefix[1],
(uint8_t const *) &a->ipv4prefix + 2,
(uint8_t const *) &a->ipv4prefix[2],
32, (uint8_t const *) &b->ipaddr);

case PW_TYPE_IPV4_PREFIX: /* IPv4 Prefix and IPv4 Prefix */
return value_data_cidr_cmp_op(op, 4, a->ipv4prefix[1],
(uint8_t const *) &a->ipv4prefix + 2,
b->ipv4prefix[1], (uint8_t const *) &b->ipv4prefix + 2);
(uint8_t const *) &a->ipv4prefix[2],
b->ipv4prefix[1], (uint8_t const *) &b->ipv4prefix[2]);

default:
fr_strerror_printf("Cannot compare IPv4 with IPv6 address");
Expand All @@ -345,7 +345,7 @@ int value_data_cmp_op(FR_TOKEN op,

case PW_TYPE_IPV6_PREFIX: /* IPv6 and IPv6 Preifx */
return value_data_cidr_cmp_op(op, 16, 128, (uint8_t const *) &a->ipv6addr,
b->ipv6prefix[1], (uint8_t const *) &b->ipv6prefix + 2);
b->ipv6prefix[1], (uint8_t const *) &b->ipv6prefix[2]);
break;

default:
Expand All @@ -358,13 +358,13 @@ int value_data_cmp_op(FR_TOKEN op,
switch (b_type) {
case PW_TYPE_IPV6_ADDR: /* IPv6 Prefix and IPv6 */
return value_data_cidr_cmp_op(op, 16, a->ipv6prefix[1],
(uint8_t const *) &a->ipv6prefix + 2,
(uint8_t const *) &a->ipv6prefix[2],
128, (uint8_t const *) &b->ipv6addr);

case PW_TYPE_IPV6_PREFIX: /* IPv6 Prefix and IPv6 */
return value_data_cidr_cmp_op(op, 16, a->ipv6prefix[1],
(uint8_t const *) &a->ipv6prefix + 2,
b->ipv6prefix[1], (uint8_t const *) &b->ipv6prefix + 2);
(uint8_t const *) &a->ipv6prefix[2],
b->ipv6prefix[1], (uint8_t const *) &b->ipv6prefix[2]);

default:
fr_strerror_printf("Cannot compare IPv6 with IPv4 address");
Expand Down Expand Up @@ -691,7 +691,7 @@ ssize_t value_data_from_str(TALLOC_CTX *ctx, value_data_t *dst,
if (fr_pton4(&addr, src, src_len, fr_hostname_lookups, false) < 0) return -1;

dst->ipv4prefix[1] = addr.prefix;
memcpy(dst->ipv4prefix + 2, &addr.ipaddr.ip4addr.s_addr, sizeof(dst->ipv4prefix) - 2);
memcpy(&dst->ipv4prefix[2], &addr.ipaddr.ip4addr.s_addr, sizeof(dst->ipv4prefix) - 2);
}
goto finish;

Expand All @@ -711,7 +711,7 @@ ssize_t value_data_from_str(TALLOC_CTX *ctx, value_data_t *dst,
return -1;
}

memcpy(&dst->ipv6addr, &addr.ipaddr.ip6addr.s6_addr, sizeof(dst->ipv6addr));
memcpy(&dst->ipv6addr, addr.ipaddr.ip6addr.s6_addr, sizeof(dst->ipv6addr));
}
goto finish;

Expand All @@ -722,7 +722,7 @@ ssize_t value_data_from_str(TALLOC_CTX *ctx, value_data_t *dst,
if (fr_pton6(&addr, src, src_len, fr_hostname_lookups, false) < 0) return -1;

dst->ipv6prefix[1] = addr.prefix;
memcpy(dst->ipv6prefix + 2, &addr.ipaddr.ip6addr.s6_addr, sizeof(dst->ipv6prefix) - 2);
memcpy(&dst->ipv6prefix[2], addr.ipaddr.ip6addr.s6_addr, sizeof(dst->ipv6prefix) - 2);
}
goto finish;

Expand Down Expand Up @@ -877,7 +877,7 @@ ssize_t value_data_from_str(TALLOC_CTX *ctx, value_data_t *dst,
break;

case PW_TYPE_IFID:
if (ifid_aton(src, (void *) &dst->ifid) == NULL) {
if (ifid_aton(src, (void *) dst->ifid) == NULL) {
fr_strerror_printf("Failed to parse interface-id string \"%s\"", src);
return -1;
}
Expand All @@ -897,7 +897,7 @@ ssize_t value_data_from_str(TALLOC_CTX *ctx, value_data_t *dst,
if (is_integer(src)) {
uint64_t integer = htonll(atoll(src));

memcpy(&dst->ether, &integer, sizeof(dst->ether));
memcpy(dst->ether, &integer, sizeof(dst->ether));
break;
}

Expand Down Expand Up @@ -1015,7 +1015,7 @@ static void value_data_hton(value_data_t *dst, PW_TYPE type, void const *src, si
* @param src_enumv Enumerated values used to convert integers to strings.
* @param src Input data.
* @param src_len Input data len.
* @return the length of data in the dst.
* @return the length of data in the dst or -1 on error.
*/
ssize_t value_data_cast(TALLOC_CTX *ctx, value_data_t *dst,
PW_TYPE dst_type, DICT_ATTR const *dst_enumv,
Expand Down Expand Up @@ -1055,7 +1055,7 @@ ssize_t value_data_cast(TALLOC_CTX *ctx, value_data_t *dst,

if ((src_type == PW_TYPE_IFID) &&
(dst_type == PW_TYPE_INTEGER64)) {
memcpy(&dst->integer64, &src->ifid, sizeof(src->ifid));
memcpy(&dst->integer64, src->ifid, sizeof(src->ifid));
dst->integer64 = htonll(dst->integer64);
fixed_length:
return dict_attr_sizes[dst_type][0];
Expand All @@ -1074,7 +1074,7 @@ ssize_t value_data_cast(TALLOC_CTX *ctx, value_data_t *dst,
*/
if ((array[0] != 0) || (array[1] != 0)) return -1;

memcpy(&dst->ether, &array[2], 6);
memcpy(dst->ether, &array[2], 6);
goto fixed_length;
}

Expand Down
5 changes: 3 additions & 2 deletions src/main/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -1140,7 +1140,8 @@ RADCLIENT *client_afrom_request(RADCLIENT_LIST *clients, REQUEST *request)
if (da->attr == PW_FREERADIUS_CLIENT_IP_PREFIX) {
RDEBUG2("ipaddr = %s", strvalue);
c->ipaddr.af = AF_INET;
memcpy(&c->ipaddr.ipaddr.ip4addr.s_addr, &(vp->vp_ipv4prefix[2]), sizeof(c->ipaddr.ipaddr.ip4addr.s_addr));
memcpy(&c->ipaddr.ipaddr.ip4addr, &vp->vp_ipv4prefix[2],
sizeof(c->ipaddr.ipaddr.ip4addr.s_addr));
fr_ipaddr_mask(&c->ipaddr, (vp->vp_ipv4prefix[1] & 0x3f));
}

Expand All @@ -1150,7 +1151,7 @@ RADCLIENT *client_afrom_request(RADCLIENT_LIST *clients, REQUEST *request)
if (da->attr == PW_FREERADIUS_CLIENT_IPV6_PREFIX) {
RDEBUG2("ipaddr = %s", strvalue);
c->ipaddr.af = AF_INET6;
memcpy(&c->ipaddr.ipaddr.ip6addr, &(vp->vp_ipv6prefix[2]), sizeof(c->ipaddr.ipaddr.ip6addr));
memcpy(&c->ipaddr.ipaddr.ip6addr, &vp->vp_ipv6prefix[2], sizeof(c->ipaddr.ipaddr.ip6addr));
fr_ipaddr_mask(&c->ipaddr, vp->vp_ipv6prefix[1]);
}

Expand Down
9 changes: 3 additions & 6 deletions src/main/pair.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,18 +218,15 @@ int radius_compare_vps(UNUSED REQUEST *request, VALUE_PAIR *check, VALUE_PAIR *v
break;

case PW_TYPE_IPV6_ADDR:
ret = memcmp(&vp->vp_ipv6addr, &check->vp_ipv6addr,
sizeof(vp->vp_ipv6addr));
ret = memcmp(&vp->vp_ipv6addr, &check->vp_ipv6addr, sizeof(vp->vp_ipv6addr));
break;

case PW_TYPE_IPV6_PREFIX:
ret = memcmp(&vp->vp_ipv6prefix, &check->vp_ipv6prefix,
sizeof(vp->vp_ipv6prefix));
ret = memcmp(vp->vp_ipv6prefix, check->vp_ipv6prefix, sizeof(vp->vp_ipv6prefix));
break;

case PW_TYPE_IFID:
ret = memcmp(&vp->vp_ifid, &check->vp_ifid,
sizeof(vp->vp_ifid));
ret = memcmp(vp->vp_ifid, check->vp_ifid, sizeof(vp->vp_ifid));
break;

default:
Expand Down
8 changes: 4 additions & 4 deletions src/main/radsniff.c
Original file line number Diff line number Diff line change
Expand Up @@ -1129,11 +1129,11 @@ static void rs_packet_process(uint64_t count, rs_event_t *event, struct pcap_pkt
current->dst_ipaddr.ipaddr.ip4addr.s_addr = ip->ip_dst.s_addr;
} else {
current->src_ipaddr.af = AF_INET6;
memcpy(&current->src_ipaddr.ipaddr.ip6addr.s6_addr, &ip6->ip_src.s6_addr,
memcpy(current->src_ipaddr.ipaddr.ip6addr.s6_addr, ip6->ip_src.s6_addr,
sizeof(current->src_ipaddr.ipaddr.ip6addr.s6_addr));

current->dst_ipaddr.af = AF_INET6;
memcpy(&current->dst_ipaddr.ipaddr.ip6addr.s6_addr, &ip6->ip_dst.s6_addr,
memcpy(current->dst_ipaddr.ipaddr.ip6addr.s6_addr, ip6->ip_dst.s6_addr,
sizeof(current->dst_ipaddr.ipaddr.ip6addr.s6_addr));
}

Expand Down Expand Up @@ -1354,7 +1354,7 @@ static void rs_packet_process(uint64_t count, rs_event_t *event, struct pcap_pkt
} else {
original = rbtree_finddata(request_tree, &search);
if (original && (memcmp(original->expect->vector, current->vector,
sizeof(original->expect->vector)) != 0)) {
sizeof(original->expect->vector)) != 0)) {
/*
* ID reused before the request timed out (which may be an issue)...
*/
Expand Down Expand Up @@ -1431,7 +1431,7 @@ static void rs_packet_process(uint64_t count, rs_event_t *event, struct pcap_pkt
vp;
vp = fr_cursor_next(&cursor)) {
pairsteal(original, search.link_vps);
}
}
original->link_vps = search.link_vps;

/* We should never have conflicts */
Expand Down
4 changes: 2 additions & 2 deletions src/main/xlat.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ static ssize_t xlat_integer(UNUSED void *instance, REQUEST *request,
* bigendian.
*/
case PW_TYPE_ETHERNET:
memcpy(&int64, &vp->vp_ether, vp->vp_length);
memcpy(&int64, vp->vp_ether, vp->vp_length);
return snprintf(out, outlen, "%" PRIu64, htonll(int64));

case PW_TYPE_SIGNED:
Expand All @@ -191,7 +191,7 @@ static ssize_t xlat_integer(UNUSED void *instance, REQUEST *request,
return fr_prints_uint128(out, outlen, ntohlll(*(uint128_t const *) &vp->vp_ipv6addr));

case PW_TYPE_IPV6_PREFIX:
return fr_prints_uint128(out, outlen, ntohlll(*(uint128_t const *) &(vp->vp_ipv6prefix[2])));
return fr_prints_uint128(out, outlen, ntohlll(*(uint128_t const *) &vp->vp_ipv6prefix[2]));

default:
break;
Expand Down
4 changes: 2 additions & 2 deletions src/modules/proto_dhcp/dhcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1272,7 +1272,7 @@ static ssize_t fr_dhcp_vp2attr(uint8_t *out, size_t outlen, VALUE_PAIR *vp)
break;

case PW_TYPE_ETHERNET:
memcpy(p, &vp->vp_ether, 6);
memcpy(p, vp->vp_ether, 6);
break;

case PW_TYPE_STRING:
Expand Down Expand Up @@ -1849,7 +1849,7 @@ int fr_dhcp_add_arp_entry(int fd, char const *interface,
strlcpy(req.arp_dev, interface, sizeof(req.arp_dev));

if (macaddr->da->type == PW_TYPE_ETHERNET) {
memcpy(&req.arp_ha.sa_data, &macaddr->vp_ether, sizeof(macaddr->vp_ether));
memcpy(&req.arp_ha.sa_data, macaddr->vp_ether, sizeof(macaddr->vp_ether));
} else {
memcpy(&req.arp_ha.sa_data, macaddr->vp_octets, macaddr->vp_length);
}
Expand Down
2 changes: 1 addition & 1 deletion src/modules/rlm_eap/types/rlm_eap_ttls/ttls.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ static VALUE_PAIR *diameter2vp(REQUEST *request, REQUEST *fake, SSL *ssl,

case PW_TYPE_IPV6_PREFIX:
if (size != vp->vp_length) goto raw;
memcpy(&vp->vp_ipv6prefix, data, vp->vp_length);
memcpy(vp->vp_ipv6prefix, data, vp->vp_length);
break;

/*
Expand Down

0 comments on commit 11ce79d

Please sign in to comment.