-
Incident report
-
Resolution: Unresolved
-
Trivial
-
6.4.0beta5
-
None
In the following block of code in tls.c, the "data" variable was not initialised during the call of BIO_get_mem_data() and then mistakenly used uninitialised in zbx_strlcpy():
if (size <= (len = (size_t)BIO_get_mem_data(bio, &data))) { *error = zbx_strdup(*error, "output buffer too small"); goto out; } zbx_strlcpy(buf, data, len + 1);
Looking at the documentation of the BIO_get_mem_data() function:
BIO_get_mem_data() returns the total number of bytes available on success, 0 if b is NULL, or a negative value in case of other errors.
So, it returns a negative value if error happened.
Example from openssl source code on how to properly handle this function:
ssl3_digest_cached_records() ... hdatalen = BIO_get_mem_data(s->s3.handshake_buffer, &hdata); if (hdatalen <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_HANDSHAKE_LENGTH); return 0; }
We however do not do that, and this is a bug (not related to the current ticket).
Update, Agent 2() independently uses BIO_get_mem_data() and also does not check the return value.
Update 2, other similar functions like BIO_read() also can return negative value in the case of error, but it is not checked, e.g. in tls_error():
*buf = malloc(sz + 1); BIO_read(tls->err, *buf, (int)sz); (*buf)[sz] = '\0'; }
The result of not checking the return values are invalid memory issues and potentially crashes that would be incredibly hard to debug (if not run by Valgrind):
==00:00:00:11.150 226099== Conditional jump or move depends on uninitialised value(s) ==00:00:00:11.150 226099== at 0x483EFB8: __strlen_sse2 (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==00:00:00:11.151 226099== by 0x408CEE: zbx_strlcpy (common_str.c:128) ==00:00:00:11.151 226099== by 0x3347C2: zbx_x509_dn_gets.constprop.0 (tls.c:1100) ==00:00:00:11.151 226099== by 0x337138: zbx_tls_get_attr_cert (tls.c:3875) ==00:00:00:11.151 226099== by 0x3A6482: zbx_proxy_check_permissions (proxy.c:154) ==00:00:00:11.151 226099== by 0x1C25C5: zbx_recv_proxy_data (proxydata.c:147) ==00:00:00:11.151 226099== by 0x1BD61B: process_trap (trapper.c:1120) ==00:00:00:11.151 226099== by 0x1BEE74: process_trapper_child (trapper.c:1265) ==00:00:00:11.151 226099== by 0x1BEE74: trapper_thread (trapper.c:1355) ==00:00:00:11.151 226099== by 0x3280F3: zbx_thread_start (threads.c:115) ==00:00:00:11.151 226099== by 0x18A8E2: server_startup.constprop.0 (server.c:1501) ==00:00:00:11.151 226099== by 0x18BA8A: MAIN_ZABBIX_ENTRY (server.c:2000) ==00:00:00:11.151 226099== by 0x3E1022: zbx_daemon_start (daemon.c:448) ==00:00:00:11.151 226099== Uninitialised value was created by a heap allocation ==00:00:00:11.151 226099== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==00:00:00:11.151 226099== by 0x4FA7CB9: CRYPTO_clear_realloc (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1) ==00:00:00:11.151 226099== by 0x4EF7DB8: BUF_MEM_grow_clean (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1) ==00:00:00:11.151 226099== by 0x4ED9C57: ??? (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1) ==00:00:00:11.151 226099== by 0x4ED563D: ??? (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1) ==00:00:00:11.151 226099== by 0x4ED4653: ??? (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1) ==00:00:00:11.151 226099== by 0x4ED4B16: BIO_write (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1) ==00:00:00:11.151 226099== by 0x4EB97C0: ??? (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1) ==00:00:00:11.151 226099== by 0x4EB9959: ??? (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1) ==00:00:00:11.151 226099== by 0x4EB9BE5: ??? (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1) ==00:00:00:11.151 226099== by 0x4EB9DC2: ??? (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1) ==00:00:00:11.151 226099== by 0x4EBA278: ??? (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1)
and
==00:00:03:08.760 226095== Invalid read of size 1 ==00:00:03:08.760 226095== at 0x483EFB4: __strlen_sse2 (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==00:00:03:08.760 226095== by 0x408CEE: zbx_strlcpy (common_str.c:128) ==00:00:03:08.760 226095== by 0x3347C2: zbx_x509_dn_gets.constprop.0 (tls.c:1100) ==00:00:03:08.760 226095== by 0x337156: zbx_tls_get_attr_cert (tls.c:3883) ==00:00:03:08.760 226095== by 0x3A6482: zbx_proxy_check_permissions (proxy.c:154) ==00:00:03:08.760 226095== by 0x1C25C5: zbx_recv_proxy_data (proxydata.c:147) ==00:00:03:08.760 226095== by 0x1BD61B: process_trap (trapper.c:1120) ==00:00:03:08.760 226095== by 0x1BEE74: process_trapper_child (trapper.c:1265) ==00:00:03:08.760 226095== by 0x1BEE74: trapper_thread (trapper.c:1355) ==00:00:03:08.760 226095== by 0x3280F3: zbx_thread_start (threads.c:115) ==00:00:03:08.760 226095== by 0x18A8E2: server_startup.constprop.0 (server.c:1501) ==00:00:03:08.760 226095== by 0x18BA8A: MAIN_ZABBIX_ENTRY (server.c:2000) ==00:00:03:08.760 226095== by 0x3E1022: zbx_daemon_start (daemon.c:448) ==00:00:03:08.760 226095== Address 0x822ba20 is 0 bytes after a block of size 96 alloc'd ==00:00:03:08.760 226095== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==00:00:03:08.760 226095== by 0x4FA7CB9: CRYPTO_clear_realloc (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1) ==00:00:03:08.760 226095== by 0x4EF7DB8: BUF_MEM_grow_clean (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1) ==00:00:03:08.760 226095== by 0x4ED9C57: ??? (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1) ==00:00:03:08.760 226095== by 0x4ED563D: ??? (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1) ==00:00:03:08.760 226095== by 0x4ED4653: ??? (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1) ==00:00:03:08.760 226095== by 0x4ED4B16: BIO_write (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1) ==00:00:03:08.760 226095== by 0x4EB97C0: ??? (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1) ==00:00:03:08.760 226095== by 0x4EB9959: ??? (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1) ==00:00:03:08.760 226095== by 0x4EB9BE5: ??? (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1) ==00:00:03:08.760 226095== by 0x4EB9DC2: ??? (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1) ==00:00:03:08.760 226095== by 0x4EBA278: ??? (in /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1)