diff options
author | Sergey V. Lobanov <sergey@lobanov.in> | 2021-12-29 09:54:13 +0300 |
---|---|---|
committer | Sergey V. Lobanov <sergey@lobanov.in> | 2021-12-29 09:54:13 +0300 |
commit | d4cb89721cc8e5b3dd3fbefaf173eb77ecb85615 (patch) | |
tree | a53c9256b978bf415194ff9a4443db671804d43f /accel-pppd | |
parent | cca47ac174d1f2a99ee4969423e2bbc4b2fb6af8 (diff) | |
download | accel-ppp-d4cb89721cc8e5b3dd3fbefaf173eb77ecb85615.tar.gz accel-ppp-d4cb89721cc8e5b3dd3fbefaf173eb77ecb85615.zip |
fix buffer overflow when receive radius packet
This patch fixes buffer overflow if radius packet contains invalid atribute length
and attrubute type from the following list: ipv4addr, ipv6addr, ipv6prefix or ifid
Reported-by: Chloe Ong
Reported-by: Eugene Lim <spaceraccoon@users.noreply.github.com>
Reported-by: Kar Wei Loh
Signed-off-by: Sergey V. Lobanov <sergey@lobanov.in>
Diffstat (limited to 'accel-pppd')
-rw-r--r-- | accel-pppd/radius/dict.c | 12 | ||||
-rw-r--r-- | accel-pppd/radius/packet.c | 13 |
2 files changed, 21 insertions, 4 deletions
diff --git a/accel-pppd/radius/dict.c b/accel-pppd/radius/dict.c index 4924c895..145c5da2 100644 --- a/accel-pppd/radius/dict.c +++ b/accel-pppd/radius/dict.c @@ -193,14 +193,20 @@ static int dict_load(const char *fname) attr->type = ATTR_TYPE_STRING; else if (!strcmp(ptr[2], "date")) attr->type = ATTR_TYPE_DATE; - else if (!strcmp(ptr[2], "ipaddr")) + else if (!strcmp(ptr[2], "ipaddr")) { attr->type = ATTR_TYPE_IPADDR; + attr->size = 4; /* RFC 8044 §3.8 ipv4addr */ + } else if (!strcmp(ptr[2], "octets")) attr->type = ATTR_TYPE_OCTETS; - else if (!strcmp(ptr[2], "ifid")) + else if (!strcmp(ptr[2], "ifid")) { attr->type = ATTR_TYPE_IFID; - else if (!strcmp(ptr[2], "ipv6addr")) + attr->size = 8; /* RFC 8044 §3.7 ifid */ + } + else if (!strcmp(ptr[2], "ipv6addr")) { attr->type = ATTR_TYPE_IPV6ADDR; + attr->size = 16; /* RFC 8044 §3.9 ipv6addr */ + } else if (!strcmp(ptr[2], "ipv6prefix")) attr->type = ATTR_TYPE_IPV6PREFIX; else if (!strcmp(ptr[2], "ether")) diff --git a/accel-pppd/radius/packet.c b/accel-pppd/radius/packet.c index 07ddf6be..79007036 100644 --- a/accel-pppd/radius/packet.c +++ b/accel-pppd/radius/packet.c @@ -258,9 +258,20 @@ int rad_packet_recv(int fd, struct rad_packet_t **p, struct sockaddr_in *addr) case ATTR_TYPE_IPADDR: case ATTR_TYPE_IFID: case ATTR_TYPE_IPV6ADDR: - memcpy(&attr->val.integer, ptr, len); + if (len == da->size) + memcpy(&attr->val.integer, ptr, len); + else + log_ppp_warn("radius:packet: attribute %s has invalid length %i (must be %i)\n", da->name, len, da->size); break; case ATTR_TYPE_IPV6PREFIX: + if (len < 2 || len > 18) { /* RFC 8044 §3.10 ipv6prefix */ + log_ppp_warn("radius:packet: attribute %s has invalid length %i (must be from 2 to 18)\n", da->name, len); + break; + } + if (ptr[1] > 128) { + log_ppp_warn("radius:packet: attribute %s has invalid prefix length %u (must be from 0 to 128)\n", da->name, ptr[1]); + break; + } attr->val.ipv6prefix.len = ptr[1]; memset(&attr->val.ipv6prefix.prefix, 0, sizeof(attr->val.ipv6prefix.prefix)); memcpy(&attr->val.ipv6prefix.prefix, ptr + 2, len - 2); |