summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
authorAnatol Belski <ab@php.net>2015-05-19 15:44:55 +0200
committerAnatol Belski <ab@php.net>2015-05-19 15:44:55 +0200
commit890a28d4b97b5785f155618fc34134acb77f7a64 (patch)
treeea56290bf3bb0e0a937c34763b91e76126e1a6c8 /Zend
parenteebab8282b38ca6ff77d3b878aba8fbb9fc89f66 (diff)
downloadphp-git-890a28d4b97b5785f155618fc34134acb77f7a64.tar.gz
Fixed bug #69511 Off-by-one bufferoverflow in php_sys_readlink
Diffstat (limited to 'Zend')
-rw-r--r--Zend/zend_virtual_cwd.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/Zend/zend_virtual_cwd.c b/Zend/zend_virtual_cwd.c
index 28cc7f6eed..e880775ea7 100644
--- a/Zend/zend_virtual_cwd.c
+++ b/Zend/zend_virtual_cwd.c
@@ -237,6 +237,10 @@ CWD_API int php_sys_readlink(const char *link, char *target, size_t target_len){
typedef BOOL (WINAPI *gfpnh_func)(HANDLE, LPTSTR, DWORD, DWORD);
gfpnh_func pGetFinalPathNameByHandle;
+ if (!target_len) {
+ return -1;
+ }
+
kernel32 = LoadLibrary("kernel32.dll");
if (kernel32) {
@@ -260,8 +264,14 @@ CWD_API int php_sys_readlink(const char *link, char *target, size_t target_len){
return -1;
}
- dwRet = pGetFinalPathNameByHandle(hFile, target, MAXPATHLEN, VOLUME_NAME_DOS);
- if(dwRet >= MAXPATHLEN || dwRet == 0) {
+ /* Despite MSDN has documented it won't to, the length returned by
+ GetFinalPathNameByHandleA includes the length of the
+ null terminator. This behavior is at least reproducible
+ with VS2012 and earlier, and seems not to be fixed till
+ now. Thus, correcting target_len so it's suddenly don't
+ overflown. */
+ dwRet = pGetFinalPathNameByHandle(hFile, target, target_len - 1, VOLUME_NAME_DOS);
+ if(dwRet >= target_len || dwRet >= MAXPATHLEN || dwRet == 0) {
return -1;
}