Skip to content

DoS: Invalid Initialization in `le_read_buffer_size_complete`

Moderate
ceolin published GHSA-wc2h-h868-q7hj Jan 19, 2023

Package

zephyr (west)

Affected versions

<= 3.2

Patched versions

None

Description

Summary

A malicious / defect bluetooth controller can cause a Denial of Service due to unchecked input in le_read_buffer_size_complete.

Description

LE Buffer Size is requested from bluehtooh controller and passed into le_read_buffer_size_complete without further checks:

bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_BUFFER_SIZE, NULL, &rsp);
le_read_buffer_size_complete(rsp);

/* Read LE Buffer Size */
err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_BUFFER_SIZE,
NULL, &rsp);
if (err) {
return err;
}
le_read_buffer_size_complete(rsp);

le_read_buffer_size_complete casts the response into a bt_hci_rp_le_read_buffer_size struct but only checks that le_max_len is set:

static void le_read_buffer_size_complete(struct net_buf *buf) {
	struct bt_hci_rp_le_read_buffer_size *rp = (void *)buf->data;
	bt_dev.le.acl_mtu = sys_le16_to_cpu(rp->le_max_len);
	if (!bt_dev.le.acl_mtu) { return; }

struct bt_hci_rp_le_read_buffer_size *rp = (void *)buf->data;
BT_DBG("status 0x%02x", rp->status);
#if defined(CONFIG_BT_CONN)
bt_dev.le.acl_mtu = sys_le16_to_cpu(rp->le_max_len);
if (!bt_dev.le.acl_mtu) {
return;
}

it passes the unchecked rp->le_max_num into k_sem_init:

k_sem_init(&bt_dev.le.acl_pkts, rp->le_max_num, rp->le_max_num);

k_sem_init(&bt_dev.le.acl_pkts, rp->le_max_num, rp->le_max_num);

However k_sem_init requires the limit to be greater than zero or skips the initialization otherwise:

int z_impl_k_sem_init(struct k_sem *sem, unsigned int initial_count, unsigned int limit) {
	CHECKIF(limit == 0U || limit > K_SEM_MAX_LIMIT || initial_count > limit) {
		return -EINVAL;
	}

zephyr/kernel/sem.c

Lines 41 to 51 in 426c51a

int z_impl_k_sem_init(struct k_sem *sem, unsigned int initial_count,
unsigned int limit)
{
/*
* Limit cannot be zero and count cannot be greater than limit
*/
CHECKIF(limit == 0U || limit > K_SEM_MAX_LIMIT || initial_count > limit) {
SYS_PORT_TRACING_OBJ_FUNC(k_sem, init, sem, -EINVAL);
return -EINVAL;
}

This ultimately leads to a nullptr-deref when the wait_q of the semaphore is used in z_impl_k_sem_take.

Impact

  • Denial of Service

Proposed Fix

  • Verify rp->le_max_num is a valid value in le_read_buffer_size_complete
    • Either return an error if not or use max(1, rp->le_max_num)

Patches

For more information

If you have any questions or comments about this advisory:

embargo: 2023-01-03

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
Physical
Attack complexity
High
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
Low
Integrity
High
Availability
High

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:P/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:H

CVE ID

CVE-2023-0397

Weaknesses

Improper Check or Handling of Exceptional Conditions

The product does not properly anticipate or handle exceptional conditions that rarely occur during normal operation of the product. Learn more on MITRE.