From 63350438907483a86fdb6e4d6cb7891644bc2ea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Fri, 21 Dec 2018 12:39:51 +0100 Subject: [PATCH 1/2] Improve printing of the cmdline - Print control characters in octal - Shorten using an ellipsis when necessary --- bin/named/main.c | 91 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 62 insertions(+), 29 deletions(-) diff --git a/bin/named/main.c b/bin/named/main.c index e4afdc5a6a..dbe39772db 100644 --- a/bin/named/main.c +++ b/bin/named/main.c @@ -110,7 +110,8 @@ LIBDNS_EXTERNAL_DATA extern unsigned int dns_zone_mkey_month; static bool want_stats = false; static char program_name[NAME_MAX] = "named"; static char absolute_conffile[PATH_MAX]; -static char saved_command_line[512]; +static char saved_command_line[8192] = { 0 }; +static char ellipsis[5] = { 0 }; static char version[512]; static unsigned int maxsocks = 0; static int maxudp = 0; @@ -335,44 +336,76 @@ usage(void) { static void save_command_line(int argc, char *argv[]) { int i; - char *src; - char *dst; - char *eob; - const char truncated[] = "..."; - bool quoted = false; - - dst = saved_command_line; - eob = saved_command_line + sizeof(saved_command_line); + char *dst = saved_command_line; + char *eob = saved_command_line + sizeof(saved_command_line) - 1; + char *rollback; for (i = 1; i < argc && dst < eob; i++) { + char *src = argv[i]; + bool quoted = false; + + rollback = dst; *dst++ = ' '; - src = argv[i]; while (*src != '\0' && dst < eob) { - /* - * This won't perfectly produce a shell-independent - * pastable command line in all circumstances, but - * comes close, and for practical purposes will - * nearly always be fine. - */ - if (quoted || isalnum(*src & 0xff) || + if (isalnum(*src) || *src == '-' || *src == '_' || - *src == '.' || *src == '/') { + *src == '.' || *src == '/') + { *dst++ = *src++; - quoted = false; - } else { + } else if (isprint(*src)) { + if (dst + 2 >= eob) { + goto add_ellipsis; + } *dst++ = '\\'; - quoted = true; + *dst++ = *src++; + } else { + /* + * Control character found in the input, + * quote the whole arg and restart + */ + if (!quoted) { + dst = rollback; + src = argv[i]; + + if (dst + 3 >= eob) { + goto add_ellipsis; + } + + *dst++ = ' '; + *dst++ = '$'; + *dst++ = '\''; + + quoted = true; + continue; + } else { + char tmp[5]; + int c = snprintf(tmp, sizeof(tmp), + "\\%03o", *src++); + if (dst + c >= eob) { + goto add_ellipsis; + } + memmove(dst, tmp, c); + dst += c; + } } } + if (quoted) { + if (dst == eob) { + goto add_ellipsis; + } + *dst++ = '\''; + } + } - INSIST(sizeof(saved_command_line) >= sizeof(truncated)); - - if (dst == eob) - strcpy(eob - sizeof(truncated), truncated); - else - *dst = '\0'; + if (dst < eob) { + return; + } +add_ellipsis: + dst = rollback; + *dst = '\0'; + strlcpy(ellipsis, " ...", sizeof(ellipsis)); } static int @@ -1005,8 +1038,8 @@ setup(void) { isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN, ISC_LOG_NOTICE, - "running as: %s%s", - program_name, saved_command_line); + "running as: %s%s%s", + program_name, saved_command_line, ellipsis); #ifdef __clang__ isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN, ISC_LOG_NOTICE, From 6acc306b107e51639a099bdfd179f3786f698b09 Mon Sep 17 00:00:00 2001 From: Joey Salazar Date: Thu, 10 Jan 2019 21:01:54 +0800 Subject: [PATCH 2/2] Test named logs cmd line as expected Test named logs control characters, special characters and large cmd line respectively as octal escaped, special escaped and elipsis --- bin/tests/system/runtime/clean.sh | 2 + bin/tests/system/runtime/ctrl-char-dir-name | 1 + .../system/runtime/ns2/named-alt7.conf.in | 17 +++++++ bin/tests/system/runtime/tests.sh | 46 +++++++++++++++++++ util/copyrights | 1 + 5 files changed, 67 insertions(+) create mode 100644 bin/tests/system/runtime/ctrl-char-dir-name create mode 100644 bin/tests/system/runtime/ns2/named-alt7.conf.in diff --git a/bin/tests/system/runtime/clean.sh b/bin/tests/system/runtime/clean.sh index 1be52649b0..705e88e005 100644 --- a/bin/tests/system/runtime/clean.sh +++ b/bin/tests/system/runtime/clean.sh @@ -18,3 +18,5 @@ rm -f rndc.out* [ -d ns2/nope ] && chmod 755 ns2/nope rm -rf ns2/nope rm -f ns*/managed-keys.bind* +rm -rf "ns2/`cat ctrl-char-dir-name`" +rm -rf "ns2/$;" diff --git a/bin/tests/system/runtime/ctrl-char-dir-name b/bin/tests/system/runtime/ctrl-char-dir-name new file mode 100644 index 0000000000..4ce1650114 --- /dev/null +++ b/bin/tests/system/runtime/ctrl-char-dir-name @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bin/tests/system/runtime/ns2/named-alt7.conf.in b/bin/tests/system/runtime/ns2/named-alt7.conf.in new file mode 100644 index 0000000000..8b8a20a56b --- /dev/null +++ b/bin/tests/system/runtime/ns2/named-alt7.conf.in @@ -0,0 +1,17 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +options { + port @PORT@; + pid-file "named7.pid"; + listen-on { 10.53.0.2; }; + listen-on-v6 { fd92:7065:b8e:ffff::2; }; +}; diff --git a/bin/tests/system/runtime/tests.sh b/bin/tests/system/runtime/tests.sh index 343adebc6b..31fe17cad5 100644 --- a/bin/tests/system/runtime/tests.sh +++ b/bin/tests/system/runtime/tests.sh @@ -113,5 +113,51 @@ cd .. if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` +n=`expr $n + 1` +echo_i "checking that named logs control characters in octal notation ($n)" +ret=0 +SPEC_DIR=`cat ctrl-char-dir-name` +mkdir "ns2/${SPEC_DIR}" +copy_setports ns2/named-alt7.conf.in "ns2/${SPEC_DIR}/named.conf" +cd ns2 +$NAMED -c "${SPEC_DIR}/named.conf" -d 99 -g > named6.run 2>&1 & +sleep 2 +grep 'running as.*\\177\\033' named6.run > /dev/null || ret=1 +pid=`cat named7.pid 2>/dev/null` +test "${pid:+set}" = set && $KILL -15 ${pid} >/dev/null 2>&1 +cd .. +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo_i "checking that named escapes special characters in the logs ($n)" +ret=0 +SPEC_DIR="$;" +mkdir "ns2/${SPEC_DIR}" +copy_setports ns2/named-alt7.conf.in "ns2/${SPEC_DIR}/named.conf" +cd ns2 +$NAMED -c "${SPEC_DIR}/named.conf" -d 99 -g > named7.run 2>&1 & +sleep 2 +grep 'running as.*\\$\\;' named7.run > /dev/null || ret=1 +pid=`cat named7.pid 2>/dev/null` +test "${pid:+set}" = set && $KILL -15 ${pid} >/dev/null 2>&1 +cd .. +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo_i "checking that named logs an ellipsis when the command line is larger than 8k bytes ($n)" +ret=0 +SPEC_DIR=`yes | head -10000 | tr -d '\n'` +cd ns2 +$NAMED -c "${SPEC_DIR}/named.conf" -d 99 -g > named8.run 2>&1 & +sleep 2 +grep "running as.*\.\.\.$" named8.run > /dev/null || ret=1 +pid=`cat named7.pid 2>/dev/null` +test "${pid:+set}" = set && $KILL -15 ${pid} >/dev/null 2>&1 +cd .. +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + echo_i "exit status: $status" [ $status -eq 0 ] || exit 1 diff --git a/util/copyrights b/util/copyrights index 5ad20e0577..bdf6d6286f 100644 --- a/util/copyrights +++ b/util/copyrights @@ -1016,6 +1016,7 @@ ./bin/tests/system/runsequential.sh SH 2018,2019 ./bin/tests/system/runtime/README TXT.BRIEF 2014,2016,2018,2019 ./bin/tests/system/runtime/clean.sh SH 2014,2015,2016,2017,2018,2019 +./bin/tests/system/runtime/ctrl-char-dir-name X 2019 ./bin/tests/system/runtime/setup.sh SH 2015,2016,2017,2018,2019 ./bin/tests/system/runtime/tests.sh SH 2014,2015,2016,2017,2018,2019 ./bin/tests/system/send.pl PERL 2001,2004,2007,2011,2012,2016,2018,2019