From: Oliver Kurth Date: Wed, 27 Feb 2019 22:39:55 +0000 (-0800) Subject: GCC 9 caught several misaligned accesses and a format overflow. X-Git-Tag: stable-11.0.0~184 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c68172ef7f2d4f116078e2aba82986a8cab0b16e;p=thirdparty%2Fopen-vm-tools.git GCC 9 caught several misaligned accesses and a format overflow. GCC 9 generated several instances of "Werror=address-of-packed-member" in HGFS Fuse support code and hgfsmounter. There is also one instance of "Werror=format-overflow" generated in util_misc.c. According to stackoverflow discussion - https://stackoverflow.com/questions/8568432/is-gccs-attribute-packed-pragma-pack-unsafe, x86 hardware handles misaligned access and does not exhibit any real issues. However, GCC 9 generates misaligned access warning ("Werror=address-of-packed-member) for all architectures. In case of open-vm-tools build we treat warnings as errors and also we want code to be as portable as possible in general unless there is a reason not to do so. --- diff --git a/open-vm-tools/hgfsmounter/hgfsmounter.c b/open-vm-tools/hgfsmounter/hgfsmounter.c index 0921b700b..3f6798dc4 100644 --- a/open-vm-tools/hgfsmounter/hgfsmounter.c +++ b/open-vm-tools/hgfsmounter/hgfsmounter.c @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2006-2017 VMware, Inc. All rights reserved. + * Copyright (C) 2006-2019 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -514,11 +514,13 @@ ParseFmask(const char *option, // IN: option string along with value HgfsMountInfo *mountInfo, // OUT: mount data int *flags) // OUT: mount flags { + unsigned short fmask = 0; ASSERT(option); ASSERT(mountInfo); - if (ParseMask(option, &mountInfo->fmask)) { - LOG("Setting mount fmask to %o\n", mountInfo->fmask); + if (ParseMask(option, &fmask)) { + LOG("Setting mount fmask to %o\n", fmask); + mountInfo->fmask = fmask; return TRUE; } @@ -548,11 +550,13 @@ ParseDmask(const char *option, // IN: option string along with value HgfsMountInfo *mountInfo, // OUT: mount data int *flags) // OUT: mount flags { + unsigned short dmask = 0; ASSERT(option); ASSERT(mountInfo); - if (ParseMask(option, &mountInfo->dmask)) { - LOG("Setting mount dmask to %o\n", mountInfo->dmask); + if (ParseMask(option, &dmask)) { + LOG("Setting mount dmask to %o\n", dmask); + mountInfo->dmask = dmask; return TRUE; } diff --git a/open-vm-tools/lib/hgfsServer/hgfsServer.c b/open-vm-tools/lib/hgfsServer/hgfsServer.c index b335bbbc3..295ab3c3f 100644 --- a/open-vm-tools/lib/hgfsServer/hgfsServer.c +++ b/open-vm-tools/lib/hgfsServer/hgfsServer.c @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 1998-2018 VMware, Inc. All rights reserved. + * Copyright (C) 1998-2019 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -6536,11 +6536,13 @@ HgfsServerRead(HgfsInputParam *input) // IN: Input params payload = &reply->payload[0]; } if (payload) { + uint32 actualSize = 0; status = HgfsPlatformReadFile(readFd, input->session, offset, requiredSize, payload, - &reply->actualSize); + &actualSize); if (HGFS_ERROR_SUCCESS == status) { reply->reserved = 0; + reply->actualSize = actualSize; replyPayloadSize = sizeof *reply; if (readUseDataBuffer) { @@ -6556,11 +6558,13 @@ HgfsServerRead(HgfsInputParam *input) // IN: Input params break; } case HGFS_OP_READ: { + uint32 actualSize = 0; HgfsReplyRead *reply = replyRead; status = HgfsPlatformReadFile(readFd, input->session, offset, requiredSize, - reply->payload, &reply->actualSize); + reply->payload, &actualSize); if (HGFS_ERROR_SUCCESS == status) { + reply->actualSize = actualSize; replyPayloadSize = sizeof *reply + reply->actualSize; } else { LOG(4, ("%s: V1 Failed to read-> %d.\n", __FUNCTION__, status)); diff --git a/open-vm-tools/lib/misc/util_misc.c b/open-vm-tools/lib/misc/util_misc.c index 198c23d2c..de671a07e 100644 --- a/open-vm-tools/lib/misc/util_misc.c +++ b/open-vm-tools/lib/misc/util_misc.c @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 1998-2018 VMware, Inc. All rights reserved. + * Copyright (C) 1998-2019 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -719,8 +719,8 @@ Util_ExpandString(const char *fileName) // IN file path to expand ASSERT(!freeChunk[i]); chunks[i] = expand; if (chunks[i] == NULL) { - Log("%s: Cannot allocate memory to expand \"%s\" in \"%s\".\n", - __FUNCTION__, expand, fileName); + Log("%s: Cannot allocate memory to expand $ in \"%s\".\n", + __FUNCTION__, fileName); goto out; } chunkSize[i] = strlen(expand); diff --git a/open-vm-tools/vmhgfs-fuse/dir.c b/open-vm-tools/vmhgfs-fuse/dir.c index 6298a4ea3..e71b7afd8 100644 --- a/open-vm-tools/vmhgfs-fuse/dir.c +++ b/open-vm-tools/vmhgfs-fuse/dir.c @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2013 VMware, Inc. All rights reserved. + * Copyright (C) 2013,2019 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -54,38 +54,53 @@ HgfsPackDirOpenRequest(const char *path, // IN: Path of the dir to open HgfsOp opUsed, // IN: Op to be used HgfsReq *req) // IN/OUT: Packet to write into { - char *name; - unsigned int *nameLength = NULL; size_t reqSize; - int result; ASSERT(path); ASSERT(req); LOG(4, ("Path = %s \n", path)); switch (opUsed) { case HGFS_OP_SEARCH_OPEN_V3: { + int result; HgfsRequestSearchOpenV3 *requestV3 = HgfsGetRequestPayload(req); - /* We'll use these later. */ - name = requestV3->dirName.name; - nameLength = &requestV3->dirName.length; requestV3->dirName.flags = 0; requestV3->dirName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; requestV3->dirName.fid = HGFS_INVALID_HANDLE; requestV3->reserved = 0; reqSize = sizeof(*requestV3) + HgfsGetRequestHeaderSize(); + /* Convert to CP name. */ + result = CPName_ConvertTo(path, + HGFS_LARGE_PACKET_MAX - (reqSize - 1), + requestV3->dirName.name); + if (result < 0) { + LOG(4, ("CP conversion failed\n")); + return -EINVAL; + } + LOG(4, ("After conversion = %s\n", requestV3->dirName.name)); + requestV3->dirName.length = result; + reqSize += result; break; } case HGFS_OP_SEARCH_OPEN: { + int result; HgfsRequestSearchOpen *request; request = (HgfsRequestSearchOpen *)(HGFS_REQ_PAYLOAD(req)); - /* We'll use these later. */ - name = request->dirName.name; - nameLength = &request->dirName.length; reqSize = sizeof *request; + /* Convert to CP name. */ + result = CPName_ConvertTo(path, + HGFS_LARGE_PACKET_MAX - (reqSize - 1), + request->dirName.name); + if (result < 0) { + LOG(4, ("CP conversion failed\n")); + return -EINVAL; + } + LOG(4, ("After conversion = %s\n", request->dirName.name)); + request->dirName.length = result; + reqSize += result; break; } @@ -94,21 +109,7 @@ HgfsPackDirOpenRequest(const char *path, // IN: Path of the dir to open return -EPROTO; } - /* Convert to CP name. */ - - LOG(4, ("After buildPath = %s\n", path)); - result = CPName_ConvertTo(path, - HGFS_LARGE_PACKET_MAX - (reqSize - 1), - name); - if (result < 0) { - LOG(4, ("CP conversion failed\n")); - return -EINVAL; - } - - LOG(4, ("After conversion = %s\n", name)); - - *nameLength = (uint32) result; - req->payloadSize = reqSize + result; + req->payloadSize = reqSize; /* Fill in header here as payloadSize needs to be there. */ HgfsPackHeader(req, opUsed); @@ -149,7 +150,6 @@ HgfsDirOpen(const char* path, // IN: Path of dir to open int result; HgfsOp opUsed; HgfsStatus replyStatus; - HgfsHandle *replySearch; ASSERT(path); req = HgfsGetNewRequest(); @@ -161,16 +161,6 @@ HgfsDirOpen(const char* path, // IN: Path of dir to open retry: opUsed = hgfsVersionSearchOpen; - if (opUsed == HGFS_OP_SEARCH_OPEN_V3) { - HgfsReplySearchOpenV3 *requestV3 = HgfsGetReplyPayload(req); - - replySearch = &requestV3->search; - - } else { - HgfsReplySearchOpen *request = (HgfsReplySearchOpen *)HGFS_REQ_PAYLOAD(req); - - replySearch = &request->search; - } result = HgfsPackDirOpenRequest(path, opUsed, req); if (result != 0) { @@ -187,8 +177,14 @@ retry: switch (result) { case 0: - *handle = *replySearch; - LOG(6, ("Set handle to %u\n", *replySearch)); + if (opUsed == HGFS_OP_SEARCH_OPEN_V3) { + HgfsReplySearchOpenV3 *requestV3 = HgfsGetReplyPayload(req); + *handle = requestV3->search; + } else { + HgfsReplySearchOpen *request = (HgfsReplySearchOpen *)HGFS_REQ_PAYLOAD(req); + *handle = request->search; + } + LOG(6, ("Set handle to %u\n", *handle)); break; case -EPROTO: /* Retry with older version(s). Set globally. */ @@ -626,25 +622,30 @@ HgfsPackCreateDirRequest(const char *path, HgfsOp opUsed, // IN: Op to be used. HgfsReq *req) // IN/OUT: Packet to write into { - char *fileName = NULL; - uint32 *fileNameLength; size_t reqSize; - int result; + ASSERT(req); switch (opUsed) { case HGFS_OP_CREATE_DIR_V3: { + int result; HgfsRequestCreateDirV3 *requestV3 = HgfsGetRequestPayload(req); reqSize = sizeof(*requestV3) + HgfsGetRequestHeaderSize(); - /* We'll use these later. */ - fileName = requestV3->fileName.name; - fileNameLength = &requestV3->fileName.length; requestV3->fileName.flags = 0; requestV3->fileName.fid = HGFS_INVALID_HANDLE; requestV3->fileName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; - + /* Convert to CP name. */ + result = CPName_ConvertTo(path, + HGFS_LARGE_PACKET_MAX - (reqSize - 1), + requestV3->fileName.name); + if (result < 0) { + LOG(4, ("CP conversion failed.\n")); + return -EINVAL; + } + requestV3->fileName.length = result; + reqSize += result; requestV3->mask = HGFS_CREATE_DIR_MASK; /* Set permissions. */ @@ -656,15 +657,23 @@ HgfsPackCreateDirRequest(const char *path, break; } case HGFS_OP_CREATE_DIR_V2: { + int result; HgfsRequestCreateDirV2 *requestV2; requestV2 = (HgfsRequestCreateDirV2 *)(HGFS_REQ_PAYLOAD(req)); - /* We'll use these later. */ - fileName = requestV2->fileName.name; - fileNameLength = &requestV2->fileName.length; reqSize = sizeof *requestV2; + /* Convert to CP name. */ + result = CPName_ConvertTo(path, + HGFS_LARGE_PACKET_MAX - (reqSize - 1), + requestV2->fileName.name); + if (result < 0) { + LOG(4, ("CP conversion failed.\n")); + return -EINVAL; + } + requestV2->fileName.length = result; + reqSize += result; requestV2->mask = HGFS_CREATE_DIR_MASK; /* Set permissions. */ @@ -675,15 +684,22 @@ HgfsPackCreateDirRequest(const char *path, break; } case HGFS_OP_CREATE_DIR: { + int result; HgfsRequestCreateDir *request; request = (HgfsRequestCreateDir *)(HGFS_REQ_PAYLOAD(req)); - /* We'll use these later. */ - fileName = request->fileName.name; - fileNameLength = &request->fileName.length; reqSize = sizeof *request; - + /* Convert to CP name. */ + result = CPName_ConvertTo(path, + HGFS_LARGE_PACKET_MAX - (reqSize - 1), + request->fileName.name); + if (result < 0) { + LOG(4, ("CP conversion failed.\n")); + return -EINVAL; + } + request->fileName.length = result; + reqSize += result; /* Set permissions. */ request->permissions = (permsMode & S_IRWXU) >> 6; break; @@ -693,18 +709,7 @@ HgfsPackCreateDirRequest(const char *path, return -EPROTO; } - - /* Convert to CP name. */ - result = CPName_ConvertTo(path, - HGFS_LARGE_PACKET_MAX - (reqSize - 1), - fileName); - if (result < 0) { - LOG(4, ("CP conversion failed.\n")); - return -EINVAL; - } - - *fileNameLength = result; - req->payloadSize = reqSize + result; + req->payloadSize = reqSize; /* Fill in header here as payloadSize needs to be there. */ HgfsPackHeader(req, opUsed); @@ -827,8 +832,6 @@ HgfsDelete(const char* path, // IN: Path to file HgfsReq *req = NULL; int result = 0; HgfsStatus replyStatus; - char *fileName = NULL; - uint32 *fileNameLength; uint32 reqSize; HgfsOp opUsed; HgfsAttrInfo newAttr = {0}; @@ -862,8 +865,17 @@ HgfsDelete(const char* path, // IN: Path to file reqSize = sizeof(*request) + HgfsGetRequestHeaderSize(); request->hints = 0; - fileName = request->fileName.name; - fileNameLength = &request->fileName.length; + /* Convert to CP name. */ + result = CPName_ConvertTo(path, + HGFS_NAME_BUFFER_SIZET(HGFS_LARGE_PACKET_MAX, reqSize), + request->fileName.name); + if (result < 0) { + LOG(4, ("CP conversion failed.\n")); + result = -EINVAL; + goto out; + } + request->fileName.length = result; + reqSize += result; request->fileName.fid = HGFS_INVALID_HANDLE; request->fileName.flags = 0; request->fileName.caseType = HGFS_FILE_NAME_DEFAULT_CASE; @@ -874,24 +886,21 @@ HgfsDelete(const char* path, // IN: Path to file request = (HgfsRequestDelete *)(HGFS_REQ_PAYLOAD(req)); /* Fill out the request packet. */ - fileName = request->fileName.name; - fileNameLength = &request->fileName.length; reqSize = sizeof *request; + /* Convert to CP name. */ + result = CPName_ConvertTo(path, + HGFS_NAME_BUFFER_SIZET(HGFS_LARGE_PACKET_MAX, reqSize), + request->fileName.name); + if (result < 0) { + LOG(4, ("CP conversion failed.\n")); + result = -EINVAL; + goto out; + } + request->fileName.length = result; + reqSize += result; } - - /* Convert to CP name. */ - result = CPName_ConvertTo(path, - HGFS_NAME_BUFFER_SIZET(HGFS_LARGE_PACKET_MAX, reqSize), - fileName); - if (result < 0) { - LOG(4, ("CP conversion failed.\n")); - result = -EINVAL; - goto out; - } - - *fileNameLength = result; - req->payloadSize = reqSize + result; + req->payloadSize = reqSize; /* Fill in header here as payloadSize needs to be there. */ HgfsPackHeader(req, opUsed); diff --git a/open-vm-tools/vmhgfs-fuse/file.c b/open-vm-tools/vmhgfs-fuse/file.c index b0744ff76..0b6c48bce 100644 --- a/open-vm-tools/vmhgfs-fuse/file.c +++ b/open-vm-tools/vmhgfs-fuse/file.c @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2013,2018 VMware, Inc. All rights reserved. + * Copyright (C) 2013,2018-2019 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -66,10 +66,7 @@ HgfsPackOpenRequest(const char *path, // IN: Path to file HgfsOp opUsed, // IN: Op to use HgfsReq *req) // IN/OUT: Packet to write into { - char *name; - uint32 *nameLength; size_t reqSize; - int result; int openMode, openFlags; ASSERT(path); @@ -88,14 +85,22 @@ HgfsPackOpenRequest(const char *path, // IN: Path to file switch (opUsed) { case HGFS_OP_OPEN_V3: { + int result; HgfsRequestOpenV3 *requestV3 = HgfsGetRequestPayload(req); reqSize = sizeof(*requestV3) + HgfsGetRequestHeaderSize(); - /* We'll use these later. */ - name = requestV3->fileName.name; - nameLength = &requestV3->fileName.length; + /* Convert to CP name. */ + result = CPName_ConvertTo(path, + HGFS_LARGE_PACKET_MAX - (reqSize - 1), + requestV3->fileName.name); + if (result < 0) { + LOG(4, ("CP conversion failed.\n")); + return -EINVAL; + } + requestV3->fileName.length = result; + reqSize += result; /* Linux clients need case-sensitive lookups. */ requestV3->fileName.flags = 0; requestV3->fileName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; @@ -122,15 +127,24 @@ HgfsPackOpenRequest(const char *path, // IN: Path to file } case HGFS_OP_OPEN_V2: { + int result; HgfsRequestOpenV2 *requestV2; requestV2 = (HgfsRequestOpenV2 *)(HGFS_REQ_PAYLOAD(req)); - /* We'll use these later. */ - name = requestV2->fileName.name; - nameLength = &requestV2->fileName.length; reqSize = sizeof *requestV2; + /* Convert to CP name. */ + result = CPName_ConvertTo(path, + HGFS_LARGE_PACKET_MAX - (reqSize - 1), + requestV2->fileName.name); + if (result < 0) { + LOG(4, ("CP conversion failed.\n")); + return -EINVAL; + } + + requestV2->fileName.length = result; + reqSize += result; requestV2->mask = mask; requestV2->mode = openMode; requestV2->flags = openFlags; @@ -148,14 +162,23 @@ HgfsPackOpenRequest(const char *path, // IN: Path to file break; } case HGFS_OP_OPEN: { + int result; HgfsRequestOpen *request; request = (HgfsRequestOpen *)(HGFS_REQ_PAYLOAD(req)); - /* We'll use these later. */ - name = request->fileName.name; - nameLength = &request->fileName.length; reqSize = sizeof *request; + /* Convert to CP name. */ + result = CPName_ConvertTo(path, + HGFS_LARGE_PACKET_MAX - (reqSize - 1), + request->fileName.name); + if (result < 0) { + LOG(4, ("CP conversion failed.\n")); + return -EINVAL; + } + + request->fileName.length = result; + reqSize += result; request->mode = openMode; request->flags = openFlags; @@ -168,18 +191,7 @@ HgfsPackOpenRequest(const char *path, // IN: Path to file return -EPROTO; } - - /* Convert to CP name. */ - result = CPName_ConvertTo(path, - HGFS_LARGE_PACKET_MAX - (reqSize - 1), - name); - if (result < 0) { - LOG(4, ("CP conversion failed.\n")); - return -EINVAL; - } - - *nameLength = (uint32) result; - req->payloadSize = reqSize + result; + req->payloadSize = reqSize; /* Fill in header here as payloadSize needs to be there. */ HgfsPackHeader(req, opUsed); @@ -915,10 +927,6 @@ int HgfsRename(const char* from, const char* to) { HgfsReq *req = NULL; - char *oldName; - char *newName; - uint32 *oldNameLength; - uint32 *newNameLength; int result = 0; uint32 reqSize; HgfsOp opUsed; @@ -942,33 +950,41 @@ retry: if (opUsed == HGFS_OP_RENAME_V3) { HgfsRequestRenameV3 *requestV3 = HgfsGetRequestPayload(req); - oldName = requestV3->oldName.name; - oldNameLength = &requestV3->oldName.length; requestV3->hints = 0; requestV3->oldName.flags = 0; requestV3->oldName.fid = HGFS_INVALID_HANDLE; requestV3->oldName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; requestV3->reserved = 0; reqSize = sizeof(*requestV3) + HgfsGetRequestHeaderSize(); + /* Convert old name to CP format. */ + result = CPName_ConvertTo(from, + HGFS_NAME_BUFFER_SIZET(HGFS_LARGE_PACKET_MAX, reqSize), + requestV3->oldName.name); + if (result < 0) { + LOG(4, ("oldName CP conversion failed\n")); + result = -EINVAL; + goto out; + } + + requestV3->oldName.length = result; + reqSize += result; } else { HgfsRequestRename *request = (HgfsRequestRename *)HGFS_REQ_PAYLOAD(req); - oldName = request->oldName.name; - oldNameLength = &request->oldName.length; reqSize = sizeof *request; - } - /* Convert old name to CP format. */ - result = CPName_ConvertTo(from, - HGFS_NAME_BUFFER_SIZET(HGFS_LARGE_PACKET_MAX, reqSize), - oldName); - if (result < 0) { - LOG(4, ("oldName CP conversion failed\n")); - result = -EINVAL; - goto out; - } + /* Convert old name to CP format. */ + result = CPName_ConvertTo(from, + HGFS_NAME_BUFFER_SIZET(HGFS_LARGE_PACKET_MAX, reqSize), + request->oldName.name); + if (result < 0) { + LOG(4, ("oldName CP conversion failed\n")); + result = -EINVAL; + goto out; + } - *oldNameLength = result; - reqSize += result; + request->oldName.length = result; + reqSize += result; + } /* * Build full new name to send to server. @@ -983,8 +999,20 @@ retry: newNameP = (HgfsFileNameV3 *)((char *)&requestV3->oldName + sizeof requestV3->oldName + result); - newName = newNameP->name; - newNameLength = &newNameP->length; + + LOG(6, ("New name: \"%s\"\n", newNameP->name)); + + /* Convert new name to CP format. */ + result = CPName_ConvertTo(to, + HGFS_NAME_BUFFER_SIZET(HGFS_LARGE_PACKET_MAX, reqSize) - result, + newNameP->name); + if (result < 0) { + LOG(4, ("newName CP conversion failed\n")); + result = -EINVAL; + goto out; + } + newNameP->length = result; + reqSize += result; newNameP->flags = 0; newNameP->fid = HGFS_INVALID_HANDLE; newNameP->caseType = HGFS_FILE_NAME_CASE_SENSITIVE; @@ -993,24 +1021,22 @@ retry: HgfsFileName *newNameP; newNameP = (HgfsFileName *)((char *)&request->oldName + sizeof request->oldName + result); - newName = newNameP->name; - newNameLength = &newNameP->length; - } - LOG(6, ("New name: \"%s\"\n", newName)); + LOG(6, ("New name: \"%s\"\n", newNameP->name)); - /* Convert new name to CP format. */ - result = CPName_ConvertTo(to, - HGFS_NAME_BUFFER_SIZET(HGFS_LARGE_PACKET_MAX, reqSize) - result, - newName); - if (result < 0) { - LOG(4, ("newName CP conversion failed\n")); - result = -EINVAL; - goto out; + /* Convert new name to CP format. */ + result = CPName_ConvertTo(to, + HGFS_NAME_BUFFER_SIZET(HGFS_LARGE_PACKET_MAX, reqSize) - result, + newNameP->name); + if (result < 0) { + LOG(4, ("newName CP conversion failed\n")); + result = -EINVAL; + goto out; + } + newNameP->length = result; + reqSize += result; } - *newNameLength = result; - reqSize += result; req->payloadSize = reqSize; /* Fill in header here as payloadSize needs to be there. */ @@ -1109,21 +1135,17 @@ HgfsPackSetattrRequest(const char *path, // IN: path to file { HgfsAttrV2 *attrV2; HgfsAttr *attrV1; - HgfsAttrHint *hints; HgfsAttrChanges *update; - char *fileName = NULL; - uint32 *fileNameLength = NULL; size_t reqBufferSize; size_t reqSize; - int result = 0; ASSERT(req); switch (opUsed) { case HGFS_OP_SETATTR_V3: { + int result; HgfsRequestSetattrV3 *requestV3 = HgfsGetRequestPayload(req); attrV2 = &requestV3->attr; - hints = &requestV3->hints; /* * Clear attributes, mask, and hints before touching them. @@ -1131,7 +1153,7 @@ HgfsPackSetattrRequest(const char *path, // IN: path to file * make sure to zero them all here. */ memset(attrV2, 0, sizeof *attrV2); - memset(hints, 0, sizeof *hints); + requestV3->hints = 0; /* * When possible, issue a setattr using an existing handle. This will @@ -1143,14 +1165,21 @@ HgfsPackSetattrRequest(const char *path, // IN: path to file * the times also requires write permissions on Windows, so we require it * here too. Otherwise, any handle will do. */ - fileName = requestV3->fileName.name; - fileNameLength = &requestV3->fileName.length; requestV3->fileName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; requestV3->fileName.fid = HGFS_INVALID_HANDLE; requestV3->fileName.flags = 0; requestV3->reserved = 0; reqSize = sizeof(*requestV3) + HgfsGetRequestHeaderSize(); reqBufferSize = HGFS_NAME_BUFFER_SIZET(HGFS_LARGE_PACKET_MAX, reqSize); + result = CPName_ConvertTo(path, + reqBufferSize, + requestV3->fileName.name); + if (result < 0) { + LOG(4, ("CP conversion failed.\n")); + return -EINVAL; + } + requestV3->fileName.length = result; + reqSize += result; attrV2->mask = attr->mask; if (attr->mask & (HGFS_ATTR_VALID_SPECIAL_PERMS | @@ -1173,22 +1202,22 @@ HgfsPackSetattrRequest(const char *path, // IN: path to file } if (attr->mask & HGFS_ATTR_VALID_ACCESS_TIME) { attrV2->accessTime = attr->accessTime; - *hints |= HGFS_ATTR_HINT_SET_ACCESS_TIME; + requestV3->hints |= HGFS_ATTR_HINT_SET_ACCESS_TIME; } if (attr->mask & HGFS_ATTR_VALID_WRITE_TIME) { attrV2->writeTime = attr->writeTime; - *hints |= HGFS_ATTR_HINT_SET_WRITE_TIME; + requestV3->hints |= HGFS_ATTR_HINT_SET_WRITE_TIME; } break; } case HGFS_OP_SETATTR_V2: { + int result; HgfsRequestSetattrV2 *requestV2; requestV2 = (HgfsRequestSetattrV2 *)(HGFS_REQ_PAYLOAD(req)); attrV2 = &requestV2->attr; - hints = &requestV2->hints; /* * Clear attributes, mask, and hints before touching them. @@ -1196,13 +1225,19 @@ HgfsPackSetattrRequest(const char *path, // IN: path to file * make sure to zero them all here. */ memset(attrV2, 0, sizeof *attrV2); - memset(hints, 0, sizeof *hints); - - fileName = requestV2->fileName.name; - fileNameLength = &requestV2->fileName.length; + requestV2->hints = 0; reqSize = sizeof *requestV2; reqBufferSize = HGFS_NAME_BUFFER_SIZE(HGFS_LARGE_PACKET_MAX, requestV2); + result = CPName_ConvertTo(path, + reqBufferSize, + requestV2->fileName.name); + if (result < 0) { + LOG(4, ("CP conversion failed.\n")); + return -EINVAL; + } + requestV2->fileName.length = result; + reqSize += result; if (attr->mask & (HGFS_ATTR_VALID_SPECIAL_PERMS | HGFS_ATTR_VALID_OWNER_PERMS | @@ -1224,16 +1259,17 @@ HgfsPackSetattrRequest(const char *path, // IN: path to file } if (attr->mask & HGFS_ATTR_VALID_ACCESS_TIME) { attrV2->accessTime = attr->accessTime; - *hints |= HGFS_ATTR_HINT_SET_ACCESS_TIME; + requestV2->hints |= HGFS_ATTR_HINT_SET_ACCESS_TIME; } if (attr->mask & HGFS_ATTR_VALID_WRITE_TIME) { attrV2->writeTime = attr->writeTime; - *hints |= HGFS_ATTR_HINT_SET_WRITE_TIME; + requestV2->hints |= HGFS_ATTR_HINT_SET_WRITE_TIME; } break; } case HGFS_OP_SETATTR: { + int result; HgfsRequestSetattr *request; request = (HgfsRequestSetattr *)(HGFS_REQ_PAYLOAD(req)); @@ -1241,11 +1277,17 @@ HgfsPackSetattrRequest(const char *path, // IN: path to file attrV1 = &request->attr; update = &request->update; - /* We'll use these later. */ - fileName = request->fileName.name; - fileNameLength = &request->fileName.length; reqSize = sizeof *request; reqBufferSize = HGFS_NAME_BUFFER_SIZE(HGFS_LARGE_PACKET_MAX, request); + result = CPName_ConvertTo(path, + reqBufferSize, + request->fileName.name); + if (result < 0) { + LOG(4, ("CP conversion failed.\n")); + return -EINVAL; + } + request->fileName.length = result; + reqSize += result; /* * Clear attributes before touching them. @@ -1284,16 +1326,7 @@ HgfsPackSetattrRequest(const char *path, // IN: path to file return -EPROTO; } - result = CPName_ConvertTo(path, - reqBufferSize, - fileName); - if (result < 0) { - LOG(4, ("CP conversion failed.\n")); - return -EINVAL; - } - - *fileNameLength = result; - req->payloadSize = reqSize + result; + req->payloadSize = reqSize; /* Fill in header here as payloadSize needs to be there. */ HgfsPackHeader(req, opUsed); diff --git a/open-vm-tools/vmhgfs-fuse/filesystem.c b/open-vm-tools/vmhgfs-fuse/filesystem.c index fb9d547d0..1931a5d2e 100644 --- a/open-vm-tools/vmhgfs-fuse/filesystem.c +++ b/open-vm-tools/vmhgfs-fuse/filesystem.c @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2013 VMware, Inc. All rights reserved. + * Copyright (C) 2013,2019 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -123,36 +123,50 @@ HgfsPackQueryVolumeRequest(const char *path, // IN: File pointer for this HgfsOp opUsed, // IN: Op to be used. HgfsReq *req) // IN/OUT: Packet to write into { - char *name; - uint32 *nameLength; size_t requestSize; - int result; + ASSERT(req); switch (opUsed) { case HGFS_OP_QUERY_VOLUME_INFO_V3: { + int result; HgfsRequestQueryVolumeV3 *requestV3 = HgfsGetRequestPayload(req); - /* We'll use these later. */ - name = requestV3->fileName.name; - nameLength = &requestV3->fileName.length; requestV3->fileName.flags = 0; requestV3->fileName.fid = HGFS_INVALID_HANDLE; requestV3->fileName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; requestV3->reserved = 0; requestSize = sizeof(*requestV3) + HgfsGetRequestHeaderSize(); + /* Convert to CP name. */ + result = CPName_ConvertTo(path, + HGFS_LARGE_PACKET_MAX - (requestSize - 1), + requestV3->fileName.name); + if (result < 0) { + LOG(4, ("CP conversion failed.\n")); + return -EINVAL; + } + requestV3->fileName.length = result; + requestSize += result; break; } case HGFS_OP_QUERY_VOLUME_INFO: { + int result; HgfsRequestQueryVolume *request; request = (HgfsRequestQueryVolume *)(HGFS_REQ_PAYLOAD(req)); - /* We'll use these later. */ - name = request->fileName.name; - nameLength = &request->fileName.length; requestSize = sizeof *request; + /* Convert to CP name. */ + result = CPName_ConvertTo(path, + HGFS_LARGE_PACKET_MAX - (requestSize - 1), + request->fileName.name); + if (result < 0) { + LOG(4, ("CP conversion failed.\n")); + return -EINVAL; + } + request->fileName.length = result; + requestSize += result; break; } default: @@ -160,17 +174,7 @@ HgfsPackQueryVolumeRequest(const char *path, // IN: File pointer for this return -EPROTO; } - /* Convert to CP name. */ - result = CPName_ConvertTo(path, - HGFS_LARGE_PACKET_MAX - (requestSize - 1), - name); - if (result < 0) { - LOG(4, ("CP conversion failed.\n")); - return -EINVAL; - } - - *nameLength = (uint32) result; - req->payloadSize = requestSize + result; + req->payloadSize = requestSize; /* Fill in header here as payloadSize needs to be there. */ HgfsPackHeader(req, opUsed); diff --git a/open-vm-tools/vmhgfs-fuse/fsutil.c b/open-vm-tools/vmhgfs-fuse/fsutil.c index 042c223ca..af85c4051 100644 --- a/open-vm-tools/vmhgfs-fuse/fsutil.c +++ b/open-vm-tools/vmhgfs-fuse/fsutil.c @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2013 VMware, Inc. All rights reserved. + * Copyright (C) 2013,2019 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -189,8 +189,6 @@ HgfsPackGetattrRequest(HgfsReq *req, // IN/OUT: Request buffer size_t reqBufferSize; size_t reqSize; int result = 0; - char *fileName = NULL; - uint32 *fileNameLength = NULL; ASSERT(attr); ASSERT(req); ASSERT(path); @@ -204,8 +202,6 @@ HgfsPackGetattrRequest(HgfsReq *req, // IN/OUT: Request buffer /* Fill out the request packet. */ requestV3->hints = 0; - fileName = requestV3->fileName.name; - fileNameLength = &requestV3->fileName.length; requestV3->fileName.flags = 0; requestV3->fileName.fid = HGFS_INVALID_HANDLE; requestV3->fileName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; @@ -213,6 +209,19 @@ HgfsPackGetattrRequest(HgfsReq *req, // IN/OUT: Request buffer requestV3->reserved = 0; reqSize = sizeof(*requestV3) + HgfsGetRequestHeaderSize(); reqBufferSize = HGFS_NAME_BUFFER_SIZET(HGFS_LARGE_PACKET_MAX, reqSize); + if (requestV3->fileName.name != NULL) { + /* Convert to CP name. */ + result = CPName_ConvertTo(path, + reqBufferSize, + requestV3->fileName.name); + LOG(8, ("Converted path %s\n", requestV3->fileName.name)); + if (result < 0) { + LOG(8, ("CP conversion failed.\n")); + result = -EINVAL; + goto out; + } + requestV3->fileName.length = result; + } break; } @@ -223,20 +232,42 @@ HgfsPackGetattrRequest(HgfsReq *req, // IN/OUT: Request buffer requestV2 = (HgfsRequestGetattrV2 *)(HGFS_REQ_PAYLOAD(req)); requestV2->hints = 0; - fileName = requestV2->fileName.name; - fileNameLength = &requestV2->fileName.length; reqSize = sizeof *requestV2; reqBufferSize = HGFS_NAME_BUFFER_SIZE(HGFS_LARGE_PACKET_MAX, requestV2); + if (requestV2->fileName.name != NULL) { + /* Convert to CP name. */ + result = CPName_ConvertTo(path, + reqBufferSize, + requestV2->fileName.name); + LOG(8, ("Converted path %s\n", requestV2->fileName.name)); + if (result < 0) { + LOG(8, ("CP conversion failed.\n")); + result = -EINVAL; + goto out; + } + requestV2->fileName.length = result; + } break; } case HGFS_OP_GETATTR: { HgfsRequestGetattr *requestV1; requestV1 = (HgfsRequestGetattr *)(HGFS_REQ_PAYLOAD(req)); - fileName = requestV1->fileName.name; - fileNameLength = &requestV1->fileName.length; reqSize = sizeof *requestV1; reqBufferSize = HGFS_NAME_BUFFER_SIZE(HGFS_LARGE_PACKET_MAX, requestV1); + if (requestV1->fileName.name != NULL) { + /* Convert to CP name. */ + result = CPName_ConvertTo(path, + reqBufferSize, + requestV1->fileName.name); + LOG(8, ("Converted path %s\n", requestV1->fileName.name)); + if (result < 0) { + LOG(8, ("CP conversion failed.\n")); + result = -EINVAL; + goto out; + } + requestV1->fileName.length = result; + } break; } @@ -246,20 +277,6 @@ HgfsPackGetattrRequest(HgfsReq *req, // IN/OUT: Request buffer goto out; } - if (fileName != NULL) { - /* Convert to CP name. */ - result = CPName_ConvertTo(path, - reqBufferSize, - fileName); - LOG(8, ("Converted path %s\n", fileName)); - if (result < 0) { - LOG(8, ("CP conversion failed.\n")); - result = -EINVAL; - goto out; - } - *fileNameLength = result; - } - req->payloadSize = reqSize + result; /* Fill in header here as payloadSize needs to be there. */ diff --git a/open-vm-tools/vmhgfs-fuse/link.c b/open-vm-tools/vmhgfs-fuse/link.c index a00e84469..777eb76ea 100644 --- a/open-vm-tools/vmhgfs-fuse/link.c +++ b/open-vm-tools/vmhgfs-fuse/link.c @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2013 VMware, Inc. All rights reserved. + * Copyright (C) 2013,2019 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -51,36 +51,81 @@ HgfsPackSymlinkCreateRequest(const char* symlink, // IN: path of the link { HgfsRequestSymlinkCreateV3 *requestV3 = NULL; HgfsRequestSymlinkCreate *request = NULL; - char *symlinkName; - uint32 *symlinkNameLength; - char *targetName; - uint32 *targetNameLength; size_t targetNameBytes; - size_t requestSize; - int result; + + targetNameBytes = strlen(symname) + 1; switch (opUsed) { case HGFS_OP_CREATE_SYMLINK_V3: { + int result; + HgfsFileNameV3 *fileNameP; requestV3 = HgfsGetRequestPayload(req); - /* We'll use these later. */ - symlinkName = requestV3->symlinkName.name; - symlinkNameLength = &requestV3->symlinkName.length; requestV3->symlinkName.flags = 0; requestV3->symlinkName.fid = HGFS_INVALID_HANDLE; requestV3->symlinkName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE; requestV3->reserved = 0; requestSize = sizeof(*requestV3) + HgfsGetRequestHeaderSize(); + /* Convert symlink name to CP format. */ + result = CPName_ConvertTo(symlink, + HGFS_LARGE_PACKET_MAX - (requestSize - 1), + requestV3->symlinkName.name); + if (result < 0) { + LOG(4, ("SymlinkName CP conversion failed.\n")); + return -EINVAL; + } + requestV3->symlinkName.length = result; + requestSize += result; + + /* Copy target name into request packet. */ + if (targetNameBytes > HGFS_LARGE_PACKET_MAX - (requestSize - 1)) { + LOG(4, ("Target name is too long.\n")); + return -EINVAL; + } + + fileNameP = (HgfsFileNameV3 *)((char *)&requestV3->symlinkName + + sizeof requestV3->symlinkName + result); + memcpy(fileNameP->name, symname, targetNameBytes); + LOG(6, ("Target name: \"%s\"\n", fileNameP->name)); + /* Convert target name to CPName-lite format. */ + CPNameLite_ConvertTo(fileNameP->name, targetNameBytes - 1, '/'); + fileNameP->length = targetNameBytes - 1; + fileNameP->flags = 0; + fileNameP->fid = HGFS_INVALID_HANDLE; + fileNameP->caseType = HGFS_FILE_NAME_CASE_SENSITIVE; break; } case HGFS_OP_CREATE_SYMLINK: { + int result; + HgfsFileName *fileNameP; request = (HgfsRequestSymlinkCreate *)(HGFS_REQ_PAYLOAD(req)); - /* We'll use these later. */ - symlinkName = request->symlinkName.name; - symlinkNameLength = &request->symlinkName.length; requestSize = sizeof *request; + /* Convert symlink name to CP format. */ + result = CPName_ConvertTo(symlink, + HGFS_LARGE_PACKET_MAX - (requestSize - 1), + request->symlinkName.name); + if (result < 0) { + LOG(4, ("SymlinkName CP conversion failed.\n")); + return -EINVAL; + } + request->symlinkName.length = result; + requestSize += result; + + /* Copy target name into request packet. */ + if (targetNameBytes > HGFS_LARGE_PACKET_MAX - (requestSize - 1)) { + LOG(4, ("Target name is too long.\n")); + return -EINVAL; + } + + fileNameP = (HgfsFileName *)((char *)&request->symlinkName + + sizeof request->symlinkName + result); + memcpy(fileNameP->name, symname, targetNameBytes); + LOG(6, ("Target name: \"%s\"\n", fileNameP->name)); + /* Convert target name to CPName-lite format. */ + CPNameLite_ConvertTo(fileNameP->name, targetNameBytes - 1, '/'); + fileNameP->length = targetNameBytes - 1; break; } default: @@ -88,59 +133,13 @@ HgfsPackSymlinkCreateRequest(const char* symlink, // IN: path of the link return -EPROTO; } - - /* Convert symlink name to CP format. */ - result = CPName_ConvertTo(symlink, - HGFS_LARGE_PACKET_MAX - (requestSize - 1), - symlinkName); - if (result < 0) { - LOG(4, ("SymlinkName CP conversion failed.\n")); - return -EINVAL; - } - - *symlinkNameLength = result; - req->payloadSize = requestSize + result; + req->payloadSize = requestSize; /* - * Note the different buffer length. This is because HgfsRequestSymlink - * contains two filenames, and once we place the first into the packet we - * must account for it when determining the amount of buffer available for - * the second. - * - * Also note that targetNameBytes accounts for the NUL character. Once - * we've converted it to CP name, it won't be NUL-terminated and the length - * of the string in the packet itself won't account for it. + * targetNameBytes accounts for the NUL character. Once we've converted + * it to CP name, it won't be NUL-terminated and the length of the string + * in the packet itself won't account for it. */ - if (opUsed == HGFS_OP_CREATE_SYMLINK_V3) { - HgfsFileNameV3 *fileNameP; - fileNameP = (HgfsFileNameV3 *)((char *)&requestV3->symlinkName + - sizeof requestV3->symlinkName + result); - targetName = fileNameP->name; - targetNameLength = &fileNameP->length; - fileNameP->flags = 0; - fileNameP->fid = HGFS_INVALID_HANDLE; - fileNameP->caseType = HGFS_FILE_NAME_CASE_SENSITIVE; - } else { - HgfsFileName *fileNameP; - fileNameP = (HgfsFileName *)((char *)&request->symlinkName + - sizeof request->symlinkName + result); - targetName = fileNameP->name; - targetNameLength = &fileNameP->length; - } - targetNameBytes = strlen(symname) + 1; - - /* Copy target name into request packet. */ - if (targetNameBytes > HGFS_LARGE_PACKET_MAX - (requestSize - 1)) { - LOG(4, ("Target name is too long.\n")); - return -EINVAL; - } - memcpy(targetName, symname, targetNameBytes); - LOG(6, ("Target name: \"%s\"\n", targetName)); - - /* Convert target name to CPName-lite format. */ - CPNameLite_ConvertTo(targetName, targetNameBytes - 1, '/'); - - *targetNameLength = targetNameBytes - 1; req->payloadSize += targetNameBytes - 1; /* Fill in header here as payloadSize needs to be there. */