From: Todd C. Miller Date: Thu, 15 Aug 2013 20:09:53 +0000 (-0600) Subject: Add support to the debug subsystem for zero-length strings. This X-Git-Tag: SUDO_1_8_8^2~55 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bec394dc11e29f2b34206ff1fab01ea46f589d13;p=sudo Add support to the debug subsystem for zero-length strings. This can happen for things like warning(NULL) or fatal(NULL) where we just want to log the errno string. --- diff --git a/common/sudo_debug.c b/common/sudo_debug.c index c46bf3634..d5c356fa8 100644 --- a/common/sudo_debug.c +++ b/common/sudo_debug.c @@ -155,8 +155,14 @@ int sudo_debug_init(const char *debugfile, const char *settings) sudo_debug_mode = SUDO_DEBUG_MODE_CONV; } + /* Stash the pid string so we only have to format it once. */ + (void)snprintf(sudo_debug_pidstr, sizeof(sudo_debug_pidstr), "[%d] ", + (int)getpid()); + sudo_debug_pidlen = strlen(sudo_debug_pidstr); + /* Parse settings string. */ - buf = estrdup(settings); + if ((buf = strdup(settings)) == NULL) + return 0; for ((cp = strtok(buf, ",")); cp != NULL; (cp = strtok(NULL, ","))) { /* Should be in the form subsys@pri. */ subsys = cp; @@ -181,11 +187,7 @@ int sudo_debug_init(const char *debugfile, const char *settings) } } } - efree(buf); - - (void)snprintf(sudo_debug_pidstr, sizeof(sudo_debug_pidstr), "[%d] ", - (int)getpid()); - sudo_debug_pidlen = strlen(sudo_debug_pidstr); + free(buf); return 1; } @@ -212,28 +214,32 @@ sudo_debug_enter(const char *func, const char *file, int line, "-> %s @ %s:%d", func, file, line); } -void sudo_debug_exit(const char *func, const char *file, int line, +void +sudo_debug_exit(const char *func, const char *file, int line, int subsys) { sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE, "<- %s @ %s:%d", func, file, line); } -void sudo_debug_exit_int(const char *func, const char *file, int line, +void +sudo_debug_exit_int(const char *func, const char *file, int line, int subsys, int rval) { sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE, "<- %s @ %s:%d := %d", func, file, line, rval); } -void sudo_debug_exit_long(const char *func, const char *file, int line, +void +sudo_debug_exit_long(const char *func, const char *file, int line, int subsys, long rval) { sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE, "<- %s @ %s:%d := %ld", func, file, line, rval); } -void sudo_debug_exit_size_t(const char *func, const char *file, int line, +void +sudo_debug_exit_size_t(const char *func, const char *file, int line, int subsys, size_t rval) { /* XXX - should use %zu but our snprintf.c doesn't support it */ @@ -242,7 +248,8 @@ void sudo_debug_exit_size_t(const char *func, const char *file, int line, } /* We use int, not bool, here for functions that return -1 on error. */ -void sudo_debug_exit_bool(const char *func, const char *file, int line, +void +sudo_debug_exit_bool(const char *func, const char *file, int line, int subsys, int rval) { if (rval == true || rval == false) { @@ -254,14 +261,16 @@ void sudo_debug_exit_bool(const char *func, const char *file, int line, } } -void sudo_debug_exit_str(const char *func, const char *file, int line, +void +sudo_debug_exit_str(const char *func, const char *file, int line, int subsys, const char *rval) { sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE, "<- %s @ %s:%d := %s", func, file, line, rval ? rval : "(null)"); } -void sudo_debug_exit_str_masked(const char *func, const char *file, int line, +void +sudo_debug_exit_str_masked(const char *func, const char *file, int line, int subsys, const char *rval) { static const char stars[] = "********************************************************************************"; @@ -271,7 +280,8 @@ void sudo_debug_exit_str_masked(const char *func, const char *file, int line, "<- %s @ %s:%d := %.*s", func, file, line, len, rval ? stars : "(null)"); } -void sudo_debug_exit_ptr(const char *func, const char *file, int line, +void +sudo_debug_exit_ptr(const char *func, const char *file, int line, int subsys, const void *rval) { sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE, @@ -282,24 +292,34 @@ static void sudo_debug_write_conv(const char *func, const char *file, int lineno, const char *str, int len, int errno_val) { - /* Remove the newline at the end if appending extra info. */ - if (str[len - 1] == '\n') + /* Remove trailing newlines. */ + while (len > 0 && str[len - 1] == '\n') len--; - if (func != NULL && file != NULL) { - if (errno_val) { - sudo_printf(SUDO_CONV_DEBUG_MSG, "%.*s: %s @ %s() %s:%d", - len, str, strerror(errno_val), func, file, lineno); + if (len > 0) { + if (func != NULL && file != NULL) { + if (errno_val) { + sudo_printf(SUDO_CONV_DEBUG_MSG, "%.*s: %s @ %s() %s:%d", + len, str, strerror(errno_val), func, file, lineno); + } else { + sudo_printf(SUDO_CONV_DEBUG_MSG, "%.*s @ %s() %s:%d", + len, str, func, file, lineno); + } } else { - sudo_printf(SUDO_CONV_DEBUG_MSG, "%.*s @ %s() %s:%d", - len, str, func, file, lineno); + if (errno_val) { + sudo_printf(SUDO_CONV_DEBUG_MSG, "%.*s: %s", + len, str, strerror(errno_val)); + } else { + sudo_printf(SUDO_CONV_DEBUG_MSG, "%.*s", len, str); + } } - } else { - if (errno_val) { - sudo_printf(SUDO_CONV_DEBUG_MSG, "%.*s: %s", - len, str, strerror(errno_val)); + } else if (errno_val) { + /* Only print error string. */ + if (func != NULL && file != NULL) { + sudo_printf(SUDO_CONV_DEBUG_MSG, "%s @ %s() %s:%d", + strerror(errno_val), func, file, lineno); } else { - sudo_printf(SUDO_CONV_DEBUG_MSG, "%.*s", len, str); + sudo_printf(SUDO_CONV_DEBUG_MSG, "%s", strerror(errno_val)); } } } @@ -311,8 +331,7 @@ sudo_debug_write_file(const char *func, const char *file, int lineno, char *timestr, numbuf[(((sizeof(int) * 8) + 2) / 3) + 2]; time_t now; struct iovec iov[12]; - int iovcnt = 4; - bool need_newline = false; + int iovcnt = 3; /* Prepend program name and pid with a trailing space. */ iov[1].iov_base = (char *)getprogname(); @@ -321,25 +340,24 @@ sudo_debug_write_file(const char *func, const char *file, int lineno, iov[2].iov_len = sudo_debug_pidlen; /* Add string along with newline if it doesn't have one. */ - iov[3].iov_base = (char *)str; - iov[3].iov_len = len; - if (str[len - 1] != '\n') - need_newline = true; + if (len > 0) { + iov[iovcnt].iov_base = (char *)str; + iov[iovcnt].iov_len = len; + while (len > 0 && str[len - 1] == '\n') + iov[iovcnt].iov_len--; + iovcnt++; + } /* Append error string if errno is specified. */ if (errno_val) { - iov[iovcnt].iov_base = ": "; - iov[iovcnt].iov_len = 2; - iovcnt++; + if (len > 0) { + iov[iovcnt].iov_base = ": "; + iov[iovcnt].iov_len = 2; + iovcnt++; + } iov[iovcnt].iov_base = strerror(errno_val); iov[iovcnt].iov_len = strlen(iov[iovcnt].iov_base); iovcnt++; - - /* Move newline to the end. */ - if (!need_newline) { - need_newline = true; - iov[3].iov_len--; - } } /* If function, file and lineno are specified, append them. */ @@ -364,21 +382,12 @@ sudo_debug_write_file(const char *func, const char *file, int lineno, iov[iovcnt].iov_base = numbuf; iov[iovcnt].iov_len = strlen(numbuf); iovcnt++; - - /* Move newline to the end. */ - if (!need_newline) { - need_newline = true; - iov[3].iov_len--; - } } - /* Append newline as needed. */ - if (need_newline) { - /* force newline */ - iov[iovcnt].iov_base = "\n"; - iov[iovcnt].iov_len = 1; - iovcnt++; - } + /* Append newline. */ + iov[iovcnt].iov_base = "\n"; + iov[iovcnt].iov_len = 1; + iovcnt++; /* Do timestamp last due to ctime's static buffer. */ time(&now); @@ -396,9 +405,6 @@ void sudo_debug_write2(const char *func, const char *file, int lineno, const char *str, int len, int errno_val) { - if (len <= 0) - return; - switch (sudo_debug_mode) { case SUDO_DEBUG_MODE_CONV: sudo_debug_write_conv(func, file, lineno, str, len, errno_val); @@ -421,7 +427,7 @@ sudo_debug_vprintf2(const char *func, const char *file, int lineno, int level, const char *fmt, va_list ap) { int buflen, pri, subsys, saved_errno = errno; - char *buf; + char *buf = NULL; if (!sudo_debug_mode) return; @@ -432,8 +438,7 @@ sudo_debug_vprintf2(const char *func, const char *file, int lineno, int level, /* Make sure we want debug info at this level. */ if (subsys < NUM_SUBSYSTEMS && sudo_debug_settings[subsys] >= pri) { - buflen = vasprintf(&buf, fmt, ap); - va_end(ap); + buflen = fmt ? vasprintf(&buf, fmt, ap) : 0; if (buflen != -1) { int errcode = ISSET(level, SUDO_DEBUG_ERRNO) ? saved_errno : 0; if (ISSET(level, SUDO_DEBUG_LINENO)) diff --git a/include/sudo_debug.h b/include/sudo_debug.h index ed1cd7147..ccc80ea5d 100644 --- a/include/sudo_debug.h +++ b/include/sudo_debug.h @@ -201,8 +201,8 @@ void sudo_debug_exit_str_masked(const char *func, const char *file, int line, in void sudo_debug_exit_ptr(const char *func, const char *file, int line, int subsys, const void *rval); int sudo_debug_fd_set(int fd); int sudo_debug_init(const char *debugfile, const char *settings); -void sudo_debug_printf2(const char *func, const char *file, int line, int level, const char *fmt, ...) __printflike(5, 6); -void sudo_debug_vprintf2(const char *func, const char *file, int line, int level, const char *fmt, va_list ap); +void sudo_debug_printf2(const char *func, const char *file, int line, int level, const char *fmt, ...) __printf0like(5, 6); +void sudo_debug_vprintf2(const char *func, const char *file, int line, int level, const char *fmt, va_list ap) __printf0like(5, 0); void sudo_debug_write(const char *str, int len, int errno_val); void sudo_debug_write2(const char *func, const char *file, int line, const char *str, int len, int errno_val); pid_t sudo_debug_fork(void);