[Spice-devel] [PATCH spice-server v2 4/7] smartcard: Fix parsing multiple messages from the device
Frediano Ziglio
fziglio at redhat.com
Tue Oct 8 17:39:21 UTC 2019
If the server is busy or the guest write multiple requests with
a single operation it could happen that we receive multiple
requests with a single read.
This will make "remaining" > 0.
Use memmove instead of memcpy as the buffer can overlap if the
second request if bigger than the first.
"buf_pos" points to the point of the buffer after we read, if
we want the first part of the next request is "buf_pos - remaining".
Same consideration setting "buf_pos" for the next iteration.
Also check the loop condition. If the remaining buffer contains
a full request we don't need to read other bytes (note that there
could be no bytes left), just parse the request.
Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
server/smartcard.c | 27 ++++++++++++++++++---------
1 file changed, 18 insertions(+), 9 deletions(-)
diff --git a/server/smartcard.c b/server/smartcard.c
index 4c5bba07d..340118e18 100644
--- a/server/smartcard.c
+++ b/server/smartcard.c
@@ -130,19 +130,28 @@ static RedPipeItem *smartcard_read_msg_from_device(RedCharDevice *self,
RedCharDeviceSmartcard *dev = RED_CHAR_DEVICE_SMARTCARD(self);
SpiceCharDeviceInterface *sif = spice_char_device_get_interface(sin);
VSCMsgHeader *vheader = (VSCMsgHeader*)dev->priv->buf;
- int n;
int remaining;
int actual_length;
- while ((n = sif->read(sin, dev->priv->buf_pos, dev->priv->buf_size - dev->priv->buf_used)) > 0) {
+ while (true) {
RedMsgItem *msg_to_client;
- dev->priv->buf_pos += n;
- dev->priv->buf_used += n;
- if (dev->priv->buf_used < sizeof(VSCMsgHeader)) {
- continue;
+ // it's possible we already got a full message from a previous partial
+ // read. In this case we don't need to read any byte
+ if (dev->priv->buf_used < sizeof(VSCMsgHeader) ||
+ dev->priv->buf_used - sizeof(VSCMsgHeader) < ntohl(vheader->length)) {
+ int n = sif->read(sin, dev->priv->buf_pos, dev->priv->buf_size - dev->priv->buf_used);
+ if (n <= 0) {
+ break;
+ }
+ dev->priv->buf_pos += n;
+ dev->priv->buf_used += n;
+
+ if (dev->priv->buf_used < sizeof(VSCMsgHeader)) {
+ continue;
+ }
+ smartcard_read_buf_prepare(dev, vheader);
}
- smartcard_read_buf_prepare(dev, vheader);
actual_length = ntohl(vheader->length);
if (dev->priv->buf_used - sizeof(VSCMsgHeader) < actual_length) {
continue;
@@ -150,9 +159,9 @@ static RedPipeItem *smartcard_read_msg_from_device(RedCharDevice *self,
msg_to_client = smartcard_char_device_on_message_from_device(dev, vheader);
remaining = dev->priv->buf_used - sizeof(VSCMsgHeader) - actual_length;
if (remaining > 0) {
- memcpy(dev->priv->buf, dev->priv->buf_pos, remaining);
+ memmove(dev->priv->buf, dev->priv->buf_pos - remaining, remaining);
}
- dev->priv->buf_pos = dev->priv->buf;
+ dev->priv->buf_pos = dev->priv->buf + remaining;
dev->priv->buf_used = remaining;
if (msg_to_client) {
return &msg_to_client->base;
--
2.21.0
More information about the Spice-devel
mailing list