From 6b6122a9570156272a11f54625ffafd672e38aba Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sat, 21 Jan 2017 02:11:24 +0100 Subject: [PATCH 1/2] ensure the string for conversion is \0 terminated and integrade additional path length check --- Zend/zend_virtual_cwd.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/Zend/zend_virtual_cwd.c b/Zend/zend_virtual_cwd.c index 9c2dc292990..b5e099848a3 100644 --- a/Zend/zend_virtual_cwd.c +++ b/Zend/zend_virtual_cwd.c @@ -916,6 +916,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i char *printname = NULL, *substitutename = NULL; size_t substitutename_len; int substitutename_off = 0; + wchar_t tmpsubstname[MAXPATHLEN]; if(++(*ll) > LINK_MAX) { free_alloca(tmp, use_heap); @@ -959,8 +960,15 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i } substitutename_len = pbuffer->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR); - substitutename = php_win32_cp_conv_w_to_any(reparsetarget + pbuffer->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR), - substitutename_len, &substitutename_len); + if (substitutename_len > MAXPATHLEN) { + free_alloca(pbuffer, use_heap_large); + free_alloca(tmp, use_heap); + FREE_PATHW() + return -1; + } + memmove(tmpsubstname, reparsetarget + pbuffer->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR), pbuffer->MountPointReparseBuffer.SubstituteNameLength); + tmpsubstname[substitutename_len] = L'\0'; + substitutename = php_win32_cp_conv_w_to_any(tmpsubstname, substitutename_len, &substitutename_len); if (!substitutename) { free_alloca(pbuffer, use_heap_large); free_alloca(tmp, use_heap); @@ -982,8 +990,15 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i substitutename_len = pbuffer->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR); - substitutename = php_win32_cp_conv_w_to_any(reparsetarget + pbuffer->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR), - substitutename_len, &substitutename_len); + if (substitutename_len > MAXPATHLEN) { + free_alloca(pbuffer, use_heap_large); + free_alloca(tmp, use_heap); + FREE_PATHW() + return -1; + } + memmove(tmpsubstname, reparsetarget + pbuffer->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR), pbuffer->MountPointReparseBuffer.SubstituteNameLength); + tmpsubstname[substitutename_len] = L'\0'; + substitutename = php_win32_cp_conv_w_to_any(tmpsubstname, substitutename_len, &substitutename_len); if (!substitutename) { free_alloca(pbuffer, use_heap_large); free_alloca(tmp, use_heap); From 51e1da6ea1e663908302e162ced1b7a8cb5aee05 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sat, 21 Jan 2017 02:17:06 +0100 Subject: [PATCH 2/2] exclude debug code --- Zend/zend_virtual_cwd.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Zend/zend_virtual_cwd.c b/Zend/zend_virtual_cwd.c index b5e099848a3..5a0b14901ad 100644 --- a/Zend/zend_virtual_cwd.c +++ b/Zend/zend_virtual_cwd.c @@ -913,7 +913,10 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i int bufindex = 0, isabsolute = 0; wchar_t * reparsetarget; BOOL isVolume = FALSE; - char *printname = NULL, *substitutename = NULL; +#if VIRTUAL_CWD_DEBUG + char *printname = NULL; +#endif + char *substitutename = NULL; size_t substitutename_len; int substitutename_off = 0; wchar_t tmpsubstname[MAXPATHLEN]; @@ -951,6 +954,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i if(pbuffer->ReparseTag == IO_REPARSE_TAG_SYMLINK) { reparsetarget = pbuffer->SymbolicLinkReparseBuffer.ReparseTarget; isabsolute = (pbuffer->SymbolicLinkReparseBuffer.Flags == 0) ? 1 : 0; +#if VIRTUAL_CWD_DEBUG printname = php_win32_ioutil_w_to_any(reparsetarget + pbuffer->MountPointReparseBuffer.PrintNameOffset / sizeof(WCHAR)); if (!printname) { free_alloca(pbuffer, use_heap_large); @@ -958,6 +962,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i FREE_PATHW() return -1; } +#endif substitutename_len = pbuffer->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR); if (substitutename_len > MAXPATHLEN) { @@ -972,7 +977,9 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i if (!substitutename) { free_alloca(pbuffer, use_heap_large); free_alloca(tmp, use_heap); +#if VIRTUAL_CWD_DEBUG free(printname); +#endif FREE_PATHW() return -1; } @@ -980,6 +987,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i else if(pbuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) { isabsolute = 1; reparsetarget = pbuffer->MountPointReparseBuffer.ReparseTarget; +#if VIRTUAL_CWD_DEBUG printname = php_win32_ioutil_w_to_any(reparsetarget + pbuffer->MountPointReparseBuffer.PrintNameOffset / sizeof(WCHAR)); if (!printname) { free_alloca(pbuffer, use_heap_large); @@ -987,6 +995,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i FREE_PATHW() return -1; } +#endif substitutename_len = pbuffer->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR); @@ -1002,7 +1011,9 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i if (!substitutename) { free_alloca(pbuffer, use_heap_large); free_alloca(tmp, use_heap); +#if VIRTUAL_CWD_DEBUG free(printname); +#endif FREE_PATHW() return -1; } @@ -1065,9 +1076,9 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i fprintf(stderr, "reparse: print: %s ", printname); fprintf(stderr, "sub: %s ", substitutename); fprintf(stderr, "resolved: %s ", path); + free(printname); #endif free_alloca(pbuffer, use_heap_large); - free(printname); free(substitutename); if(isabsolute == 1) {