summaryrefslogtreecommitdiff
path: root/win32/vdir.h
diff options
context:
space:
mode:
authorTony Cook <tony@develop-help.com>2015-12-16 11:13:30 +1100
committerRicardo Signes <rjbs@cpan.org>2016-01-11 08:01:48 -0500
commit52236464559c6e410a4587d3c6da9639e75f3ec1 (patch)
tree91f97467e5bf793e22e03cbd278686df42de42d7 /win32/vdir.h
parent130509aa42a87eef258fab0182ee2c7ad16baa8b (diff)
downloadperl-52236464559c6e410a4587d3c6da9639e75f3ec1.tar.gz
avoid invalid memory access in MapPath[AW]
This issue was assigned CVE-2015-8608. [perl #126755]
Diffstat (limited to 'win32/vdir.h')
-rw-r--r--win32/vdir.h23
1 files changed, 16 insertions, 7 deletions
diff --git a/win32/vdir.h b/win32/vdir.h
index 42c306b779..b5c6bc6f45 100644
--- a/win32/vdir.h
+++ b/win32/vdir.h
@@ -15,6 +15,7 @@
* and one additional slot for a UNC name
*/
const int driveCount = ('Z'-'A')+1+1;
+const int driveLetterCount = ('Z'-'A')+1;
class VDir
{
@@ -383,6 +384,7 @@ char *VDir::MapPathA(const char *pInName)
* possiblities -- relative path or absolute path with or without drive letter
* OR UNC name
*/
+ int driveIndex;
char szBuffer[(MAX_PATH+1)*2];
char szlBuf[MAX_PATH+1];
int length = strlen(pInName);
@@ -402,15 +404,18 @@ char *VDir::MapPathA(const char *pInName)
}
/* strlen(pInName) is now <= MAX_PATH */
- if (pInName[1] == ':') {
+ if (length > 1 && pInName[1] == ':') {
/* has drive letter */
- if (IsPathSep(pInName[2])) {
+ if (length > 2 && IsPathSep(pInName[2])) {
/* absolute with drive letter */
DoGetFullPathNameA((char*)pInName, sizeof(szLocalBufferA), szLocalBufferA);
}
else {
/* relative path with drive letter */
- strcpy(szBuffer, GetDirA(DriveIndex(*pInName)));
+ driveIndex = DriveIndex(*pInName);
+ if (driveIndex < 0 || driveIndex >= driveLetterCount)
+ return (char *)pInName;
+ strcpy(szBuffer, GetDirA(driveIndex));
strcat(szBuffer, &pInName[2]);
if(strlen(szBuffer) > MAX_PATH)
szBuffer[MAX_PATH] = '\0';
@@ -420,7 +425,7 @@ char *VDir::MapPathA(const char *pInName)
}
else {
/* no drive letter */
- if (IsPathSep(pInName[1]) && IsPathSep(pInName[0])) {
+ if (length > 1 && IsPathSep(pInName[1]) && IsPathSep(pInName[0])) {
/* UNC name */
DoGetFullPathNameA((char*)pInName, sizeof(szLocalBufferA), szLocalBufferA);
}
@@ -611,6 +616,7 @@ WCHAR* VDir::MapPathW(const WCHAR *pInName)
* possiblities -- relative path or absolute path with or without drive letter
* OR UNC name
*/
+ int driveIndex;
WCHAR szBuffer[(MAX_PATH+1)*2];
WCHAR szlBuf[MAX_PATH+1];
int length = wcslen(pInName);
@@ -630,7 +636,7 @@ WCHAR* VDir::MapPathW(const WCHAR *pInName)
}
/* strlen(pInName) is now <= MAX_PATH */
- if (pInName[1] == ':') {
+ if (length > 1 && pInName[1] == ':') {
/* has drive letter */
if (IsPathSep(pInName[2])) {
/* absolute with drive letter */
@@ -638,7 +644,10 @@ WCHAR* VDir::MapPathW(const WCHAR *pInName)
}
else {
/* relative path with drive letter */
- wcscpy(szBuffer, GetDirW(DriveIndex((char)*pInName)));
+ driveIndex = DriveIndex(*pInName);
+ if (driveIndex < 0 || driveIndex >= driveLetterCount)
+ return (WCHAR *)pInName;
+ wcscpy(szBuffer, GetDirW(driveIndex));
wcscat(szBuffer, &pInName[2]);
if(wcslen(szBuffer) > MAX_PATH)
szBuffer[MAX_PATH] = '\0';
@@ -648,7 +657,7 @@ WCHAR* VDir::MapPathW(const WCHAR *pInName)
}
else {
/* no drive letter */
- if (IsPathSep(pInName[1]) && IsPathSep(pInName[0])) {
+ if (length > 1 && IsPathSep(pInName[1]) && IsPathSep(pInName[0])) {
/* UNC name */
DoGetFullPathNameW((WCHAR*)pInName, (sizeof(szLocalBufferW)/sizeof(WCHAR)), szLocalBufferW);
}