vhost IOTLB path leaks kernel memory via unchecked user access
A CAP_NET_ADMIN controller can aim vdpa_sim virtqueues at kernel addresses and read two bytes per kick after a missing access_ok check.
A missing address check in the Linux kernel's vhost virtqueue helpers lets a privileged controller read arbitrary kernel memory two bytes at a time through the vDPA simulator's default passthrough mode, security researcher Haoran Wang reported on the kernel mailing list.
The IOTLB helpers that fetch and store 16-bit virtqueue fields used the unchecked __get_user and __put_user macros on pointers that came only from an IOTLB interval lookup. That lookup never calls access_ok. In vdpa_sim passthrough the entire address space is identity-mapped, and queue addresses from the controller are stored verbatim. With CAP_NET_ADMIN, an attacker can therefore point a virtqueue at a kernel address; each queue kick yields a repeatable two-byte kernel read. Ordinary get_user would have rejected the address.
Virtio maintainer Michael S. Tsirkin posted a patch that added an explicit access_ok before the unchecked accessors. Linus Torvalds rejected the pattern: pairing access_ok with __get_user is slower, larger, and more bug-prone than plain get_user, and bare __get_user is almost always a bug except in rare code that deliberately tolerates kernel pointers. David Laight made the same point.
Tsirkin agreed the simple form is right in principle, then hit a constraint: the helpers run with bottom halves disabled, so get_user's might_sleep check would fire. Torvalds pointed at the newer unsafe_get_user model for multi-access hot paths, which generates better code than the legacy approach. Tsirkin said he would look at converting vhost once a wave of static-analysis reports settles.
The leak still needs a fix that both rejects kernel addresses and respects the non-sleeping call context. The exchange also restates a long-standing rule of thumb for kernel user-copy code: prefer get_user, and treat bare __get_user as a red flag.