[net.bugs.4bsd] Bug in C library syslog

crp@ccivax.UUCP (Chuck Privitera) (03/28/85)

Index:	/usr/src/lib/libc/gen/syslog.c 4.2BSD +FIX

Description:
	The syslog subroutine in the C library does not handle
	printf format specifications correctly. The syslog subroutine
	that sendmail uses (/usr/src/usr.lib/sendmail/lib/syslog.c)
	does. Messages handed to syslog that contain printf format
	specifications will not be printed in the system log(s).
Repeat-By:
	Try this simple test program:

	#include <syslog.h>
	main()
	{
		int i;

		/*
		 * None of the following will be added to
		 * the system log(s).
		 */
		for(i = 1; i < 10; i++)
			syslog(i, "Test message %d", i);
		syslog(LOG_INFO, "But this will be added");
	}
Fix:
	The problem is that syslog looks for format specifications
	so it can handle %m which means interpolate the system error
	message for the current value of errno. It handles %m allright,
	but %AnythingElse fails because after copying in the format
	specification it adds a '\0' to terminate the line and then
	increments the pointer PAST the null terminator. Thus you
	have a null byte in your message. This would be fine if
	the syslog daemon didn't throw out messages that don't
	have a newline at the end of them. The fix is simple,
	you can either simply delete the addition of the null
	terminator, or don't increment the pointer after adding
	the null terminator. The addition of the null terminator
	is just a remnant of an older version of syslog that handled
	the % special case with a switch and upon falling out of
	the switch did ptr += strlen(ptr). It no longer gets to
	that line for printf format specifications. Here is a
	visual aid for the two character fix:


diff  old new
73c73
< 				*b++ = '%', *b++ = c, *b++ = '\0';
---
> 				*b++ = '%', *b++ = c, *b = '\0';