-
Notifications
You must be signed in to change notification settings - Fork 155
Unhandled NULL return value from ERR_reason_error_string() can lead to crash #588
Description
Hi @michalvasko,
We came across SIGSEGV from nc_tls_get_err_reasons(void) -> libc
?? () from /lib/x86_64-linux-gnu/libc.so.6
nc_tls_get_err_reasons () from /usr/local/lib64/libnetco
nc_tls_read_wrap () from /usr/local/lib64/libnetconf2.so
nc_read.constprop () from /usr/local/lib64/libnetconf2.s
nc_read_until.constprop () from /usr/local/lib64/libnetc
nc_read_msg_io () from /usr/local/lib64/libnetconf2.so.4
On looking further in nc_tls_get_err_reasons(). Found that 'realloc, sprintf, strlen' are the libc calls which can cause SUGSEGV. We are clear that, system has enough memory to allocate memory so rolling out realloc and snprintf. Last one left is strlen.
Below piece of code from libnetconf2/src/session_openssl.c => ERR_get_error() returns error-number if there is no mapped error string then ERR_reason_error_string() returns NULL. strlen(NULL) leads to SIGSEGV.
This happens in some specific 'netconf-session disconnect' scenarios. I couldn't give which error code caused SIGSEV because below piece do not have log to print error code.
Please let us know your comments.
static char *
nc_tls_get_err_reasons(void)
{
...
while ((e = ERR_get_error())) {
if (reason_len) {
/* add "; " */
reason_size += 2;
reasons = nc_realloc(reasons, reason_size);
NC_CHECK_ERRMEM_RET(!reasons, NULL);
reason_len += sprintf(reasons + reason_len, "; ");
}
reason_size += strlen(ERR_reason_error_string(e));
reasons = nc_realloc(reasons, reason_size);
NC_CHECK_ERRMEM_RET(!reasons, NULL);
reason_len += sprintf(reasons + reason_len, "%s", ERR_reason_error_string(e));
}
return reasons;
}
Thanks,
Chinni