On 2020/12/15 ??5:49, Konrad Rzeszutek Wilk wrote:> On Fri, Dec 11, 2020 at 06:31:21PM +0100, Felicitas Hetzelt wrote: >> Hello, > Hi! Please see below my responses. > >> we have been analyzing the Hypervisor-OS interface of Linux >> and discovered bugs in the swiotlb/virtio implementation that can be >> triggered from a malicious Hypervisor / virtual device. >> With SEV, the SWIOTLB implementation is forcefully enabled and would >> always be used. Thus, all virtio devices and others would use it under >> the hood. >> >> The reason for analyzing this interface 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. Therefore, all input received from the hypervisor or an >> external device should be carefully validated. 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. >> >> 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 >> >> Bug: >> OOB memory write. >> dma_unmap_single -> swiotlb_tbl_unmap_single is invoked with dma_addr >> and length parameters that are under control of the device. >> This happens e.g. in virtio_ring: >> https://elixir.bootlin.com/linux/v5.10-rc7/source/drivers/virtio/virtio_ring.c#L378 > Heya! > > Thank you for pointing this out! I've a couple of questions and hope you can > help me out with them. > > Also CC-ing AMD / TDX folks. >> This raises two issues: >> 1) swiotlb_tlb_unmap_single fails to check whether the index generated >> from the dma_addr is in range of the io_tlb_orig_addr array. > That is fairly simple to implement I would think. That is it can check > that the dma_addr is from the PA in the io_tlb pool when SWIOTLB=force > is used.I'm not sure this can fix all the cases. It looks to me we should map descriptor coherent but readonly (which is not supported by current DMA API). Otherwise, device can modify the desc[i].addr/desc[i].len at any time to pretend a valid mapping. Thanks>
Konrad Rzeszutek Wilk
2020-Dec-15 14:27 UTC
swiotlb/virtio: unchecked device dma address and length
.snip.> > > This raises two issues: > > > 1) swiotlb_tlb_unmap_single fails to check whether the index generated > > > from the dma_addr is in range of the io_tlb_orig_addr array. > > That is fairly simple to implement I would think. That is it can check > > that the dma_addr is from the PA in the io_tlb pool when SWIOTLB=force > > is used. > > > I'm not sure this can fix all the cases. It looks to me we should map > descriptor coherent but readonly (which is not supported by current DMA > API).I think I am missing something obvious here. The attacker is the hypervisor, aka the owner of the VirtIO device (ring0). The attacker is the one that provides the addr/len - having that readonly from a guest perspective does not change the fact that the hypervisor can modify the memory range by mapping it via a different virtual address in the hypervisor? (aka aliasing it).> > Otherwise, device can modify the desc[i].addr/desc[i].len at any time to > pretend a valid mapping.With the swiotlb=force as long as addr/len are within the PA boundaries within the SWIOTLB pool this should be OK? After all that whole area is in cleartext and visible to the attacker.
Michael S. Tsirkin
2020-Dec-16 08:54 UTC
swiotlb/virtio: unchecked device dma address and length
On Tue, Dec 15, 2020 at 11:20:48AM +0800, Jason Wang wrote:> > On 2020/12/15 ??5:49, Konrad Rzeszutek Wilk wrote: > > On Fri, Dec 11, 2020 at 06:31:21PM +0100, Felicitas Hetzelt wrote: > > > Hello, > > Hi! Please see below my responses. > > > > > we have been analyzing the Hypervisor-OS interface of Linux > > > and discovered bugs in the swiotlb/virtio implementation that can be > > > triggered from a malicious Hypervisor / virtual device. > > > With SEV, the SWIOTLB implementation is forcefully enabled and would > > > always be used. Thus, all virtio devices and others would use it under > > > the hood. > > > > > > The reason for analyzing this interface 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. Therefore, all input received from the hypervisor or an > > > external device should be carefully validated. 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. > > > > > > 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 > > > > > > Bug: > > > OOB memory write. > > > dma_unmap_single -> swiotlb_tbl_unmap_single is invoked with dma_addr > > > and length parameters that are under control of the device. > > > This happens e.g. in virtio_ring: > > > https://elixir.bootlin.com/linux/v5.10-rc7/source/drivers/virtio/virtio_ring.c#L378 > > Heya! > > > > Thank you for pointing this out! I've a couple of questions and hope you can > > help me out with them. > > > > Also CC-ing AMD / TDX folks. > > > This raises two issues: > > > 1) swiotlb_tlb_unmap_single fails to check whether the index generated > > > from the dma_addr is in range of the io_tlb_orig_addr array. > > That is fairly simple to implement I would think. That is it can check > > that the dma_addr is from the PA in the io_tlb pool when SWIOTLB=force > > is used. > > > I'm not sure this can fix all the cases. It looks to me we should map > descriptor coherent but readonly (which is not supported by current DMA > API).Neither is this supported but encrypted memory technologies.> Otherwise, device can modify the desc[i].addr/desc[i].len at any time to > pretend a valid mapping. > > Thanks > > > >