maxmind / geoipupdate-legacy

GeoIP update client code
GNU General Public License v2.0
258 stars 63 forks source link

Unsafe use in CURLOPT_WRITEDATA #104

Open gvanem opened 6 years ago

gvanem commented 6 years ago

After some patching to make a geoipupdate.exe for Windows, I get a crash due to this call:

    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)f);

in geoipupdate.c.

Reason: My libcurl.dll was built using MSVC. But geoipupdate.exe was built using MinGW where the inner structure of a FILE* is another story completely . The call-stack shows it crashes while accessing the critical-section of f:

ntdll!RtlpWaitOnCriticalSection+0x6f
ntdll!RtlpEnterCriticalSectionContended+0xd6
ntdll!RtlEnterCriticalSection+0x49
ucrtbase!__crt_seh_guarded_call<unsigned int>::operator()<<lambda_cd3bfd923e8d1349099e544c97b1bd8e>,<lambda_54dcfcba6f8e0c549fa430f4d53fb7dd> &,<lambda_5e1d0fa2aa2b73b187bf8b7e1d30c7f8> >+0x1f
ucrtbase!fwrite+0x4e
libcurl!chop_write(struct connectdata * conn = 0x0cfa9cc8, int type = 0n1, char * optr = 0x0cf9cc1f "Invalid user ID.", unsigned int olen = 0x10)+0x9c [f:\mingw32\src\inet\curl\lib\sendf.c @ 585] 
libcurl!Curl_client_write(struct connectdata * conn = 0x0cfa9cc8, int type = 0n1, char * ptr = 0x0cf9cc1f "Invalid user ID.", unsigned int len = 0x10)+0x4a [f:\mingw32\src\inet\curl\lib\sendf.c @ 668] 
libcurl!readwrite_data(struct Curl_easy * data = 0x0cf97e78, struct connectdata * conn = 0x0cfa9cc8, struct SingleRequest * k = 0x0cf97ee8, int * didwhat = 0x0061fc5c, bool * done = 0x0061fc97, bool * comeback = 0x0061fc98)+0x5cc [f:\mingw32\src\inet\curl\lib\transfer.c @ 796] 
libcurl!Curl_readwrite(struct connectdata * conn = 0x0cfa9cc8, struct Curl_easy * data = 0x0cf97e78, bool * done = 0x0061fc97, bool * comeback = 0x0061fc98)+0xef [f:\mingw32\src\inet\curl\lib\transfer.c @ 1125] 
libcurl!multi_runsingle(struct Curl_multi * multi = 0x0cfa0bc0, struct curltime now = struct curltime, struct Curl_easy * data = 0x0cf97e78)+0x1116 [f:\mingw32\src\inet\curl\lib\multi.c @ 1932] 
libcurl!curl_multi_perform(struct Curl_multi * multi = 0x0cfa0bc0, int * running_handles = 0x0061fd18)+0x5f [f:\mingw32\src\inet\curl\lib\multi.c @ 2196] 
libcurl!easy_transfer+0x6c [f:\mingw32\src\inet\curl\lib\easy.c @ 686] 
libcurl!easy_perform(struct Curl_easy * data = 0x0cf97e78, bool events = false)+0x193 [f:\mingw32\src\inet\curl\lib\easy.c @ 779] 
libcurl!curl_easy_perform(struct Curl_easy * data = 0x0cf97e78)+0xb [f:\mingw32\src\inet\curl\lib\easy.c @ 798] 
geoipupdate+0x2179

What (besides linking to a static libcurl) can be be done for this? But it could be a PITA to use a static libcurl since there could be so many external dependencies.

oschwald commented 6 years ago

You may also be interested in the next gen version of geoipupdate. It is written in Go and should work on Windows without issue. We plan on providing binaries for Windows once we do a full release.