]> granicus.if.org Git - sudo/commitdiff
Add support to the debug subsystem for zero-length strings. This
authorTodd C. Miller <Todd.Miller@courtesan.com>
Thu, 15 Aug 2013 20:09:53 +0000 (14:09 -0600)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Thu, 15 Aug 2013 20:09:53 +0000 (14:09 -0600)
can happen for things like warning(NULL) or fatal(NULL) where we
just want to log the errno string.

common/sudo_debug.c
include/sudo_debug.h

index c46bf36349b1c0d9adcb5ce29148753ca4fa7de3..d5c356fa83279fc41a978e8879547a82378afc76 100644 (file)
@@ -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))
index ed1cd7147ef583e5a2ba81f02b24fbed07d51f62..ccc80ea5d5c0d31c8487bd8051642f1cd93dda64 100644 (file)
@@ -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);