-
-
Notifications
You must be signed in to change notification settings - Fork 6.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
segmentation fault using a easy handle after CURLE_WRITE_ERROR #9873
Comments
That looks like a crash inside |
Prior to this change if the user wanted to signal an error from their write callbacks they would have to use logic to return a value different from the number of bytes (nmemb) passed to the callback. Also, the inclination of some users has been to just return 0 to signal error, which is incorrect as that may be the number of bytes passed to the callback. To remedy this the user can now return CURL_WRITEFUNC_ERROR instead. Ref: curl#9873 Closes #xxxx
To be clear 0 only signals an error if nmemb is not 0, because then the amount of bytes handled is different from what was passed in. You would have to use logic to determine a proper failure code (example). Anyway, so far there's nothing here to suggest the issue you reported is a libcurl issue. Can you give us a minimal self contained example that can be used to reproduce? |
Yes, of course, if the provided nmemb is null, returning 0 from the callback will not trigger curl_easy_perform() to stop with CURLE_WRITE_ERROR (but unless the callback is constantly invoked with nmemb set to zero, the requested interruption of libcurl would occur a next time. But OK, this can be optimized on my side). I will try to extract the calls done to libcurl from the C++ classes into a simpler C code, I just need a few days to find the time to do that. |
Potentially this bug? |
Prior to this change if the user wanted to signal an error from their write callbacks they would have to use logic to return a value different from the number of bytes (nmemb) passed to the callback. Also, the inclination of some users has been to just return 0 to signal error, which is incorrect as that may be the number of bytes passed to the callback. To remedy this the user can now return CURL_WRITEFUNC_ERROR instead. Ref: #9873 Closes #9874
Well, that does not match. I have the problem with both statically and dynamically linked binaries. But during these testings, I found (by mistake) that the segfault expressed only when some options were set (CURLOPT_USERPWD attracted my attention) I still have to characterize more precisely which option is significant and is not eventually improperly set on my side. I will get back to you with more precised scenario/info. But can you confirm that I properly understand the documentation when it tells " |
Yes, that is correct. |
after reviewing my testing environment, I realized that my dynamically linked binaries were upx-compressed (they are built this way by default), which lead the 'file' command to report them as statically linked (not sure how it impacts on the bug concerning getaddrinfo() you mentioned). Anyway, disabling upx compression I get the segfault only with real statically linked binaries, no problem with dynamically linked one. What troubled me is that calling the statically linked binary a given way led the segfault to occur, but calling it another way did not. I added some printf() calls before the invocations to curl_* routines and realized that both ways ended with the almost same sequence of call to the libcurl API!
or
in the first sequence ending with a segfault, only a somehow simple routine is called in addition, to display a message to the user, but this message may be translated by mean of gettext(). When the LANG variable is unset no segfault occurs, when it is set to my locale the segfault occurs.... I've checked both native formatting string and its translated version, they have the same % format in type and values. Removing the gettext() call avoids the segfault while the LANG is still set to my locale... I don't understand for now why it only concerns statically linked version... but that's another story. In conclusion, IMHO, the problem is not libcurl related at all, I understand there is some memory corruption done around the gettext() call and translated string, which lead to the segfault some time after in _nss_files_gethostbyname4_r() which is called (indirectly) from libcurl. thank you for your support and this very useful library :) |
Thanks for following up. You could try valgrind or address sanitizer to further narrow it down. I don't think there's enough information here to definitively identify the cause, but I also think it's highly unlikely this is a libcurl issue so I'm closing. |
I did this
the application I maintain and that relies on libcurl sometime needs to stop reading file content from ftp/sftp depending on the data read so far.
For years it was implemented by CURLOPT_WRITEFUNCTION + CURLOPT_WRITEDATA and the pointed to callback returned 0 instead of the size*nmemb value when reading needed to stop (sftp and ftp protocols).
Today, if doing that way still works as expected, (curl_easy_perform() returns the expected CURLE_WRITE_ERROR code) any subsequent further action on the handle triggers a segmentation fault with the following stack (if that can help):
I tried to curl_easy_reset() first and reapplying all option (curl_easy_setopt()) on this handle, this just leads to the same fate...
I tried also after a curl_easy_cleanup() + curl_easy_init() ... same fate...
I expected the following
if I'm doing something wrong which might still be possible, an error message would be welcome ;)
curl/libcurl version
note that only libcurl is used (compiled by myself to have a statically linkable library, something my distro does not provide), where from the curl/liburl difference in the previous output
operating system
Linux Devuan
lsb_release -a
uname -a
Linux terre-neuve 5.10.0-16-amd64 #1 SMP Debian 5.10.127-2 (2022-07-23) x86_64 GNU/Linux
The text was updated successfully, but these errors were encountered: