nagios-plugins / nagios-plugins

Nagios Plugins
GNU General Public License v3.0
351 stars 330 forks source link

`check_http` segfault when SSL connection fails #778

Open mtelka opened 1 month ago

mtelka commented 1 month ago

I see the following segmentation fault on OpenIndiana:

$ /usr/libexec/nagios-plugins/check_http --ssl -H www.mozilla.com
CRITICAL - Cannot make SSL connection.
01000000:error:0A000410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:../../openssl-3.1.6/ssl/record/rec_layer_s3.c:1605:SSL alert number 40
Segmentation Fault (core dumped)
$

The segfault is caused by the die (STATE_CRITICAL, NULL) call here:

        result = np_net_ssl_init_with_hostname_version_and_cert(sd, (use_sni ? host_name : NULL), ssl_version, client_cert, client_privkey);
        if (verbose) printf ("SSL initialized\n");
        if (result != STATE_OK)
            die (STATE_CRITICAL, NULL);

which in turn causes the vprintf() is called with NULL in fmt here:

void
die (int result, const char *fmt, ...)
{
    va_list ap;
    va_start (ap, fmt);
    vprintf (fmt, ap);

and so the null pointer is dereferenced in vprintf().

mtelka commented 1 month ago

Here is a simple testcase to demonstrate the problem:

$ cat <<EOF > test.c 
#include <stdio.h>

int
main(void)
{
        printf(NULL);
        return 0;
}
EOF
$

When compiled it throws following warnings and segfaults on OpenIndiana:

$ gcc -Wall -o test test.c 
test.c: In function 'main':
test.c:6:9: warning: argument 1 null where non-null expected [-Wnonnull]
    6 |         printf(NULL);
      |         ^~~~~~
In file included from /usr/include/stdio.h:82,
                 from test.c:1:
/usr/include/iso/stdio_iso.h:208:17: note: in a call to function 'printf' declared 'nonnull'
  208 | extern int      printf(const char *_RESTRICT_KYWD, ...);
      |                 ^~~~~~
test.c:6:9: warning: null format string [-Wformat-overflow=]
    6 |         printf(NULL);
      |         ^~~~~~~~~~~~
$
$
$
$ ./test 
Segmentation Fault (core dumped)
$

While on Linux (Rocky 9) it produces similar warnings, but does not do the core dump:

$ gcc -Wall -o test test.c 
test.c: In function ‘main’:
test.c:6:9: warning: argument 1 null where non-null expected [-Wnonnull]
    6 |         printf(NULL);
      |         ^~~~~~
In file included from test.c:1:
/usr/include/stdio.h:350:12: note: in a call to function ‘printf’ declared ‘nonnull’
  350 | extern int printf (const char *__restrict __format, ...);
      |            ^~~~~~
test.c:6:9: warning: null format string [-Wformat-overflow=]
    6 |         printf(NULL);
      |         ^~~~~~~~~~~~
$
$
$
$ ./test
$

Apparently, portable applications should avoid to pass NULL as the format string to printf()/vprintf().