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;
}
/* 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,10 +292,11 @@ 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 (len > 0) {
if (func != NULL && file != NULL) {
if (errno_val) {
sudo_printf(SUDO_CONV_DEBUG_MSG, "%.*s: %s @ %s() %s:%d",
@@ -302,6 +313,15 @@ sudo_debug_write_conv(const char *func, const char *file, int lineno,
sudo_printf(SUDO_CONV_DEBUG_MSG, "%.*s", len, str);
}
}
} 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", strerror(errno_val));
}
}
}
static void
@@ -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) {
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 */
/* 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))

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);
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);