lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [day] [month] [year] [list]
Date:   Thu, 10 Dec 2020 12:19:16 +0100
From:   Felicitas Hetzelt <file@...t.tu-berlin.de>
To:     <jiri@...nulli.us>
CC:     <netdev@...r.kernel.org>,
        "Radev, Martin" <martin.radev@...ec.fraunhofer.de>,
        "Morbitzer, Mathias" <mathias.morbitzer@...ec.fraunhofer.de>,
        Robert Buhren <robert@...t.tu-berlin.de>
Subject: Unchecked HW/hypervisor input issues in rocker module

Hello Jiri,

we have been analyzing the HW/Hypervisor-OS interface of device drivers
and discovered bugs in the rocker driver that can be triggered from a
malicious Hypervisor or PCI device.

The reason for analyzing these interfaces is that, technologies such as
Intel's Trusted Domain Extensions [1] and AMD's Secure Nested Paging [2]
change the threat model assumed by various Linux kernel subsystems.
These technologies take the presence of a fully malicious hypervisor
into account and aim to provide protection for virtual machines in such
an environment. Executing at a higher privilege level than the guest
kernel, the hypervisor was considered trustworthy in the past. Note that
these issues are of little (or no) relevance in a "normal"
virtualization setup, nevertheless we believe that it is required to fix
them if TDX or SNP is used.

Further, it is known that malicious PCI devices can be attached to the
USB-C port in order to attack this interface [3] (if thunderbolt is not
locked down).

Therefore, all input received from the hypervisor or an external device
should be carefully validated.

We are aware that these threat-models are relatively new and many parts
of the Linux kernel do not yet incorporate them.

We are happy to provide more information if needed!

[1]
https://software.intel.com/content/www/us/en/develop/articles/intel-trust-domain-extensions.html

[2] https://www.amd.com/en/processors/amd-secure-encrypted-virtualization

[3]
https://www.ndss-symposium.org/wp-content/uploads/2019/02/ndss2019_05A-1_Markettos_paper.pdf

###################################################################
Bug1:
Description:

Oob array access on rocker->msix_entries, due to an integer overflow
when evaluating ROCKER_MSIX_VEC_COUNT.

The allocation size of the rocker->msix_entries array determined by the
hardware
https://github.com/torvalds/linux/blob/eccc876724927ff3b9ff91f36f7b6b159e948f0c/drivers/net/ethernet/rocker/rocker_main.c#L2684
https://github.com/torvalds/linux/blob/eccc876724927ff3b9ff91f36f7b6b159e948f0c/drivers/net/ethernet/rocker/rocker_main.c#L2691

A different hardware controlled variable port_count determines the
maximum index for this array via
https://github.com/torvalds/linux/blob/eccc876724927ff3b9ff91f36f7b6b159e948f0c/drivers/net/ethernet/rocker/rocker_hw.h#L33
For a sufficiently large value of port count this calculation will cause
an integer overflow, i.e. port_count == 0xffffffff will result in
ROCKER_MSIX_VEC_COUNT(rocker->port_count) == 2, which is lower than e.g.
ROCKER_MSIX_VEC_RESERVED0.

Therefore, even though the number of reported msix_entries is checked
against port count
https://github.com/torvalds/linux/blob/eccc876724927ff3b9ff91f36f7b6b159e948f0c/drivers/net/ethernet/rocker/rocker_main.c#L2688
We found that for a value of port_count == -1/0xffffffff and
msix_entries == 2 that check will not trigger.
This leads to oob access on each invocation of rocker_msix_vector
https://github.com/torvalds/linux/blob/eccc876724927ff3b9ff91f36f7b6b159e948f0c/drivers/net/ethernet/rocker/rocker_main.c#L96
Whenever the passed vector parameter is >= 2, e.g.
https://github.com/torvalds/linux/blob/eccc876724927ff3b9ff91f36f7b6b159e948f0c/drivers/net/ethernet/rocker/rocker_main.c#L280

Patch:
Cast to long in ROCKER_MSIX_VEC_COUNT
Or check if port_count has a valid range in
https://github.com/torvalds/linux/blob/eccc876724927ff3b9ff91f36f7b6b159e948f0c/drivers/net/ethernet/rocker/rocker_main.c#L2944

###################################################################
Bug2:
Description:

PTR read from dma controlled mem (desc_info)
https://github.com/torvalds/linux/blob/eccc876724927ff3b9ff91f36f7b6b159e948f0c/drivers/net/ethernet/rocker/rocker_main.c#L572
https://github.com/torvalds/linux/blob/eccc876724927ff3b9ff91f36f7b6b159e948f0c/drivers/net/ethernet/rocker/rocker_main.c#L358

rocker->cmd_ring->desc is allocated as coherent dma memory
https://github.com/torvalds/linux/blob/eccc876724927ff3b9ff91f36f7b6b159e948f0c/drivers/net/ethernet/rocker/rocker_main.c#L610
https://github.com/torvalds/linux/blob/eccc876724927ff3b9ff91f36f7b6b159e948f0c/drivers/net/ethernet/rocker/rocker_main.c#L444

And rocker->cmd_ring->desc_info[*].desc is set to point to desc
structures in dma memory
https://github.com/torvalds/linux/blob/eccc876724927ff3b9ff91f36f7b6b159e948f0c/drivers/net/ethernet/rocker/rocker_main.c#L453

When the device is removed the following functions are called
Rocker_remove -> rocker_dma_rings_finie ->
rocker_dma_cmd_ring_waits_free -> rocker_dma_cmd_wait_free

Rocker_dma_cmd_wait_free invokes rocker_desc_cookie_ptr_get to
initialize the pointer variable ‘wait’ with a device controlled value
(as it is located in dma coherent memory). And passes that value to kfree.
https://github.com/torvalds/linux/blob/eccc876724927ff3b9ff91f36f7b6b159e948f0c/drivers/net/ethernet/rocker/rocker_main.c#L572
https://github.com/torvalds/linux/blob/eccc876724927ff3b9ff91f36f7b6b159e948f0c/drivers/net/ethernet/rocker/rocker_main.c#L358

Similar issues arise in other locations of the driver.

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ