mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-25 06:52:13 +00:00
agent/device: Check type as well as major:minor when looking up devices
To update device resource entries from host to guest, we search for the right entry by host major:minor numbers, then later update it. However block and character devices exist in separate major:minor namespaces so we could have one block and one character device with matching major:minor and thus incorrectly update both with the details for whichever device is processed second. Add a check on device type to prevent this. Port from the Kata 1 Go agent https://github.com/kata-containers/agent/commit/27ebdc9d2761 Fixes: #703 Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
859301b009
commit
ae6b8ec747
@ -345,7 +345,10 @@ impl DevIndex {
|
|||||||
|
|
||||||
for linuxres in linux.resources.as_ref() {
|
for linuxres in linux.resources.as_ref() {
|
||||||
for (j, r) in linuxres.devices.iter().enumerate() {
|
for (j, r) in linuxres.devices.iter().enumerate() {
|
||||||
if r.major == Some(d.major) && r.minor == Some(d.minor) {
|
if r.r#type == d.r#type
|
||||||
|
&& r.major == Some(d.major)
|
||||||
|
&& r.minor == Some(d.minor)
|
||||||
|
{
|
||||||
residx.push(j);
|
residx.push(j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -639,4 +642,77 @@ mod tests {
|
|||||||
assert_eq!(Some(guest_major_b), specresources.devices[1].major);
|
assert_eq!(Some(guest_major_b), specresources.devices[1].major);
|
||||||
assert_eq!(Some(guest_minor_b), specresources.devices[1].minor);
|
assert_eq!(Some(guest_minor_b), specresources.devices[1].minor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_update_spec_device_list_char_block_conflict() {
|
||||||
|
let null_rdev = fs::metadata("/dev/null").unwrap().rdev();
|
||||||
|
|
||||||
|
let guest_major = stat::major(null_rdev) as i64;
|
||||||
|
let guest_minor = stat::minor(null_rdev) as i64;
|
||||||
|
let host_major: i64 = 99;
|
||||||
|
let host_minor: i64 = 99;
|
||||||
|
|
||||||
|
let mut spec = Spec {
|
||||||
|
linux: Some(Linux {
|
||||||
|
devices: vec![
|
||||||
|
oci::LinuxDevice {
|
||||||
|
path: "/dev/char".to_string(),
|
||||||
|
r#type: "c".to_string(),
|
||||||
|
major: host_major,
|
||||||
|
minor: host_minor,
|
||||||
|
..oci::LinuxDevice::default()
|
||||||
|
},
|
||||||
|
oci::LinuxDevice {
|
||||||
|
path: "/dev/block".to_string(),
|
||||||
|
r#type: "b".to_string(),
|
||||||
|
major: host_major,
|
||||||
|
minor: host_minor,
|
||||||
|
..oci::LinuxDevice::default()
|
||||||
|
},
|
||||||
|
],
|
||||||
|
resources: Some(LinuxResources {
|
||||||
|
devices: vec![
|
||||||
|
LinuxDeviceCgroup {
|
||||||
|
r#type: "c".to_string(),
|
||||||
|
major: Some(host_major),
|
||||||
|
minor: Some(host_minor),
|
||||||
|
..LinuxDeviceCgroup::default()
|
||||||
|
},
|
||||||
|
LinuxDeviceCgroup {
|
||||||
|
r#type: "b".to_string(),
|
||||||
|
major: Some(host_major),
|
||||||
|
minor: Some(host_minor),
|
||||||
|
..LinuxDeviceCgroup::default()
|
||||||
|
},
|
||||||
|
],
|
||||||
|
..LinuxResources::default()
|
||||||
|
}),
|
||||||
|
..Linux::default()
|
||||||
|
}),
|
||||||
|
..Spec::default()
|
||||||
|
};
|
||||||
|
let devidx = DevIndex::new(&spec);
|
||||||
|
|
||||||
|
let dev = Device {
|
||||||
|
container_path: "/dev/char".to_string(),
|
||||||
|
vm_path: "/dev/null".to_string(),
|
||||||
|
..Device::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let specresources = spec.linux.as_ref().unwrap().resources.as_ref().unwrap();
|
||||||
|
assert_eq!(Some(host_major), specresources.devices[0].major);
|
||||||
|
assert_eq!(Some(host_minor), specresources.devices[0].minor);
|
||||||
|
assert_eq!(Some(host_major), specresources.devices[1].major);
|
||||||
|
assert_eq!(Some(host_minor), specresources.devices[1].minor);
|
||||||
|
|
||||||
|
let res = update_spec_device_list(&dev, &mut spec, &devidx);
|
||||||
|
assert!(res.is_ok());
|
||||||
|
|
||||||
|
// Only the char device, not the block device should be updated
|
||||||
|
let specresources = spec.linux.as_ref().unwrap().resources.as_ref().unwrap();
|
||||||
|
assert_eq!(Some(guest_major), specresources.devices[0].major);
|
||||||
|
assert_eq!(Some(guest_minor), specresources.devices[0].minor);
|
||||||
|
assert_eq!(Some(host_major), specresources.devices[1].major);
|
||||||
|
assert_eq!(Some(host_minor), specresources.devices[1].minor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user