[PATCH] Core: print "(null)" on NULL for "%s" in ngx_vslprintf

Александр А. Стрелец xoiss at yandex-team.ru
Thu Apr 4 16:56:23 UTC 2019


# HG changeset patch
# User Alexander A. Strelets <streletsaa at gmail.com>
# Date 1554396620 -10800
#      Thu Apr 04 19:50:20 2019 +0300
# Node ID cf212fc46cb7025b33dfb7313b5191eb09330446
# Parent  7da71a7b141abf417d334dfaca8a13f01c9fe3f5
Core: print "(null)" on NULL for "%s" in ngx_vslprintf

When NULL is passes with arguments for "%s" format specifier to ngx_vslprintf (or other ngx_printf-like derivative), ngx_vslprintf really tries to access 0 address which triggers SIGSEGV, while conventional printf just literally prints "(null)" without an error. This is a reach source of hidden bugs in numerous calls to ngx_log_error, ngx_log_debug, etc. which are normally not called and not covered with tests. This case may be hit, for example, with ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "pread() \"%s\" failed", file->name.data); in nginx/src/os/unix/ngx_files.c, lines 40-46, in case file->name.data was left initially assigned with NULL (i.e. the user gets SIGSEGV instead of an [error]-record in the log).

diff -r 7da71a7b141a -r cf212fc46cb7 src/core/ngx_string.c
--- a/src/core/ngx_string.c	Thu Apr 04 16:26:56 2019 +0300
+++ b/src/core/ngx_string.c	Thu Apr 04 19:50:20 2019 +0300
@@ -16,6 +16,8 @@
 static ngx_int_t ngx_decode_base64_internal(ngx_str_t *dst, ngx_str_t *src,
     const u_char *basis);
 
+static const char ngx_string_literal_null[] = "(null)";
+
 
 void
 ngx_strlow(u_char *dst, u_char *src, size_t n)
@@ -268,6 +270,13 @@
             case 's':
                 p = va_arg(args, u_char *);
 
+                if (p == NULL) {
+                    p = (u_char *) ngx_string_literal_null;
+                    if (slen != (size_t) -1) {
+                        slen = ngx_min(slen, sizeof(ngx_string_literal_null) - 1);
+                    }
+                }
+
                 if (slen == (size_t) -1) {
                     while (*p && buf < last) {
                         *buf++ = *p++;



More information about the nginx-devel mailing list