OSCORE: Fix OSCORE configuration file parsing issue

With a large boolean parameter value, (longer than "false"), memory
would be read past the "true" or "false" string boundaries in the ".rodata"
section when doing a memcmp(), potetially causing the application to crash
when calling coap_new_oscore_conf() with a specially crafted configuration
file.

It also can provide a mechanism to determine the byte values following the
"true" or "false" string boundaries which could lead to accessing sensitive
information. The standard libcoap library does not have defined keys or
certificates. This can only be done by a specially crafted local application.

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

Now fixed.
This commit is contained in:
Jon Shallow authored and Jon Shallow committed 2025-09-05 16:16:32 +01:00
1 parent 56a90642d3
commit da534de75e
1 file changed
+9 -4
+9 -4
View File
@@ -1758,6 +1758,7 @@ get_split_entry(const char **start,
const char *kend;
const char *split;
size_t i;
size_t len;
retry:
kend = end = memchr(begin, '\n', size);
@@ -1834,9 +1835,10 @@ retry:
value->u.value_str.length = end - begin;
break;
case COAP_ENC_BOOL:
if (memcmp("true", begin, end - begin) == 0)
len = (size_t)(end - begin);
if (len == 4 && memcmp("true", begin, len) == 0)
value->u.value_int = 1;
else if (memcmp("false", begin, end - begin) == 0)
else if (len == 5 && memcmp("false", begin, len) == 0)
value->u.value_int = 0;
else
goto bad_entry;
@@ -1851,7 +1853,7 @@ bad_entry:
coap_log_warn("oscore_conf: Unrecognized configuration entry '%.*s'\n",
(int)(end - begin),
begin);
return 0;
return -1;
}
#undef CONFIG_ENTRY
@@ -1923,6 +1925,7 @@ coap_parse_oscore_conf_mem(coap_str_const_t conf_mem) {
coap_str_const_t keyword;
oscore_value_t value;
coap_oscore_conf_t *oscore_conf;
int split_ok = -1;
oscore_conf = coap_malloc_type(COAP_STRING, sizeof(coap_oscore_conf_t));
if (oscore_conf == NULL)
@@ -1941,7 +1944,7 @@ coap_parse_oscore_conf_mem(coap_str_const_t conf_mem) {
oscore_conf->break_recipient_key = 0;
while (end > start &&
get_split_entry(&start, end - start, &keyword, &value)) {
(split_ok = get_split_entry(&start, end - start, &keyword, &value)) > 0) {
size_t i;
size_t j;
@@ -2027,6 +2030,8 @@ coap_parse_oscore_conf_mem(coap_str_const_t conf_mem) {
goto error;
}
}
if (split_ok == -1)
goto error;
if (!oscore_conf->master_secret) {
coap_log_warn("oscore_conf: master_secret not defined\n");
goto error;