In the Linux kernel, the following vulnerability has been resolved:
vfio/type1: fix cap_migration information leak
Fix an information leak where an uninitialized hole in struct vfioiommutype1infocap_migration on the stack is exposed to userspace.
The definition of struct vfioiommutype1infocap_migration contains a hole as shown in this pahole(1) output:
struct vfioiommutype1infocapmigration { struct vfioinfocapheader header; /* 0 8 / __u32 flags; / 8 4 */
/* XXX 4 bytes hole, try to pack */
__u64 pgsize_bitmap; /* 16 8 */
__u64 max_dirty_bitmap_size; /* 24 8 */
/* size: 32, cachelines: 1, members: 4 */
/* sum members: 28, holes: 1, sum holes: 4 */
/* last cacheline: 32 bytes */
};
The cap_mig variable is filled in without initializing the hole:
static int vfioiommumigrationbuildcaps(struct vfioiommu *iommu, struct vfioinfocap *caps) { struct vfioiommutype1infocapmigration cap_mig;
cap_mig.header.id = VFIO_IOMMU_TYPE1_INFO_CAP_MIGRATION;
cap_mig.header.version = 1;
cap_mig.flags = 0;
/* support minimum pgsize */
cap_mig.pgsize_bitmap = (size_t)1 << __ffs(iommu->pgsize_bitmap);
cap_mig.max_dirty_bitmap_size = DIRTY_BITMAP_SIZE_MAX;
return vfio_info_add_capability(caps, &cap_mig.header, sizeof(cap_mig));
}
The structure is then copied to a temporary location on the heap. At this point it's already too late and ioctl(VFIOIOMMUGET_INFO) copies it to userspace later:
int vfioinfoaddcapability(struct vfioinfocap *caps, struct vfioinfocapheader *cap, sizet size) { struct vfioinfocapheader *header;
header = vfio_info_cap_add(caps, size, cap->id, cap->version);
if (IS_ERR(header))
return PTR_ERR(header);
memcpy(header + 1, cap + 1, size - sizeof(*header));
return 0;
}
This issue was found by code inspection.
{
"cna_assigner": "Linux",
"osv_generated_from": "https://github.com/CVEProject/cvelistV5/tree/main/cves/2023/54xxx/CVE-2023-54137.json"
}