I did this
In the debug build of the new cURL 8.19, very simple programs can lead to a free() of invalid pointers. This is because the memory-debugging strdup is used to allocate the memory, but libssh2 then calls the system free() on the resulting pointer, which is 8 bytes into the pointer, which leads to a SEGV on some systems.
The issue is present in previous versions of cURL, at the very least in 8.18, but it used to be suppressed by the --disable-curldebug option. With the following change in cURL 8.19 (which for some reason is classified as a bugfix), memory debugging is turned on for debug builds by default.
o build: merge TrackMemory (`CURLDEBUG`) into debug-enabled option [46]
A very simple C program can be used to reproduce this problem. The issue occurs on RHAT 7.9, SUSE 12 SP3, SUSE15 SP5, but not newer Red Hat systems (with the same binary built on RHAT7, libc version does not seem to make a difference either). The following should be linked to a debug version of cURL 8.19 - debug or release of OpenSSL and libssh2 does not matter.
#include <stdio.h>
#include <curl/curl.h>
#define SETOPT_OK(curl, option, value) \
assert(curl_easy_setopt((curl), (option), (value)) == CURLE_OK)
int main(void)
{
assert(curl_global_init(CURL_GLOBAL_ALL) == CURLE_OK);
CURL *curl = curl_easy_init();
assert(curl != NULL);
SETOPT_OK(curl, CURLOPT_URL, "sftp:/127.0.0.1:22/tmp/test.txt");
SETOPT_OK(curl, CURLOPT_USERNAME, "user");
SETOPT_OK(curl, CURLOPT_PASSWORD, "password");
assert(curl_easy_perform(curl) == CURLE_OK);
curl_easy_cleanup(curl);
curl_global_cleanup();
return 0;
}
The result is a segmentation violation
*** Error in ./a.out': free(): invalid pointer: 0x000000000186f8e8 ***`
Valgrind specifies where the issue occurs:
==27777== Memcheck, a memory error detector
==27777== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==27777== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==27777== Command: ./curl.out
==27777==
==27777== Invalid free() / delete / delete[] / realloc()
==27777== at 0x4C2ACBD: free (vg_replace_malloc.c:530)
==27777== by 0x456DB9: my_libssh2_free (libssh2.c:251)
==27777== by 0x85EA11: userauth_keyboard_interactive (in /tmp/curl.out)
==27777== by 0x85EBB0: libssh2_userauth_keyboard_interactive_ex (in /tmp/curl.out)
==27777== by 0x45AC75: ssh_state_auth_key (libssh2.c:1728)
==27777== by 0x45D63A: ssh_statemachine (libssh2.c:2638)
==27777== by 0x45EA6B: ssh_multi_statemach (libssh2.c:3082)
==27777== by 0x41C8A9: protocol_connecting (multi.c:1787)
==27777== by 0x41E284: multi_runsingle (multi.c:2583)
==27777== by 0x41E8FC: multi_perform (multi.c:2777)
==27777== by 0x41EBA1: curl_multi_perform (multi.c:2838)
==27777== by 0x4071FD: easy_transfer (easy.c:694)
==27777== Address 0x5796d18 is 8 bytes inside a block of size 25 alloc'd
==27777== at 0x4C29BC3: malloc (vg_replace_malloc.c:299)
==27777== by 0x4111C9: curl_dbg_malloc (memdebug.c:222)
==27777== by 0x4113E7: curl_dbg_strdup (memdebug.c:277)
==27777== by 0x456C15: kbd_callback (libssh2.c:151)
==27777== by 0x85E6AE: userauth_keyboard_interactive (in /tmp/curl.out)
==27777== by 0x85EBB0: libssh2_userauth_keyboard_interactive_ex (in /tmp/curl.out)
==27777== by 0x45AC75: ssh_state_auth_key (libssh2.c:1728)
==27777== by 0x45D63A: ssh_statemachine (libssh2.c:2638)
==27777== by 0x45EA6B: ssh_multi_statemach (libssh2.c:3082)
==27777== by 0x41C8A9: protocol_connecting (multi.c:1787)
==27777== by 0x41E284: multi_runsingle (multi.c:2583)
==27777== by 0x41E8FC: multi_perform (multi.c:2777)
==27777==
curl/libcurl version
curl 8.19.0 with OpenSSL 3.5.5 and libssh2 1.11.1
operating system
The issue occurs on the following systems;
RHAT 7.9: 3.10.0-1160.81.1.el7.x86_64 #1 SMP Thu Nov 24 12:21:22 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
SUSE 12 SP3: 4.4.180-94.100-default #1 SMP Tue Jul 9 19:57:20 UTC 2019 (1569ffb) x86_64 x86_64 x86_64 GNU/Linux
SUSE 15 SP5: 5.14.21-150500.55.88-default #1 SMP PREEMPT_DYNAMIC Fri Dec 6 16:43:20 UTC 2024 (e102a89) x86_64 x86_64 x86_64 GNU/Linux
I did this
In the debug build of the new cURL 8.19, very simple programs can lead to a free() of invalid pointers. This is because the memory-debugging strdup is used to allocate the memory, but libssh2 then calls the system free() on the resulting pointer, which is 8 bytes into the pointer, which leads to a SEGV on some systems.
The issue is present in previous versions of cURL, at the very least in 8.18, but it used to be suppressed by the --disable-curldebug option. With the following change in cURL 8.19 (which for some reason is classified as a bugfix), memory debugging is turned on for debug builds by default.
o build: merge TrackMemory (`CURLDEBUG`) into debug-enabled option [46]A very simple C program can be used to reproduce this problem. The issue occurs on RHAT 7.9, SUSE 12 SP3, SUSE15 SP5, but not newer Red Hat systems (with the same binary built on RHAT7, libc version does not seem to make a difference either). The following should be linked to a debug version of cURL 8.19 - debug or release of OpenSSL and libssh2 does not matter.
The result is a segmentation violation
*** Error in./a.out': free(): invalid pointer: 0x000000000186f8e8 ***`Valgrind specifies where the issue occurs:
curl/libcurl version
curl 8.19.0 with OpenSSL 3.5.5 and libssh2 1.11.1
operating system
The issue occurs on the following systems;
RHAT 7.9: 3.10.0-1160.81.1.el7.x86_64 #1 SMP Thu Nov 24 12:21:22 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
SUSE 12 SP3: 4.4.180-94.100-default #1 SMP Tue Jul 9 19:57:20 UTC 2019 (1569ffb) x86_64 x86_64 x86_64 GNU/Linux
SUSE 15 SP5: 5.14.21-150500.55.88-default #1 SMP PREEMPT_DYNAMIC Fri Dec 6 16:43:20 UTC 2024 (e102a89) x86_64 x86_64 x86_64 GNU/Linux