Skip to content

zephyr: out-of-bound read in utf8_trunc

Moderate
ceolin published GHSA-gg46-3rh2-v765 Oct 4, 2024

Package

zephyr (zephyr)

Affected versions

<=3.6

Patched versions

None

Description

Summary

In utf8_trunc in zephyr/lib/utils/utf8.c, last_byte_p can point to one byte before the string pointer if the string is empty.

Details

First of all, I'm not sure whether this is a bug of library function or calling site's function.

The function utf8_trunc can be invoked by utf8_lcpy.

utf8_lcpy is called by multiple sites, and one example could be handle_generic_update in zephyr/subsys/bluetooth/audio/has_client.c.

There is no check for the input string, which could be empty string starting with null character, but name_len is larger than 0:

	pdu = net_buf_simple_pull_mem(buf, sizeof(*pdu));

	...

	name_len = buf->len + 1; /* + 1 byte for NULL terminator */
	if (name_len > ARRAY_SIZE(name)) {
		LOG_WRN("name is too long (%zu > %u)", buf->len, BT_HAS_PRESET_NAME_MAX);

		name_len = ARRAY_SIZE(name);
	}

	utf8_lcpy(name, pdu->name, name_len); // pdu->name could be null while name_len is not zero

When it goes into utf8_lcpy, it enters utf8_trunc since n is not 0:

char *utf8_lcpy(char *dst, const char *src, size_t n)
{
	if (n > 0) {
		strncpy(dst, src, n - 1);
		dst[n - 1] = '\0';

		if (n != 1) {
			utf8_trunc(dst);
		}
	}

	return dst;
}

This results in last_byte_p pointing to utf8_str - 1, because utf8_trunc seems to assume that utf8_str is not an empty string.

char *utf8_trunc(char *utf8_str)
{
	char *last_byte_p = utf8_str + strlen(utf8_str) - 1;
	uint8_t bytes_truncated;
	char seq_start_byte;

	if ((*last_byte_p & ASCII_CHAR) == *last_byte_p) {
		/* Not part of an UTF8 sequence, return */
		return utf8_str;
	}
	...

It directly leads to an out-of-bounds read in the subsequent code.

PoC

Send Read Preset response with PresetRecord name starting with a null character.

The name length can be any value other than 0.

Impact

Result of exploitation could lead to instability (i.e., crash) or denial of service attacks.

Patches

main: #74949
v3.6: #78286

For more information

If you have any questions or comments about this advisory:

embargo: 2024-09-22

Severity

Moderate

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Adjacent
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
Low
Integrity
Low
Availability
Low

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L

CVE ID

CVE-2024-6443

Credits