summaryrefslogtreecommitdiff
path: root/symbian/symbian_proto.h
diff options
context:
space:
mode:
authorDaniel Dragan <bulk88@hotmail.com>2013-11-01 23:04:35 -0400
committerSteve Hay <steve.m.hay@googlemail.com>2013-11-02 19:35:43 +0000
commitb47a847f6284f6f98ad7509cf77a4aeb802d8fce (patch)
tree418e95b955a5704fce4f1f4abfb5a4b6bfa76a38 /symbian/symbian_proto.h
parent50e4f4d46de7747365d201feabf76ce56822c514 (diff)
downloadperl-b47a847f6284f6f98ad7509cf77a4aeb802d8fce.tar.gz
win32/win32sck.c: dont close() a freed socket os handle
This patch is in RT as [perl #120091] but also fixes [perl #118059]. Because the MS C lib, doesn't support sockets natively, Perl uses open_osfhandle, to wrap a socket into CRT fd. Sockets handles must be closed with closesocket, not CloseHandle (which CRT close calls). Undefined behavior will happen otherwise according to MS. Swap the now closed socket handle in the CRT to INVALID_HANDLE_VALUE. The CRT will not call CloseHandle on INVALID_HANDLE_VALUE and returns success if it sees INVALID_HANDLE_VALUE. CloseHandle will never be called on a socket handle with this patch. In #118059, a race condition was reported, where accept() failed with ENOTSOCK, when a psuedofork was done, and connection from the child fake perl process to parent fake perl process was done. The race condition's effects occur inside the user mode code in mswsock.dll!_WSPAccept in the parent perl, which winds up having a kernel handle of an unknown type in it that is invalid. The invalid handle is passed to kernel calls, which fail, because the handle is invalid, and the error is translated to ENOTSOCK. The exact mechanism of the bug and 100% reproducabilty of the race were never established, since mswsock.dll is closed source. Another benefit of this patch is making it easier to use C debuggers on a Win32 Perl because of less debugger-only bad handle exceptions (NtGlobalFlag FLG_ENABLE_HANDLE_EXCEPTIONS/0xC0000008 STATUS_INVALID_HANDLE). This commit reverts parts of commit 9b1f18150a "Get rid of PERL_MSVCRT_READFIX" and parts of commit 46e77f1118 "Don't use the PERL_MSVCRT_READFIX when using VC++ 7.x onwards." and contains additional changes not found in those 2 commits. The method for selecting the definition of struct ioinfo isn't perfect. It will break if VC > 6 is changed to use the older msvcrt.dll. For some versions of the CRT, like 2005/8.0, it is impossible to know the definition of ioinfo struct at C compile time, since the struct increased in size a number of times with higher build numbers of v8.0 CRT. SxS and security updates make that same perl binary will run with different v8.0 CRTs at different times. For the case when ioinfo can not be hard coded, introduce WIN32_DYN_IOINFO_SIZE. With WIN32_DYN_IOINFO_SIZE, the size of the ioinfo struct is determined on Perl process startup using _mize. Since VC 2013 is a brand new product at the time of this patch, even though its struct is known, and 2008 through 2012 have been stable so far, don't assume at this time 2013's ioinfo will be stable. Therefore, VC 2003 and older (including Mingw's v6.0), 2008 to 2012, are hard coded. 2013 is a candidate one day to be hard coded. VC 2005 can never be hard coded. All non-WIN32_DYN_IOINFO_SIZE compilers will work with WIN32_DYN_IOINFO_SIZE. Non-WIN32_DYN_IOINFO_SIZE mode is simply more efficient. For future compatibility concerns, 3 forms of protection are offered. If __pioinfo isn't exported anymore, the Perl build will break. In WIN32_DYN_IOINFO_SIZE mode, if __pioinfo isn't heap memory anymore or the start of a memory block, the runtime panic will happen. In with and without WIN32_DYN_IOINFO_SIZE, only on a DEBUGGING build, the handle returned by CRT's _get_osfhandle, which is the authentic handle in the CRT, is compared to the handle found by accessing the ioinfo struct directly. If they don't match, the handle swapping code is broken and the assert fails.
Diffstat (limited to 'symbian/symbian_proto.h')
0 files changed, 0 insertions, 0 deletions