[UBUNTU 20.04] kernel: unable to read partitions on virtio-block dasd (kvm)
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Ubuntu on IBM z Systems |
Fix Released
|
High
|
Skipper Bug Screeners | ||
linux (Ubuntu) |
Fix Released
|
Undecided
|
Unassigned | ||
Focal |
Fix Released
|
Medium
|
Canonical Kernel Team | ||
Hirsute |
Fix Released
|
Medium
|
Canonical Kernel Team | ||
Impish |
Fix Released
|
Medium
|
Canonical Kernel Team | ||
Jammy |
Fix Released
|
Undecided
|
Unassigned |
Bug Description
SRU Justification:
==================
[Impact]
* The kernel is unable to read partitions on virtio-block DASD (on KVM).
That's a severe situation, since it prevents Ubuntu from starting, if installed on a DASD.
This issue can either occur after a fresh installation or after an upgrade.
* The virtio specification virtio-v1.1-cs01 states: "Transitional devices
MUST detect Legacy drivers by detecting that VIRTIO_F_VERSION_1 has not
been acknowledged by the driver."
And this is what QEMU as of 6.1 has done relying solely on
VIRTIO_
* But the specification also says: "... the driver MAY read (but MUST
NOT write) the device-specific configuration fields to check that it can
support the device ..." before setting FEATURES_OK.
* In this case, any transitional device relying solely on VIRTIO_F_VERSION_1
for detecting legacy drivers will return data in legacy format.
In particular, this implies that it's in big endian format for
big endian guests. This naturally confuses the driver that expects
little endian in the modern mode.
* VIRTIO_F_VERSION_1 can only be relied on after the feature negotiation is done.
* 'verify' is called before virtio_
s390 virtio device still serves native endian (i.e. big endian) config space,
while the driver knows that it is going to accept VERSION_1,
so when reading the config space, it assumes it got little endian, and byteswaps.
* For QEMU, we can work around the issue by writing out the feature bits with
VIRTIO_
this. This isn't enough to address all vhost devices since these do not get
the features until FEATURES_OK, however it looks like the affected devices
actually never handled the endianness for legacy mode correctly, so at least
that's not a regression.
[Fix]
* 2f9a174f918e296
[Test Case]
* Setup an IBM Z or LinuxONE LPAR with Ubuntu Server 20.04 as KVM host.
* This Ubuntu KVM host can either be installed on FCP or DASD storage,
but at least one DASD disk need to be reserved for a KVM guest.
* Now hand over the reserved DASD disk (low-level formatted using dasdfmt
and partitioned using fdasd) using 'virtio-block' to a KVM virtual machine
(e.g. using a virsh VM config).
* Try to install an Ubuntu KVM virtual machine using this DASD disk,
that includes the check and read of the partition table.
[Where problems could occur]
* First of all requested commit contains one additional if statement;
and is due tothat relatively traceable.
* But the change is in /drivers/
* This issue obviously affects big endian systems only.
* But if done wrong, it may effect in worst-case little endian systems, too!
* But the if statement explicitly checks for '!virtio_
* Only virtio net and virtio blk devices seem to be affected.
* And the commit/solutions was in-depth discussed upstream here:
https://<email address hidden>/t/#u
[Other]
* Patches are upstream accepted with since 5.15-rc6
and tagged for upstream stable #v4.11.
Hence jammy is not affected.
* Request was to add the patches to focal / 20.04,
but to avoid potential regressions on upgrades,
the patches need to be added to impish and hirsute, too.
* Fortunately cherry-picking the commit works cleanly
from all the affected Ubuntu releases.
__________
Description: kernel: unable to read partitions on virtio-block dasd (kvm)
Symptom: unable to read partitions on virtio-block dasd (kvm)
Problem: verify is called before virtio_
(i.e. big endian) config space, while the driver knows that it
is going to accept VERSION_1, so when reading the config space,
it assumes it got little endian, and byteswaps.
Solution: For QEMU, we can work around the issue by writing out the
until FEATURES_OK, however it looks like the affected devices
so at least that's not a regression.
CVE References
tags: | added: architecture-s39064 bugnameltc-195009 severity-high targetmilestone-inin--- |
Changed in ubuntu: | |
assignee: | nobody → Skipper Bug Screeners (skipper-screen-team) |
affects: | ubuntu → linux (Ubuntu) |
Changed in linux (Ubuntu Impish): | |
importance: | Undecided → Medium |
Changed in linux (Ubuntu Hirsute): | |
importance: | Undecided → Medium |
Changed in linux (Ubuntu Focal): | |
importance: | Undecided → Medium |
Changed in linux (Ubuntu Impish): | |
status: | In Progress → Fix Committed |
Changed in linux (Ubuntu Hirsute): | |
status: | In Progress → Fix Committed |
Changed in linux (Ubuntu Focal): | |
status: | In Progress → Fix Committed |
Changed in ubuntu-z-systems: | |
status: | In Progress → Fix Committed |
tags: |
added: targetmilestone-inin2004 removed: targetmilestone-inin--- |
Changed in ubuntu-z-systems: | |
status: | Fix Committed → Fix Released |
------- Comment From <email address hidden> 2021-11-08 06:34 EDT-------
[Impact]
* unable to read partitions on virtio-block dasd (Regression)
* the problem is that verify is called before virtio_ finalize_ features( ) , so a
transitional s390 virtio device still serves native endian
(i.e. big endian) config space, while the driver knows that it
is going to accept VERSION_1, so when reading the config space,
it assumes it got little endian, and byteswaps.
* as a solution for QEMU, we can work around the issue by writing out the
feature bits with VIRTIO_F_VERSION_1 bit set. We (ab)use the
finalize_features config op for this. This isn't enough to
address all vhost devices since these do not get the features
until FEATURES_OK, however it looks like the affected devices
actually never handled the endianness for legacy mode correctly,
so at least that's not a regression.
[Test Plan]
Short: try to read/write virtio-dasd partition table in a kvm guest
Long:
- get access to a dasd device (for this test it is best to pick a dasd that has already been formatted and partitioned in the past,
but can format and partition dasd new if needed).
- configure guest with the full dasd block device as a virtio block device
- boot this guest
- verify whether or not the guest is seeing the pre-created partition on device.
[Fix]
apply kernel upstream commit: 2f9a174f918e (virtio: write back F_VERSION_1 before validate)