Skip to content
Permalink
Browse files Browse the repository at this point in the history
Fix a security issue in radius_get_vendor_attr().
The underlying rad_get_vendor_attr() function assumed that it would always be
given valid VSA data. Indeed, the buffer length wasn't even passed in; the
assumption was that the length field within the VSA structure would be valid.

This could result in denial of service by providing a length that would be
beyond the memory limit, or potential arbitrary memory access by providing a
length greater than the actual data given.

rad_get_vendor_attr() has been changed to require the raw data length be
provided, and this is then used to check that the VSA is valid.

Conflicts:
	radlib_vs.h
  • Loading branch information
LawnGnome committed Jun 27, 2013
1 parent 71b2139 commit 13c149b
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 10 deletions.
14 changes: 7 additions & 7 deletions radius.c
Expand Up @@ -541,24 +541,24 @@ PHP_FUNCTION(radius_get_attr)
/* {{{ proto string radius_get_vendor_attr(data) */
PHP_FUNCTION(radius_get_vendor_attr)
{
int res;
const void *data;
const void *data, *raw;
int len;
u_int32_t vendor;
unsigned char type;
size_t data_len;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &len) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &raw, &len) == FAILURE) {
return;
}

res = rad_get_vendor_attr(&vendor, &data, (size_t *) &len);
if (res == -1) {
if (rad_get_vendor_attr(&vendor, &type, &data, &data_len, raw, len) == -1) {
RETURN_FALSE;
} else {

array_init(return_value);
add_assoc_long(return_value, "attr", res);
add_assoc_long(return_value, "attr", type);
add_assoc_long(return_value, "vendor", vendor);
add_assoc_stringl(return_value, "data", (char *) data, len, 1);
add_assoc_stringl(return_value, "data", (char *) data, data_len, 1);
return;
}
}
Expand Down
13 changes: 11 additions & 2 deletions radlib.c
Expand Up @@ -898,15 +898,24 @@ split(char *str, char *fields[], int maxfields, char *msg, size_t msglen)
}

int
rad_get_vendor_attr(u_int32_t *vendor, const void **data, size_t *len)
rad_get_vendor_attr(u_int32_t *vendor, unsigned char *type, const void **data, size_t *len, const void *raw, size_t raw_len)
{
struct vendor_attribute *attr;

attr = (struct vendor_attribute *)*data;
if (raw_len < sizeof(struct vendor_attribute)) {
return -1;
}

attr = (struct vendor_attribute *) raw;
*vendor = ntohl(attr->vendor_value);
*type = attr->attrib_type;
*data = attr->attrib_data;
*len = attr->attrib_len - 2;

if ((attr->attrib_len + 4) > raw_len) {
return -1;
}

return (attr->attrib_type);
}

Expand Down
2 changes: 1 addition & 1 deletion radlib_vs.h
Expand Up @@ -74,7 +74,7 @@

struct rad_handle;

int rad_get_vendor_attr(u_int32_t *, const void **, size_t *);
int rad_get_vendor_attr(u_int32_t *, unsigned char *, const void **, size_t *, const void *, size_t);
int rad_put_vendor_addr(struct rad_handle *, int, int, struct in_addr);
int rad_put_vendor_attr(struct rad_handle *, int, int, const void *,
size_t);
Expand Down

0 comments on commit 13c149b

Please sign in to comment.