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.
This commit is contained in:
Todd C. Miller
2013-08-15 14:09:53 -06:00
parent a44d827636
commit bec394dc11
2 changed files with 68 additions and 63 deletions

View File

@@ -155,8 +155,14 @@ int sudo_debug_init(const char *debugfile, const char *settings)
sudo_debug_mode = SUDO_DEBUG_MODE_CONV; 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. */ /* Parse settings string. */
buf = estrdup(settings); if ((buf = strdup(settings)) == NULL)
return 0;
for ((cp = strtok(buf, ",")); cp != NULL; (cp = strtok(NULL, ","))) { for ((cp = strtok(buf, ",")); cp != NULL; (cp = strtok(NULL, ","))) {
/* Should be in the form subsys@pri. */ /* Should be in the form subsys@pri. */
subsys = cp; subsys = cp;
@@ -181,11 +187,7 @@ int sudo_debug_init(const char *debugfile, const char *settings)
} }
} }
} }
efree(buf); free(buf);
(void)snprintf(sudo_debug_pidstr, sizeof(sudo_debug_pidstr), "[%d] ",
(int)getpid());
sudo_debug_pidlen = strlen(sudo_debug_pidstr);
return 1; return 1;
} }
@@ -212,28 +214,32 @@ sudo_debug_enter(const char *func, const char *file, int line,
"-> %s @ %s:%d", func, file, 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) int subsys)
{ {
sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE, sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
"<- %s @ %s:%d", func, file, line); "<- %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) int subsys, int rval)
{ {
sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE, sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
"<- %s @ %s:%d := %d", func, file, line, rval); "<- %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) int subsys, long rval)
{ {
sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE, sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
"<- %s @ %s:%d := %ld", func, file, line, rval); "<- %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) int subsys, size_t rval)
{ {
/* XXX - should use %zu but our snprintf.c doesn't support it */ /* 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. */ /* 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) int subsys, int rval)
{ {
if (rval == true || rval == false) { 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) int subsys, const char *rval)
{ {
sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE, sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE,
"<- %s @ %s:%d := %s", func, file, line, rval ? rval : "(null)"); "<- %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) int subsys, const char *rval)
{ {
static const char stars[] = "********************************************************************************"; 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)"); "<- %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) int subsys, const void *rval)
{ {
sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE, 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, sudo_debug_write_conv(const char *func, const char *file, int lineno,
const char *str, int len, int errno_val) const char *str, int len, int errno_val)
{ {
/* Remove the newline at the end if appending extra info. */ /* Remove trailing newlines. */
if (str[len - 1] == '\n') while (len > 0 && str[len - 1] == '\n')
len--; len--;
if (func != NULL && file != NULL) { if (len > 0) {
if (errno_val) { if (func != NULL && file != NULL) {
sudo_printf(SUDO_CONV_DEBUG_MSG, "%.*s: %s @ %s() %s:%d", if (errno_val) {
len, str, strerror(errno_val), func, file, lineno); 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 { } else {
sudo_printf(SUDO_CONV_DEBUG_MSG, "%.*s @ %s() %s:%d", if (errno_val) {
len, str, func, file, lineno); sudo_printf(SUDO_CONV_DEBUG_MSG, "%.*s: %s",
len, str, strerror(errno_val));
} else {
sudo_printf(SUDO_CONV_DEBUG_MSG, "%.*s", len, str);
}
} }
} else { } else if (errno_val) {
if (errno_val) { /* Only print error string. */
sudo_printf(SUDO_CONV_DEBUG_MSG, "%.*s: %s", if (func != NULL && file != NULL) {
len, str, strerror(errno_val)); sudo_printf(SUDO_CONV_DEBUG_MSG, "%s @ %s() %s:%d",
strerror(errno_val), func, file, lineno);
} else { } 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]; char *timestr, numbuf[(((sizeof(int) * 8) + 2) / 3) + 2];
time_t now; time_t now;
struct iovec iov[12]; struct iovec iov[12];
int iovcnt = 4; int iovcnt = 3;
bool need_newline = false;
/* Prepend program name and pid with a trailing space. */ /* Prepend program name and pid with a trailing space. */
iov[1].iov_base = (char *)getprogname(); 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; iov[2].iov_len = sudo_debug_pidlen;
/* Add string along with newline if it doesn't have one. */ /* Add string along with newline if it doesn't have one. */
iov[3].iov_base = (char *)str; if (len > 0) {
iov[3].iov_len = len; iov[iovcnt].iov_base = (char *)str;
if (str[len - 1] != '\n') iov[iovcnt].iov_len = len;
need_newline = true; while (len > 0 && str[len - 1] == '\n')
iov[iovcnt].iov_len--;
iovcnt++;
}
/* Append error string if errno is specified. */ /* Append error string if errno is specified. */
if (errno_val) { if (errno_val) {
iov[iovcnt].iov_base = ": "; if (len > 0) {
iov[iovcnt].iov_len = 2; iov[iovcnt].iov_base = ": ";
iovcnt++; iov[iovcnt].iov_len = 2;
iovcnt++;
}
iov[iovcnt].iov_base = strerror(errno_val); iov[iovcnt].iov_base = strerror(errno_val);
iov[iovcnt].iov_len = strlen(iov[iovcnt].iov_base); iov[iovcnt].iov_len = strlen(iov[iovcnt].iov_base);
iovcnt++; 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. */ /* 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_base = numbuf;
iov[iovcnt].iov_len = strlen(numbuf); iov[iovcnt].iov_len = strlen(numbuf);
iovcnt++; iovcnt++;
/* Move newline to the end. */
if (!need_newline) {
need_newline = true;
iov[3].iov_len--;
}
} }
/* Append newline as needed. */ /* Append newline. */
if (need_newline) { iov[iovcnt].iov_base = "\n";
/* force newline */ iov[iovcnt].iov_len = 1;
iov[iovcnt].iov_base = "\n"; iovcnt++;
iov[iovcnt].iov_len = 1;
iovcnt++;
}
/* Do timestamp last due to ctime's static buffer. */ /* Do timestamp last due to ctime's static buffer. */
time(&now); time(&now);
@@ -396,9 +405,6 @@ void
sudo_debug_write2(const char *func, const char *file, int lineno, sudo_debug_write2(const char *func, const char *file, int lineno,
const char *str, int len, int errno_val) const char *str, int len, int errno_val)
{ {
if (len <= 0)
return;
switch (sudo_debug_mode) { switch (sudo_debug_mode) {
case SUDO_DEBUG_MODE_CONV: case SUDO_DEBUG_MODE_CONV:
sudo_debug_write_conv(func, file, lineno, str, len, errno_val); 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) const char *fmt, va_list ap)
{ {
int buflen, pri, subsys, saved_errno = errno; int buflen, pri, subsys, saved_errno = errno;
char *buf; char *buf = NULL;
if (!sudo_debug_mode) if (!sudo_debug_mode)
return; 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. */ /* Make sure we want debug info at this level. */
if (subsys < NUM_SUBSYSTEMS && sudo_debug_settings[subsys] >= pri) { if (subsys < NUM_SUBSYSTEMS && sudo_debug_settings[subsys] >= pri) {
buflen = vasprintf(&buf, fmt, ap); buflen = fmt ? vasprintf(&buf, fmt, ap) : 0;
va_end(ap);
if (buflen != -1) { if (buflen != -1) {
int errcode = ISSET(level, SUDO_DEBUG_ERRNO) ? saved_errno : 0; int errcode = ISSET(level, SUDO_DEBUG_ERRNO) ? saved_errno : 0;
if (ISSET(level, SUDO_DEBUG_LINENO)) if (ISSET(level, SUDO_DEBUG_LINENO))

View 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); 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_fd_set(int fd);
int sudo_debug_init(const char *debugfile, const char *settings); 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_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); 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_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); 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); pid_t sudo_debug_fork(void);