diff options
author | Anatol Belski <ab@php.net> | 2015-05-19 15:44:55 +0200 |
---|---|---|
committer | Anatol Belski <ab@php.net> | 2015-05-19 15:44:55 +0200 |
commit | 890a28d4b97b5785f155618fc34134acb77f7a64 (patch) | |
tree | ea56290bf3bb0e0a937c34763b91e76126e1a6c8 /Zend/zend_virtual_cwd.c | |
parent | eebab8282b38ca6ff77d3b878aba8fbb9fc89f66 (diff) | |
download | php-git-890a28d4b97b5785f155618fc34134acb77f7a64.tar.gz |
Fixed bug #69511 Off-by-one bufferoverflow in php_sys_readlink
Diffstat (limited to 'Zend/zend_virtual_cwd.c')
-rw-r--r-- | Zend/zend_virtual_cwd.c | 14 |
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; } |