Skip to content

Commit 91a3b37

Browse files
committed
Fix heap corruption in symlink procedure.
1 parent 5fb1214 commit 91a3b37

File tree

1 file changed

+18
-16
lines changed

1 file changed

+18
-16
lines changed

src/NFS3Prog.cpp

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -578,43 +578,47 @@ nfsstat3 CNFS3Prog::ProcedureREADLINK(void)
578578
}
579579
else {
580580
DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, NULL, 0, lpOutBuffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &bytesReturned, NULL);
581-
581+
std::string finalSymlinkPath;
582582
if (lpOutBuffer->ReparseTag == IO_REPARSE_TAG_SYMLINK || lpOutBuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
583583
{
584584
if (lpOutBuffer->ReparseTag == IO_REPARSE_TAG_SYMLINK)
585585
{
586586
size_t plen = lpOutBuffer->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(WCHAR);
587-
pMBBuffer = (char *)malloc((plen + 1));
588587
WCHAR *szPrintName = new WCHAR[plen + 1];
589588
wcsncpy_s(szPrintName, plen + 1, &lpOutBuffer->SymbolicLinkReparseBuffer.PathBuffer[lpOutBuffer->SymbolicLinkReparseBuffer.PrintNameOffset / sizeof(WCHAR)], plen);
590589
szPrintName[plen] = 0;
591-
size_t i;
592-
wcstombs_s(&i, pMBBuffer, (plen + 1), szPrintName, (plen + 1));
590+
std::wstring wStringTemp(szPrintName);
591+
delete[] szPrintName;
592+
std::string cPrintName(wStringTemp.begin(), wStringTemp.end());
593+
finalSymlinkPath.assign(cPrintName);
593594
// TODO: Revisit with cleaner solution
594-
if (!PathIsRelative(pMBBuffer))
595+
if (!PathIsRelative(cPrintName.c_str()))
595596
{
596597
std::string strFromChar;
597598
strFromChar.append("\\\\?\\");
598-
strFromChar.append(pMBBuffer);
599+
strFromChar.append(cPrintName);
599600
char *target = _strdup(strFromChar.c_str());
600601
// remove last folder
601602
char *pos = strrchr(path, '\\');
602603
if (pos != NULL) {
603604
*pos = '\0';
604605
}
605-
PathRelativePathTo(pMBBuffer, path, FILE_ATTRIBUTE_DIRECTORY, target, FILE_ATTRIBUTE_DIRECTORY);
606+
char szOut[MAX_PATH] = "";
607+
PathRelativePathTo(szOut, path, FILE_ATTRIBUTE_DIRECTORY, target, FILE_ATTRIBUTE_DIRECTORY);
608+
std::string symlinkPath(szOut);
609+
finalSymlinkPath.assign(symlinkPath);
606610
}
607611
}
608612

609613
// TODO: Revisit with cleaner solution
610614
if (lpOutBuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
611615
{
612616
size_t slen = lpOutBuffer->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
613-
pMBBuffer = (char *)malloc((slen + 1));
614617
WCHAR *szSubName = new WCHAR[slen + 1];
615618
wcsncpy_s(szSubName, slen + 1, &lpOutBuffer->MountPointReparseBuffer.PathBuffer[lpOutBuffer->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)], slen);
616619
szSubName[slen] = 0;
617620
std::wstring wStringTemp(szSubName);
621+
delete[] szSubName;
618622
std::string target(wStringTemp.begin(), wStringTemp.end());
619623
target.erase(0, 2);
620624
target.insert(0, 2, '\\');
@@ -623,18 +627,16 @@ nfsstat3 CNFS3Prog::ProcedureREADLINK(void)
623627
if (pos != NULL) {
624628
*pos = '\0';
625629
}
626-
PathRelativePathTo(pMBBuffer, path, FILE_ATTRIBUTE_DIRECTORY, target.c_str(), FILE_ATTRIBUTE_DIRECTORY);
630+
char szOut[MAX_PATH] = "";
631+
PathRelativePathTo(szOut, path, FILE_ATTRIBUTE_DIRECTORY, target.c_str(), FILE_ATTRIBUTE_DIRECTORY);
632+
std::string symlinkPath = szOut;
633+
finalSymlinkPath.assign(symlinkPath);
627634
}
628635

629636
// write path always with / separator, so windows created symlinks work too
630-
std::string strFromChar;
631-
strFromChar.append(pMBBuffer);
632-
std::replace(strFromChar.begin(), strFromChar.end(), '\\', '/');
633-
char *result = _strdup(strFromChar.c_str());
634-
637+
std::replace(finalSymlinkPath.begin(), finalSymlinkPath.end(), '\\', '/');
638+
char *result = _strdup(finalSymlinkPath.c_str());
635639
data.Set(result);
636-
free(pMBBuffer);
637-
free(result);
638640
}
639641
free(lpOutBuffer);
640642
}

0 commit comments

Comments
 (0)