Bug 16355

Summary: syslog.h's SYSLOG_NAMES namespace violation and utter mess
Product: glibc Reporter: Rich Felker <bugdal>
Component: libcAssignee: Not yet assigned to anyone <unassigned>
Status: NEW ---    
Severity: normal CC: drepper.fsp
Priority: P2 Flags: fweimer: security-
Version: unspecified   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:

Description Rich Felker 2013-12-20 18:18:06 UTC
syslog.h badly violates the namespace and not just declares but defines arrays facilitynames[] and prioritynames[] if the macro SYSLOG_NAMES is defined by the application. This is non-conforming since SYSLOG_NAMES is in the namespace belonging to the application. Technically the conformance issue could be fixed by changing:



#if defined(SYSLOG_NAMES) && defined(__USE_MISC)

or similar, but the whole thing is still really bad behavior. In particular, only one translation unit can define SYSLOG_NAMES, since it causes definitions for the arrays to be emitted. And there's no way to access the arrays from other translation units since there's no way to request declarations without definitions.

Most possible fixes have drawbacks:

1. facilitynames could be made external and moved into libc, with just a declaration in the header. This is really bad because it results in a copy relocation and the size of the array becomes part of the ABI.

2. facilitynames could be #defined as (__get_facilitynames()), with CODE *__get_facilitynames(); This is bad because it breaks applications that assume it has array type (e.g. that sizeof is meaningful).

3. facilitynames could be #defined as (*__get_facilitynames()) or similar, with CODE (*__get_facilitynames())[N]; This hard-codes the size as part of the ABI but at least eliminates the copy relocation.

4. facilitynames could be given internal linkage (static). This probably couldn't break anything, but I'm not sure.

5. facilitynames could be defined as a macro expanding to a compound literal array. This is also unlikely to break anything (except maybe -std=c89 -pedantic-errors or something) but it does result in bloat when the array is used in more than one place.

Other ideas welcome...
Comment 1 Andreas Schwab 2013-12-20 22:46:01 UTC
SYSLOG_NAMES is defined by the syslogd source to get the definition of facilitynames and prioritynames, see <http://svnweb.freebsd.org/base/head/usr.sbin/syslogd/syslogd.c?revision=258077&view=markup>.  As such it can safely be removed.
Comment 2 Rich Felker 2013-12-20 23:04:20 UTC
Andreas, what? Your comment makes no sense. First you say it's defined by an application (FreeBSD syslogd, which probably is not the one used on most glibc-based systems...) to get these definitions, and then you say it's safe to remove (it's not; it would break the application).

At the very least, several syslogd implementations, including Busybox syslogd, define SYSLOG_NAMES to get these definitions. So just removing them would need to be coordinated with programs using them. It's _probably_ safe to just move the whole mess under __USE_MISC though to fix the conformance issue.
Comment 3 Andreas Schwab 2013-12-20 23:56:12 UTC
FreeBSD never uses glibc's syslog.h.