Can kernel buffers + GPU DMA lead to data leaks.
Posted by This-Independent3181@reddit | linux | View on Reddit | 5 comments
Hi guys, I was digging into Linux memory management and came across an interesting optimization, when a page in memory is dropped(assuming it's clean) the kernel doesn't immediately zero out the contents rather it unmounts the page, does TLB shootdowns and puts the page in the page pool. Now when another process needs it the kernel zeros out the page and mounts the page to that process Virtual Memory.
Now the interesting thing is that if the page requested was by an user process the zeroing out is done mandatorly as to not violate isolation rules but if the page requested is by the kernel itself say the kernel needed it for its internal buffer or something then zeroing out isn't usually done as the kernel space is treated as trusted boundary and anyways the kernel will overwrite the contents of it so as to save time and bandwidth it avoids it.
This got me into thinking could it be missued. Like i did learn the other day that external devices like NIC, GPU, PCIe devices if they need to write to Main Memory they usually don't directly DMA to user mapped memory rather they DMA write to kernel buffer and copy from kernel space to user space happens.
I thought of situation where say a NIC card is DMAing to kernel buffer page this page was previously was allocated to some process and wasn't zeroed so old contents still exist. For example the NIC writes only 64 bytes but reports it as written 128 bytes So when the kernel sees this it interprets as NIC written 128 bytes as valid bytes and copies the 64 bytes actual content+64 bytes of stale left over bytes into respective process receive socket and the process then can call read on the socket and it reads the other process data.
But as i dig little deeper into the working of NIC I came to conclusion that this to happen is very highly unlikely and would need a bug at NIC's frimware level or the driver itself because NIC can't just like that lie about the bytes received, they track how many bits recieved at the phsyical level and writes a metadata about the exact length it wrote to the DRAM. So unless the frimware didn't count the recived bits properly or the driver failed to interpret the metadata it's highly unlikely to occur.
Another place where this could possibly happen is with GPU especially if followed the pipeline of GPU(DMA to)->kernel buffer(driver)->copy->user space.
As far as i have seen GPUs don't exactly report how many bytes it has written it usually signals after completion. and the driver acknowledges it and even if an explicitly mentioned the bytes written like using an counter it's usually managed by the software.
So when an user space application uses APIs like CUDA/DirectX to request a GPU compute with the expected output size, the driver in the kernel space then validates the request, allocates the required buffer size, sends GPU commands for execution and memory descriptiors for DMA. The driver then expects the GPU to fill the buffer with the expected size here say 128 Bytes was requested. But the GPU actually wrote only 16 Bytes and doesn't report the size written and just signals the completion the driver then copies the 128 Bytes from the kernel space to user space assuming the GPU has filled 128 Bytes where as in reality that wasn't case so if that page that was allocated to that buffer wasn't zeroed out those remianing bytes copied could contain the data of other process and the malicious application reads it.
Since GPUs are programmable today, is this possible if not, what exactly prevents this scenario from happening.
natermer@reddit
There is a classic hack using firewire devices and DMA access. This was back in USB 1.x and 2.x days.
Back in the day Firewire was popular for devices that needed high speed access. The original intention of USB was to create a unified interface for low speed serial devices like mice and keyboards. So if you needed higher speed access for things like sound cards or external hard drives you could use firewire. Also you could connect computers together using firewire.
One of the things that made firewire faster was it had DMA access. Meaning firewire devices could by-pass the OS and access memory directly.
So a hack was demonstrated were you could attach a device through firewire and then it could examine the system memory. By using entropy calculations it could then find in-memory secrets like harddrive encryption keys (the keys need to be in memory for the drive to be mounted) and passwords.
This is theoretically possible using faster USB and Thunderbolt. Using PCIe access is especially problematic. Since these things do use DMA.
OS designers and hardware manufacturers are aware of these types of exploits. So you can't just walk up to random laptops and insert a device into a firewire port like you used to. Newer versions of Windows have things like have white lists of approved devices and require administrative access for others. But if you trick users into adding malicious devices or modifying BIOS settings or that sort of thing then it can be possible.
It has been a long time since I last looked into the issue, but if attackers have physical access to your system while it is running then things like "full disk encryption" using LUKS can be defeated. It isn't trivial like it was with firewire, but it isn't impossible either.
monocasa@reddit
Also, these DMAing devices are behind IOMMUs these days, so they don't just have open access to physical memory.
natermer@reddit
Good to know. Thanks.
dnu-pdjdjdidndjs@reddit
Its kind of hard to understand what you're saying, but nowadays at least with vulkan the architecture is more like process virtual memory -> gpu dmas into the user space pages and they are always zeroed so this isnt possible with vulkan
if you mean for other pcie devices they could still be doing things in a silly way maybe I dont know
Good-Boy-961@reddit
In theory anything is possible