summaryrefslogtreecommitdiff
path: root/accel-pppd
diff options
context:
space:
mode:
authorSergey V. Lobanov <sergey@lobanov.in>2021-12-29 09:54:13 +0300
committerSergey V. Lobanov <sergey@lobanov.in>2021-12-29 09:54:13 +0300
commitd4cb89721cc8e5b3dd3fbefaf173eb77ecb85615 (patch)
treea53c9256b978bf415194ff9a4443db671804d43f /accel-pppd
parentcca47ac174d1f2a99ee4969423e2bbc4b2fb6af8 (diff)
downloadaccel-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.c12
-rw-r--r--accel-pppd/radius/packet.c13
2 files changed, 21 insertions, 4 deletions
diff --git a/accel-pppd/radius/dict.c b/accel-pppd/radius/dict.c
index 4924c89..145c5da 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 07ddf6b..7900703 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);