coap_address.c: Validate length of provided host name

Host names larger than 255 bytes will cause an internal buffer overflow.

Hostnames provided to coap_resolve_address_info() now have their length validated.

Discovered by SecMate (https://secmate.dev).

Sanity check host lengths when parsing a CoAP URI when using the coap_split_uri()
function.
This commit is contained in:
Jon Shallow committed 2025-09-16 11:41:41 +01:00
1 parent af54b3d826
commit cc9aba6e01
3 files changed
+32 -8

No files matched your search

+6 -5
View File
@@ -868,6 +868,12 @@ cmdline_tls_engine(char *arg) {
static int
cmdline_uri(char *arg) {
/* Sanity check the provided (Proxy)Uri */
if (coap_split_uri((unsigned char *)arg, strlen(arg), &uri) < 0) {
coap_log_err("invalid CoAP URI '%s'\n", arg);
return -1;
}
if (!proxy_scheme_option && proxy.host.length) {
/* create Proxy-Uri from argument */
size_t len = strlen(arg);
@@ -882,11 +888,6 @@ cmdline_uri(char *arg) {
(unsigned char *)arg));
} else { /* split arg into Uri-* options */
if (coap_split_uri((unsigned char *)arg, strlen(arg), &uri) < 0) {
coap_log_err("invalid CoAP URI\n");
return -1;
}
/* Need to special case use of reliable */
if (uri.scheme == COAP_URI_SCHEME_COAPS && reliable) {
if (!coap_tls_is_supported()) {
+7 -2
View File
@@ -534,10 +534,15 @@ coap_resolve_address_info(const coap_str_const_t *address,
#endif /* COAP_AF_UNIX_SUPPORT */
memset(addrstr, 0, sizeof(addrstr));
if (address && address->length)
if (address && address->length) {
if (address->length >= sizeof(addrstr)) {
coap_log_warn("Host name too long (%zu > 255)\n", address->length);
return NULL;
}
memcpy(addrstr, address->s, address->length);
else
} else {
memcpy(addrstr, "localhost", 9);
}
memset((char *)&hints, 0, sizeof(hints));
hints.ai_socktype = 0;
+19 -1
View File
@@ -59,6 +59,15 @@ coap_uri_info_t coap_uri_scheme[COAP_URI_SCHEME_LAST] = {
{ "coaps+ws", 443, 0, COAP_URI_SCHEME_COAPS_WS }
};
/*
* Returns 0 All OK
* -1 Insufficient / Invalid parameters
* -2 No '://'
* -3 Ipv6 definition error or no host defined after scheme://
* -4 Invalid port value
* -5 Port defined for Unix domain
* -6 Hostname > 255 chars
*/
static int
coap_split_uri_sub(const uint8_t *str_var,
size_t len,
@@ -167,8 +176,10 @@ coap_split_uri_sub(const uint8_t *str_var,
if (len && *p == '[') {
/* IPv6 address reference */
++p;
++q;
--len;
while (len && *q != ']') {
while (len && *q != ']' && (isxdigit(*q) || *q == ':')) {
++q;
--len;
}
@@ -199,6 +210,12 @@ coap_split_uri_sub(const uint8_t *str_var,
goto error;
}
if ((int)(q - p) > 255) {
coap_log_warn("Host name length too long (%d > 255)\n", (int)(q - p));
res = -6;
goto error;
}
COAP_SET_STR(&uri->host, q - p, p);
}
@@ -224,6 +241,7 @@ coap_split_uri_sub(const uint8_t *str_var,
/* check if port number is in allowed range */
if (uri_port > UINT16_MAX) {
coap_log_warn("Port number too big (%ld > 65535)\n", uri_port);
res = -4;
goto error;
}