tags 409600 -unreproducable
tags 409600 +patch
thanks
Hello,
I ran into this bug while trying to debug another problem.
My method to reproduce it is:
radvd -d 3 -u radvd -p /var/run/radvd/radvd.pid
with some options in /etc/radvd.conf that cause errors
due to user "radvd" not being able to write to /proc files.
For example "AdvLinkMTU 1480" causes the error "failed to
set LinkMTU (1480) for eth0" when configured like this.
It drove me nuts trying to track it down, but I eventually got it.
(I always miss fall-through cases at first!)
If you turn on debugging with "-d 3", then messages go both to syslog
and stderr when they are high priority. From log.c:vlog() --
case L_STDERR_SYSLOG:
vsnprintf(buff, sizeof(buff), format, ap);
syslog(prio, "%s", buff);
if (prio > LOG_ERR) /* fall through for messages with high priority */
break;
case L_STDERR:
// ... some stuff removed ...
vfprintf(stderr, format, ap);
If prio <= LOG_ERR, boom, the vfprintf crashes. You can't reuse a
va_list like that because vsnprintf will modify it (through va_args).
The attached patch just uses the va_list once to fill the buffer
and then uses that buffer for everything else.
-jim
diff -purN radvd-1.0-orig/log.c radvd-1.0/log.c
--- radvd-1.0-orig/log.c 2006-10-09 02:15:32.000000000 -0400
+++ radvd-1.0/log.c 2008-01-21 01:29:32.000000000 -0500
@@ -72,15 +72,15 @@ vlog(int prio, char *format, va_list ap)
struct tm *tm;
time_t current;
+ vsnprintf(buff, sizeof(buff), format, ap);
+
switch (log_method) {
case L_NONE:
break;
case L_SYSLOG:
- vsnprintf(buff, sizeof(buff), format, ap);
syslog(prio, "%s", buff);
break;
case L_STDERR_SYSLOG:
- vsnprintf(buff, sizeof(buff), format, ap);
syslog(prio, "%s", buff);
if (prio > LOG_ERR) /* fall through for messages with high priority */
break;
@@ -89,9 +89,7 @@ vlog(int prio, char *format, va_list ap)
tm = localtime(¤t);
(void) strftime(tstamp, sizeof(tstamp), LOG_TIME_FORMAT, tm);
- fprintf(stderr, "[%s] %s: ", tstamp, log_ident);
- vfprintf(stderr, format, ap);
- fputs("\n", stderr);
+ fprintf(stderr, "[%s] %s: %s\n", tstamp, log_ident, buff);
fflush(stderr);
break;
case L_LOGFILE:
@@ -99,9 +97,7 @@ vlog(int prio, char *format, va_list ap)
tm = localtime(¤t);
(void) strftime(tstamp, sizeof(tstamp), LOG_TIME_FORMAT, tm);
- fprintf(log_file_fd, "[%s] %s: ", tstamp, log_ident);
- vfprintf(log_file_fd, format, ap);
- fputs("\n", log_file_fd);
+ fprintf(log_file_fd, "[%s] %s: %s\n", tstamp, log_ident, buff);
fflush(log_file_fd);
break;
default: