Index: rsyslog/ChangeLog
===================================================================
--- rsyslog.orig/ChangeLog	2014-09-27 00:21:21.654998869 +0200
+++ rsyslog/ChangeLog	2014-09-27 00:21:21.650998781 +0200
@@ -1721,6 +1721,8 @@
   closes: http://bugzilla.adiscon.com/show_bug.cgi?id=271
 - improved some code based on clang static analyzer results
 - bugfix: potential misadressing in property replacer
+- bugfix: improper handling of invalid PRI values
+  references: CVE-2014-3634
 ---------------------------------------------------------------------------
 Version 3.22.3 [v3-stable] (rgerhards), 2010-11-24
 - bugfix(important): problem in TLS handling could cause rsyslog to loop
Index: rsyslog/configure.ac
===================================================================
--- rsyslog.orig/configure.ac	2014-09-27 00:21:21.654998869 +0200
+++ rsyslog/configure.ac	2014-09-27 00:21:21.650998781 +0200
@@ -76,7 +76,7 @@
 AC_HEADER_RESOLV
 AC_HEADER_STDC
 AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS([arpa/inet.h libgen.h malloc.h fcntl.h locale.h netdb.h netinet/in.h paths.h stddef.h stdlib.h string.h sys/file.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h sys/stat.h syslog.h unistd.h utmp.h utmpx.h sys/epoll.h sys/prctl.h])
+AC_CHECK_HEADERS([arpa/inet.h libgen.h malloc.h fcntl.h locale.h netdb.h netinet/in.h paths.h stddef.h stdlib.h string.h sys/file.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h sys/stat.h unistd.h utmp.h utmpx.h sys/epoll.h sys/prctl.h])
 
 # Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
Index: rsyslog/plugins/imfile/imfile.c
===================================================================
--- rsyslog.orig/plugins/imfile/imfile.c	2014-09-27 00:21:21.654998869 +0200
+++ rsyslog/plugins/imfile/imfile.c	2014-09-27 00:21:21.650998781 +0200
@@ -118,8 +118,8 @@
 	MsgSetMSGoffs(pMsg, 0);	/* we do not have a header... */
 	MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName()));
 	MsgSetTAG(pMsg, pInfo->pszTag, pInfo->lenTag);
-	pMsg->iFacility = LOG_FAC(pInfo->iFacility);
-	pMsg->iSeverity = LOG_PRI(pInfo->iSeverity);
+	pMsg->iFacility = pri2fac(pInfo->iFacility);
+	pMsg->iSeverity = pri2sev(pInfo->iSeverity);
 	MsgSetRuleset(pMsg, pInfo->pRuleset);
 	CHKiRet(submitMsg(pMsg));
 finalize_it:
Index: rsyslog/plugins/imklog/imklog.c
===================================================================
--- rsyslog.orig/plugins/imklog/imklog.c	2014-09-27 00:21:21.654998869 +0200
+++ rsyslog/plugins/imklog/imklog.c	2014-09-27 00:21:21.650998781 +0200
@@ -173,7 +173,7 @@
 	va_end(ap);
 
 	iRet = enqMsg((uchar*)pLogMsg, (uchar*) ((iFacilIntMsg == LOG_KERN) ? "kernel:" : "imklog:"),
-		      iFacilIntMsg, LOG_PRI(priority));
+		      iFacilIntMsg, pri2sev(priority));
 
 	RETiRet;
 }
@@ -194,10 +194,10 @@
 	/* if we don't get the pri, we use whatever we were supplied */
 
 	/* ignore non-kernel messages if not permitted */
-	if(bPermitNonKernel == 0 && LOG_FAC(priority) != LOG_KERN)
+	if(bPermitNonKernel == 0 && pri2fac(priority) != LOG_KERN)
 		FINALIZE; /* silently ignore */
 
-	iRet = enqMsg((uchar*)pMsg, (uchar*) "kernel:", LOG_FAC(priority), LOG_PRI(priority));
+	iRet = enqMsg((uchar*)pMsg, (uchar*) "kernel:", pri2fac(priority), pri2sev(priority));
 
 finalize_it:
 	RETiRet;
Index: rsyslog/plugins/imklog/ksym.c
===================================================================
--- rsyslog.orig/plugins/imklog/ksym.c	2014-09-27 00:21:21.654998869 +0200
+++ rsyslog/plugins/imklog/ksym.c	2014-09-27 00:21:21.650998781 +0200
@@ -118,7 +118,6 @@
 #include <ctype.h>
 #include <stdarg.h>
 #include <string.h>
-#include <syslog.h>
 #include "imklog.h"
 #include "ksyms.h"
 #include "module.h"
Index: rsyslog/plugins/imsolaris/imsolaris.c
===================================================================
--- rsyslog.orig/plugins/imsolaris/imsolaris.c	2014-09-27 00:21:21.654998869 +0200
+++ rsyslog/plugins/imsolaris/imsolaris.c	2014-09-27 00:21:21.650998781 +0200
@@ -204,8 +204,8 @@
 		MsgSetInputName(pMsg, pInputName);
 		MsgSetRawMsg(pMsg, (char*)pRcv, strlen((char*)pRcv));
 		MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName()));
-		pMsg->iFacility = LOG_FAC(hdr.pri);
-		pMsg->iSeverity = LOG_PRI(hdr.pri);
+		pMsg->iFacility = pri2fac(hdr.pri);
+		pMsg->iSeverity = pri2sev(hdr.pri);
 		pMsg->msgFlags = NEEDS_PARSING | NO_PRI_IN_RAW;
 		CHKiRet(submitMsg(pMsg));
 	}
Index: rsyslog/plugins/imtemplate/imtemplate.c
===================================================================
--- rsyslog.orig/plugins/imtemplate/imtemplate.c	2014-09-27 00:21:21.654998869 +0200
+++ rsyslog/plugins/imtemplate/imtemplate.c	2014-09-27 00:21:21.650998781 +0200
@@ -245,8 +245,8 @@
 		MsgSetRawMsg(pMsg, msg);
 		MsgSetHOSTNAME(pMsg, LocalHostName);
 		MsgSetTAG(pMsg, "rsyslogd:");
-		pMsg->iFacility = LOG_FAC(pri);
-		pMsg->iSeverity = LOG_PRI(pri);
+		pMsg->iFacility = pri2fac(pri);
+		pMsg->iSeverity = pri2sev(pri);
 		flags |= INTERNAL_MSG;
 		logmsg(pMsg, flags); / * some time, CHKiRet() will work here, too [today NOT!] * /
 		 * 
Index: rsyslog/plugins/imuxsock/imuxsock.c
===================================================================
--- rsyslog.orig/plugins/imuxsock/imuxsock.c	2014-09-27 00:21:21.654998869 +0200
+++ rsyslog/plugins/imuxsock/imuxsock.c	2014-09-27 00:21:21.650998781 +0200
@@ -6,7 +6,7 @@
  *
  * File begun on 2007-12-20 by RGerhards (extracted from syslogd.c)
  *
- * Copyright 2007-2011 Rainer Gerhards and Adiscon GmbH.
+ * Copyright 2007-2014 Rainer Gerhards and Adiscon GmbH.
  *
  * This file is part of rsyslog.
  *
@@ -542,8 +542,8 @@
 		++parse;
 		++offs;
 	} 
-	facil = LOG_FAC(pri);
-	sever = LOG_PRI(pri);
+	facil = pri2fac(pri);
+	sever = pri2sev(pri);
 
 	if(sever >= pLstn->ratelimitSev) {
 		/* note: if cred == NULL, then ratelimiter == NULL as well! */
Index: rsyslog/runtime/msg.c
===================================================================
--- rsyslog.orig/runtime/msg.c	2014-09-27 00:21:21.654998869 +0200
+++ rsyslog/runtime/msg.c	2014-09-27 00:21:21.650998781 +0200
@@ -67,7 +67,7 @@
 static struct {
 	uchar *pszName;
 	short lenName;
-} syslog_pri_names[192] = {
+} syslog_pri_names[200] = {
 	{ UCHAR_CONSTANT("0"), 3},
 	{ UCHAR_CONSTANT("1"), 3},
 	{ UCHAR_CONSTANT("2"), 3},
@@ -259,14 +259,22 @@
 	{ UCHAR_CONSTANT("188"), 5},
 	{ UCHAR_CONSTANT("189"), 5},
 	{ UCHAR_CONSTANT("190"), 5},
-	{ UCHAR_CONSTANT("191"), 5}
+	{ UCHAR_CONSTANT("191"), 5},
+	{ UCHAR_CONSTANT("192"), 5},
+	{ UCHAR_CONSTANT("193"), 5},
+	{ UCHAR_CONSTANT("194"), 5},
+	{ UCHAR_CONSTANT("195"), 5},
+	{ UCHAR_CONSTANT("196"), 5},
+	{ UCHAR_CONSTANT("197"), 5},
+	{ UCHAR_CONSTANT("198"), 5},
+	{ UCHAR_CONSTANT("199"), 5}
 	};
 
 /*syslog facility names (as of RFC5424) */
-static char *syslog_fac_names[24] = { "kern", "user", "mail", "daemon", "auth", "syslog", "lpr",
+static char *syslog_fac_names[LOG_NFACILITIES] = { "kern", "user", "mail", "daemon", "auth", "syslog", "lpr",
 			    	      "news", "uucp", "cron", "authpriv", "ftp", "ntp", "audit",
 			    	      "alert", "clock", "local0", "local1", "local2", "local3",
-			    	      "local4", "local5", "local6", "local7" };
+			    	      "local4", "local5", "local6", "local7", "invld" };
 
 /* table of severity names (in numerical order)*/
 static char *syslog_severity_names[8] = { "emerg", "alert", "crit", "err", "warning", "notice", "info", "debug" };
@@ -275,8 +283,8 @@
  * and facility values to a numerical string... -- rgerhars, 2009-06-17
  */
 
-static char *syslog_number_names[24] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14",
-					 "15", "16", "17", "18", "19", "20", "21", "22", "23" };
+static char *syslog_number_names[LOG_NFACILITIES] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14",
+					 "15", "16", "17", "18", "19", "20", "21", "22", "23", "24" };
 
 /* global variables */
 #if defined(HAVE_MALLOC_TRIM) && !defined(HAVE_ATOMIC_BUILTINS)
@@ -685,8 +693,8 @@
 	pM->bDoLock = 0;
 	pM->bAlreadyFreed = 0;
 	pM->iRefCount = 1;
-	pM->iSeverity = -1;
-	pM->iFacility = -1;
+	pM->iSeverity = LOG_DEBUG;
+	pM->iFacility = LOG_INVLD;
 	pM->offAfterPRI = 0;
 	pM->offMSG = -1;
 	pM->iProtocolVersion = 0;
@@ -2243,8 +2251,8 @@
 	assert(pRes != NULL);
 	assert(pResLen > 0);
 
-	snprintf(pRes, pResLen, "%s.%s<%d>", syslog_fac_names[LOG_FAC(pri)],
-		 syslog_severity_names[LOG_PRI(pri)], pri);
+	snprintf(pRes, pResLen, "%s.%s<%d>", syslog_fac_names[pri2fac(pri)],
+		 syslog_severity_names[pri2sev(pri)], pri);
 
 	return pRes;
 }
Index: rsyslog/runtime/parser.c
===================================================================
--- rsyslog.orig/runtime/parser.c	2014-09-27 00:21:21.654998869 +0200
+++ rsyslog/runtime/parser.c	2014-09-27 00:21:21.650998781 +0200
@@ -450,11 +450,11 @@
 			}
 			if(*msg == '>')
 				++msg;
-			if(pri & ~(LOG_FACMASK|LOG_PRIMASK))
-				pri = DEFUPRI;
+			if(pri > LOG_MAXPRI)
+				pri = LOG_PRI_INVLD;
 		}
-		pMsg->iFacility = LOG_FAC(pri);
-		pMsg->iSeverity = LOG_PRI(pri);
+		pMsg->iFacility = pri2fac(pri);
+		pMsg->iSeverity = pri2sev(pri);
 		MsgSetAfterPRIOffs(pMsg, msg - pMsg->pszRawMsg);
 	}
 	RETiRet;
Index: rsyslog/runtime/rsyslog.h
===================================================================
--- rsyslog.orig/runtime/rsyslog.h	2014-09-27 00:21:21.654998869 +0200
+++ rsyslog/runtime/rsyslog.h	2014-09-27 00:21:21.650998781 +0200
@@ -3,7 +3,7 @@
  *
  * Begun 2005-09-15 RGerhards
  *
- * Copyright (C) 2005-2008 by Rainer Gerhards and Adiscon GmbH
+ * Copyright (C) 2005-2014 by Rainer Gerhards and Adiscon GmbH
  *
  * This file is part of the rsyslog runtime library.
  *
@@ -74,19 +74,58 @@
  * #                  End Config Settings                      # *
  * ############################################################# */
 
-/* portability: not all platforms have these defines, so we
- * define them here if they are missing. -- rgerhards, 2008-03-04
+/* make sure we uses consistent macros, no matter what the
+ * platform gives us.
  */
-#ifndef LOG_MAKEPRI
-#	define	LOG_MAKEPRI(fac, pri)	(((fac) << 3) | (pri))
-#endif
-#ifndef LOG_PRI
-#	define	LOG_PRI(p)	((p) & LOG_PRIMASK)
-#endif
-#ifndef LOG_FAC
-#	define	LOG_FAC(p)	(((p) & LOG_FACMASK) >> 3)
-#endif
+#define LOG_NFACILITIES 24+1 /* plus one for our special "invld" facility! */
+#define LOG_MAXPRI 191	/* highest supported valid PRI value --> RFC3164, RFC5424 */
+#undef LOG_MAKEPRI
+#define LOG_PRI_INVLD	LOG_INVLD|LOG_DEBUG	/* PRI is invalid --> special "invld.=debug" PRI code (rsyslog-specific) */
+
+#define	LOG_EMERG	0	/* system is unusable */
+#define	LOG_ALERT	1	/* action must be taken immediately */
+#define	LOG_CRIT	2	/* critical conditions */
+#define	LOG_ERR		3	/* error conditions */
+#define	LOG_WARNING	4	/* warning conditions */
+#define	LOG_NOTICE	5	/* normal but significant condition */
+#define	LOG_INFO	6	/* informational */
+#define	LOG_DEBUG	7	/* debug-level messages */
+
+#define	LOG_KERN	(0<<3)	/* kernel messages */
+#define	LOG_USER	(1<<3)	/* random user-level messages */
+#define	LOG_MAIL	(2<<3)	/* mail system */
+#define	LOG_DAEMON	(3<<3)	/* system daemons */
+#define	LOG_AUTH	(4<<3)	/* security/authorization messages */
+#define	LOG_SYSLOG	(5<<3)	/* messages generated internally by syslogd */
+#define	LOG_LPR		(6<<3)	/* line printer subsystem */
+#define	LOG_NEWS	(7<<3)	/* network news subsystem */
+#define	LOG_UUCP	(8<<3)	/* UUCP subsystem */
+#define	LOG_CRON	(9<<3)	/* clock daemon */
+#define	LOG_AUTHPRIV	(10<<3)	/* security/authorization messages (private) */
+#define	LOG_FTP		(11<<3)	/* ftp daemon */
+#define	LOG_LOCAL0	(16<<3)	/* reserved for local use */
+#define	LOG_LOCAL1	(17<<3)	/* reserved for local use */
+#define	LOG_LOCAL2	(18<<3)	/* reserved for local use */
+#define	LOG_LOCAL3	(19<<3)	/* reserved for local use */
+#define	LOG_LOCAL4	(20<<3)	/* reserved for local use */
+#define	LOG_LOCAL5	(21<<3)	/* reserved for local use */
+#define	LOG_LOCAL6	(22<<3)	/* reserved for local use */
+#define	LOG_LOCAL7	(23<<3)	/* reserved for local use */
+#define LOG_FAC_INVLD   24
+#define	LOG_INVLD	(LOG_FAC_INVLD<<3)	/* invalid facility/PRI code */
 
+/* we need to use a function to avoid side-effects. This MUST guard
+ * against invalid facility values. rgerhards, 2014-09-16
+ */
+static inline int pri2fac(const int pri)
+{
+	int fac = pri >> 3;
+	return (fac > 23) ? LOG_FAC_INVLD : fac;
+}
+static inline int pri2sev(const int pri)
+{
+	return pri & 0x07;
+}
 
 /* the rsyslog core provides information about present feature to plugins
  * asking it. Below are feature-test macros which must be used to query 
Index: rsyslog/runtime/rule.c
===================================================================
--- rsyslog.orig/runtime/rule.c	2014-09-27 00:21:21.654998869 +0200
+++ rsyslog/runtime/rule.c	2014-09-27 00:21:21.650998781 +0200
@@ -171,7 +171,7 @@
 
 	if(pRule->f_filter_type == FILTER_PRI) {
 		/* skip messages that are incorrect priority */
-		dbgprintf("testing filter, f_pmask %d\n", pRule->f_filterData.f_pmask[pMsg->iFacility]);
+		dbgprintf("testing filter, f_pmask %d, facility %d\n", pRule->f_filterData.f_pmask[pMsg->iFacility], pMsg->iFacility);
 		if ( (pRule->f_filterData.f_pmask[pMsg->iFacility] == TABLE_NOPRI) || \
 		    ((pRule->f_filterData.f_pmask[pMsg->iFacility] & (1<<pMsg->iSeverity)) == 0) )
 			bRet = 0;
Index: rsyslog/runtime/srutils.c
===================================================================
--- rsyslog.orig/runtime/srutils.c	2014-09-27 00:21:21.654998869 +0200
+++ rsyslog/runtime/srutils.c	2014-09-27 00:21:21.650998781 +0200
@@ -102,6 +102,7 @@
 	{"local5",       LOG_LOCAL5},
 	{"local6",       LOG_LOCAL6},
 	{"local7",       LOG_LOCAL7},
+	{"invld",        LOG_INVLD},
 	{NULL,           -1},
 };
 
Index: rsyslog/runtime/syslogd-types.h
===================================================================
--- rsyslog.orig/runtime/syslogd-types.h	2014-09-27 00:21:21.654998869 +0200
+++ rsyslog/runtime/syslogd-types.h	2014-09-27 00:21:21.650998781 +0200
@@ -27,9 +27,6 @@
 
 #include "stringbuf.h"
 #include <sys/param.h>
-#if HAVE_SYSLOG_H
-#include <syslog.h>
-#endif
 
 #define FALSE 0
 #define TRUE 1
Index: rsyslog/tools/syslogd.c
===================================================================
--- rsyslog.orig/tools/syslogd.c	2014-09-27 00:21:21.654998869 +0200
+++ rsyslog/tools/syslogd.c	2014-09-27 00:21:21.650998781 +0200
@@ -556,8 +556,8 @@
 		pszTag[32] = '\0'; /* just to make sure... */
 		MsgSetTAG(pMsg, pszTag, len);
 	}
-	pMsg->iFacility = LOG_FAC(pri);
-	pMsg->iSeverity = LOG_PRI(pri);
+	pMsg->iFacility = pri2fac(pri);
+	pMsg->iSeverity = pri2sev(pri);
 	flags |= INTERNAL_MSG;
 	pMsg->msgFlags  = flags;
 
@@ -570,7 +570,7 @@
 	 * supressor statement.
 	 */
 	if(((Debug == DEBUG_FULL || NoFork) && bErrMsgToStderr) || iConfigVerify) {
-		if(LOG_PRI(pri) == LOG_ERR)
+		if(pri2fac(pri) == LOG_ERR)
 			fprintf(stderr, "rsyslogd: %s\n", msg);
 	}
 
