From: VMware, Inc <> Date: Wed, 18 Sep 2013 03:27:51 +0000 (-0700) Subject: HGFS: Server packet abstraction part XI X-Git-Tag: 2013.09.16-1328054~63 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9f3ea592f1651fc43c715bf2c74499bf63b47ab7;p=thirdparty%2Fopen-vm-tools.git HGFS: Server packet abstraction part XI Deal with the broken reply packet part of the abstraction. Fix the get reply packet function call to separate out the reply data size passed in and the reply packet buffer size which is returned. Add the reply data size field in the HgfsPacket object so that the reply data size and reply buffer size can be separated out and not overloaded. This allows the transport channel send routines to extract the reply details from the packet object and not need the buffer and size arguments. The send function channel callback API will be cleaned up in a separate change. The get reply function for the packet now sets the meta packet data size too when it is used for the reply packet. This is used by the VMCI channel which now only maps and copies the correct amount of reply data into the guest VM shared memory. The reply packet size is randomly overwritten from the total packet size available for the reply to hold the amount of written data in the reply. This however, does not have any effect, since, the reply data size is passed to the send function which then knows how much data to send, and for VMCI, the meta part of the packet is used to transfer data to the guest shared memory so the reply part is essentially unused. This is now deleted. Signed-off-by: Dmitry Torokhov --- diff --git a/open-vm-tools/lib/hgfsServer/hgfsServer.c b/open-vm-tools/lib/hgfsServer/hgfsServer.c index 71ab60626..1b670cbb6 100644 --- a/open-vm-tools/lib/hgfsServer/hgfsServer.c +++ b/open-vm-tools/lib/hgfsServer/hgfsServer.c @@ -3140,9 +3140,10 @@ HgfsServerCompleteRequest(HgfsInternalStatus status, // IN: Status of the requ } } - replyTotalSize = replySize; - reply = HSPU_GetReplyPacket(input->packet, &replyTotalSize, - input->transportSession->channelCbTable); + reply = HSPU_GetReplyPacket(input->packet, + input->transportSession->channelCbTable, + replySize, + &replyTotalSize); ASSERT_DEVEL(reply && (replySize <= replyTotalSize)); if (!HgfsPackReplyHeader(status, replyPayloadSize, input->sessionEnabled, replySessionId, @@ -4587,11 +4588,10 @@ HgfsPacketSend(HgfsPacket *packet, // IN/OUT: Hgfs Packet ASSERT(transportSession); if (transportSession->state == HGFS_SESSION_STATE_OPEN) { - packet->replyPacketSize = packetOutLen; ASSERT(transportSession->type == HGFS_SESSION_TYPE_REGULAR); result = transportSession->channelCbTable->send(transportSession->transportData, - packet, packetOut, - packetOutLen, flags); + packet, packetOut, + packetOutLen, flags); } if (notificationNeeded) { @@ -5803,10 +5803,10 @@ HgfsAllocInitReply(HgfsPacket *packet, // IN/OUT: Hgfs Packet request->op > HGFS_OP_RENAME_V2) { headerSize = sizeof(HgfsReply); } - replyPacketSize = headerSize + replyDataSize; replyHeader = HSPU_GetReplyPacket(packet, - &replyPacketSize, - session->transportSession->channelCbTable); + session->transportSession->channelCbTable, + headerSize + replyDataSize, + &replyPacketSize); ASSERT_DEVEL(replyHeader && (replyPacketSize >= headerSize + replyDataSize)); diff --git a/open-vm-tools/lib/hgfsServer/hgfsServerInt.h b/open-vm-tools/lib/hgfsServer/hgfsServerInt.h index 6088b1fbc..088f933bd 100644 --- a/open-vm-tools/lib/hgfsServer/hgfsServerInt.h +++ b/open-vm-tools/lib/hgfsServer/hgfsServerInt.h @@ -839,8 +839,9 @@ HSPU_PutMetaPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet void * HSPU_GetReplyPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet - size_t *replyPacketSize, //IN/OUT: Size of reply Packet - HgfsServerChannelCallbacks *chanCb); // IN: Channel callbacks + HgfsServerChannelCallbacks *chanCb, // IN: Channel callbacks + size_t replyDataSize, // IN: Size of reply data + size_t *replyPacketSize); // OUT: Size of reply Packet void HSPU_PutReplyPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet diff --git a/open-vm-tools/lib/hgfsServer/hgfsServerPacketUtil.c b/open-vm-tools/lib/hgfsServer/hgfsServerPacketUtil.c index 73b015f74..0395bf079 100644 --- a/open-vm-tools/lib/hgfsServer/hgfsServerPacketUtil.c +++ b/open-vm-tools/lib/hgfsServer/hgfsServerPacketUtil.c @@ -92,17 +92,19 @@ static void HSPUUnmapBuf(HgfsChannelUnmapVirtAddrFunc unmapVa, void * HSPU_GetReplyPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet - size_t *replyPacketSize, // IN/OUT: Size of reply Packet - HgfsServerChannelCallbacks *chanCb) // IN: Channel callbacks + HgfsServerChannelCallbacks *chanCb, // IN: Channel callbacks + size_t replyDataSize, // IN: Size of reply data + size_t *replyPacketSize) // OUT: Size of reply Packet { if (packet->replyPacket != NULL) { /* * When we are transferring packets over backdoor, reply packet * is a static buffer. Backdoor should always return from here. */ + packet->replyPacketDataSize = replyDataSize; LOG(4, ("Existing reply packet %s %"FMTSZ"u %"FMTSZ"u\n", __FUNCTION__, - *replyPacketSize, packet->replyPacketSize)); - ASSERT_DEVEL(*replyPacketSize <= packet->replyPacketSize); + replyDataSize, packet->replyPacketSize)); + ASSERT_DEVEL(replyDataSize <= packet->replyPacketSize); } else if (chanCb != NULL && chanCb->getWriteVa != NULL) { /* Can we write directly into guest memory? */ ASSERT_DEVEL(packet->metaPacket != NULL); @@ -116,20 +118,30 @@ HSPU_GetReplyPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet * is always mapped and copied no matter how much data it really contains. */ LOG(10, ("%s Using meta packet for reply packet\n", __FUNCTION__)); - ASSERT_DEVEL(*replyPacketSize <= packet->metaPacketDataSize); + ASSERT_DEVEL(replyDataSize <= packet->metaPacketDataSize); ASSERT_DEVEL(BUF_READWRITEABLE == packet->metaMappingType); - ASSERT_DEVEL(*replyPacketSize <= packet->metaPacketSize); + ASSERT_DEVEL(replyDataSize <= packet->metaPacketSize); packet->replyPacket = packet->metaPacket; - packet->replyPacketSize = packet->metaPacketDataSize; + packet->replyPacketDataSize = replyDataSize; + packet->replyPacketSize = packet->metaPacketSize; packet->replyPacketIsAllocated = FALSE; + /* + * The reply is using the meta buffer so update the valid data size. + * + * Note, currently We know the reply size is going to be less than the + * incoming request valid data size. This will updated when that part is + * fixed. See the above comment about the assumptions and asserts. + */ + packet->metaPacketDataSize = packet->replyPacketDataSize; } } else { /* For sockets channel we always need to allocate buffer */ LOG(10, ("%s Allocating reply packet\n", __FUNCTION__)); - packet->replyPacket = Util_SafeMalloc(*replyPacketSize); + packet->replyPacket = Util_SafeMalloc(replyDataSize); packet->replyPacketIsAllocated = TRUE; - packet->replyPacketSize = *replyPacketSize; + packet->replyPacketDataSize = replyDataSize; + packet->replyPacketSize = replyDataSize; } *replyPacketSize = packet->replyPacketSize; diff --git a/open-vm-tools/lib/hgfsServerManagerGuest/hgfsChannelGuestBd.c b/open-vm-tools/lib/hgfsServerManagerGuest/hgfsChannelGuestBd.c index d7ff8cd45..52c023693 100644 --- a/open-vm-tools/lib/hgfsServerManagerGuest/hgfsChannelGuestBd.c +++ b/open-vm-tools/lib/hgfsServerManagerGuest/hgfsChannelGuestBd.c @@ -633,23 +633,22 @@ HgfsChannelGuestBdInvalidateInactiveSessions(HgfsGuestConn *connData) // IN: co static Bool HgfsChannelGuestBdSend(void *conn, // IN: our connection data HgfsPacket *packet, // IN/OUT: Hgfs Packet - char *buffer, // IN: buffer to be sent - size_t bufferLen, // IN: buffer length + char *buffer, // IN: unused reply in hgfs packet + size_t bufferLen, // IN: unused reply len in hgfs packet HgfsSendFlags flags) // IN: Flags to say how to process { HgfsGuestConn *connData = conn; ASSERT(NULL != connData); ASSERT(NULL != packet); - ASSERT(NULL != buffer); - ASSERT(bufferLen <= HGFS_LARGE_PACKET_MAX && - bufferLen <= packet->replyPacketSize); + ASSERT(NULL != packet->replyPacket); + ASSERT(packet->replyPacketDataSize <= connData->packetOutLen); + ASSERT(packet->replyPacketSize == connData->packetOutLen); - ASSERT(bufferLen <= connData->packetOutLen); - if (bufferLen > connData->packetOutLen) { - bufferLen = connData->packetOutLen; + if (packet->replyPacketDataSize > connData->packetOutLen) { + packet->replyPacketDataSize = connData->packetOutLen; } - connData->packetOutLen = (uint32)bufferLen; + connData->packetOutLen = (uint32)packet->replyPacketDataSize; if (!(flags & HGFS_SEND_NO_COMPLETE)) { connData->serverCbTable->sendComplete(packet, diff --git a/open-vm-tools/lib/include/hgfsServer.h b/open-vm-tools/lib/include/hgfsServer.h index 818623bdd..40956b3d0 100644 --- a/open-vm-tools/lib/include/hgfsServer.h +++ b/open-vm-tools/lib/include/hgfsServer.h @@ -75,6 +75,7 @@ typedef struct HgfsPacket { void *replyPacket; size_t replyPacketSize; + size_t replyPacketDataSize; Bool replyPacketIsAllocated; /* Iov for the packet private to the channel. */