This is not related to your patch, but can the "msg->iova + msg->size"
addition can have an integer overflow. From looking at the callers it
seems like it can. msg comes from:
vhost_chr_write_iter()
--> dev->msg_handler(dev, &msg);
--> vhost_vdpa_process_iotlb_msg()
--> vhost_vdpa_process_iotlb_update()
If I'm thinking of the right thing then these are allowed to overflow to
0 because of the " - 1" but not further than that. I believe the check
needs to be something like:
if (msg->iova < v->range.first ||
msg->iova - 1 > U64_MAX - msg->size ||
msg->iova + msg->size - 1 > v->range.last)
But writing integer overflow check correctly is notoriously difficult.
Do you think you could send a fix for that which is separate from the
patcheset? We'd want to backport it to stable.
regards,
dan carpenter
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
This is not related to your patch, but can the "msg->iova + msg->size"
addition can have an integer overflow. From looking at the callers it
seems like it can. msg comes from:
vhost_chr_write_iter()
--> dev->msg_handler(dev, &msg);
--> vhost_vdpa_process_iotlb_msg()
--> vhost_vdpa_process_iotlb_update()
Yes.
If I'm thinking of the right thing then these are allowed to overflow to
0 because of the " - 1" but not further than that. I believe the check
needs to be something like:
if (msg->iova < v->range.first ||
msg->iova - 1 > U64_MAX - msg->size ||
I guess we don't need - 1 here?
Thanks
msg->iova + msg->size - 1 > v->range.last)
But writing integer overflow check correctly is notoriously difficult.
Do you think you could send a fix for that which is separate from the
patcheset? We'd want to backport it to stable.
regards,
dan carpenter
This is not related to your patch, but can the "msg->iova + msg->size"
addition can have an integer overflow. From looking at the callers it
seems like it can. msg comes from:
vhost_chr_write_iter()
--> dev->msg_handler(dev, &msg);
--> vhost_vdpa_process_iotlb_msg()
--> vhost_vdpa_process_iotlb_update()
Yes.
quoted
If I'm thinking of the right thing then these are allowed to overflow to
0 because of the " - 1" but not further than that. I believe the check
needs to be something like:
if (msg->iova < v->range.first ||
msg->iova - 1 > U64_MAX - msg->size ||
I guess we don't need - 1 here?
The - 1 is important. The highest address is 0xffffffff. So it goes
start + size = 0 and then start + size - 1 == 0xffffffff.
I guess we could move the - 1 to the other side?
msg->iova > U64_MAX - msg->size + 1 ||
regards,
dan carpenter
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
This is not related to your patch, but can the "msg->iova + msg->size"
addition can have an integer overflow. From looking at the callers it
seems like it can. msg comes from:
vhost_chr_write_iter()
--> dev->msg_handler(dev, &msg);
--> vhost_vdpa_process_iotlb_msg()
--> vhost_vdpa_process_iotlb_update()
Yes.
quoted
If I'm thinking of the right thing then these are allowed to overflow to
0 because of the " - 1" but not further than that. I believe the check
needs to be something like:
if (msg->iova < v->range.first ||
msg->iova - 1 > U64_MAX - msg->size ||
I guess we don't need - 1 here?
The - 1 is important. The highest address is 0xffffffff. So it goes
start + size = 0 and then start + size - 1 == 0xffffffff.
Right, so actually
msg->iova = 0xfffffffe, msg->size=2 is valid.
Thanks
I guess we could move the - 1 to the other side?
msg->iova > U64_MAX - msg->size + 1 ||
regards,
dan carpenter
This is not related to your patch, but can the "msg->iova + msg->size"
addition can have an integer overflow. From looking at the callers it
seems like it can. msg comes from:
vhost_chr_write_iter()
--> dev->msg_handler(dev, &msg);
--> vhost_vdpa_process_iotlb_msg()
--> vhost_vdpa_process_iotlb_update()
Yes.
quoted
If I'm thinking of the right thing then these are allowed to overflow to
0 because of the " - 1" but not further than that. I believe the check
needs to be something like:
if (msg->iova < v->range.first ||
msg->iova - 1 > U64_MAX - msg->size ||
I guess we don't need - 1 here?
The - 1 is important. The highest address is 0xffffffff. So it goes
start + size = 0 and then start + size - 1 == 0xffffffff.
Right, so actually
msg->iova = 0xfffffffe, msg->size=2 is valid.
I believe so, yes. It's inclusive of 0xfffffffe and 0xffffffff.
(Not an expert).
regards,
dan carpenter
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
This is not related to your patch, but can the "msg->iova + msg->size"
addition can have an integer overflow. From looking at the callers it
seems like it can. msg comes from:
vhost_chr_write_iter()
--> dev->msg_handler(dev, &msg);
--> vhost_vdpa_process_iotlb_msg()
--> vhost_vdpa_process_iotlb_update()
Yes.
quoted
If I'm thinking of the right thing then these are allowed to overflow to
0 because of the " - 1" but not further than that. I believe the check
needs to be something like:
if (msg->iova < v->range.first ||
msg->iova - 1 > U64_MAX - msg->size ||
I guess we don't need - 1 here?
The - 1 is important. The highest address is 0xffffffff. So it goes
start + size = 0 and then start + size - 1 == 0xffffffff.
Right, so actually
msg->iova = 0xfffffffe, msg->size=2 is valid.
I believe so, yes. It's inclusive of 0xfffffffe and 0xffffffff.
(Not an expert).
I think so, and we probably need to fix vhost_overflow() as well which did:
static bool vhost_overflow(u64 uaddr, u64 size)
{
/* Make sure 64 bit math will not overflow. */
return uaddr > ULONG_MAX || size > ULONG_MAX || uaddr >
ULONG_MAX - size;
}
Thanks