In the Linux kernel, the following vulnerability has been resolved:
accel/qaic: Clean up integer overflow checking in mapuserpages()
The encodedma() function has some validation on intrans->size but it would be more clear to move those checks to findandmapuserpages().
The encode_dma() had two checks:
if (in_trans->addr + in_trans->size < in_trans->addr || !in_trans->size)
return -EINVAL;
The intrans->addr variable is the starting address. The intrans->size variable is the total size of the transfer. The transfer can occur in parts and the resources->xferreddmasize tracks how many bytes we have already transferred.
This patch introduces a new variable "remaining" which represents the amount we want to transfer (intrans->size) minus the amount we have already transferred (resources->xferreddma_size).
I have modified the check for if intrans->size is zero to instead check if intrans->size is less than resources->xferreddmasize. If we have already transferred more bytes than in_trans->size then there are negative bytes remaining which doesn't make sense. If there are zero bytes remaining to be copied, just return success.
The check in encodedma() checked that "addr + size" could not overflow and barring a driver bug that should work, but it's easier to check if we do this in parts. First check that "intrans->addr + resources->xferreddmasize" is safe. Then check that "xferstartaddr + remaining" is safe.
My final concern was that we are dealing with u64 values but on 32bit systems the kmalloc() function will truncate the sizes to 32 bits. So I calculated "total = intrans->size + offsetinpage(xferstartaddr);" and returned -EINVAL if it were >= SIZEMAX. This will not affect 64bit systems.
{
"osv_generated_from": "https://github.com/CVEProject/cvelistV5/tree/main/cves/2023/53xxx/CVE-2023-53778.json",
"cna_assigner": "Linux"
}