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(&current);
 			(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(&current);
 			(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:

Reply via email to