Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 22 Aug 2022 02:39:04 GMT
From:      Eugene Grosbein <eugen@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 09387f73b1a8 - stable/12 - syslog(3): unbreak log generation using fabricated PID
Message-ID:  <202208220239.27M2d4YU083044@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/12 has been updated by eugen:

URL: https://cgit.FreeBSD.org/src/commit/?id=09387f73b1a8a1b9359c1e92f5a5c6aea61aefce

commit 09387f73b1a8a1b9359c1e92f5a5c6aea61aefce
Author:     Eugene Grosbein <eugen@FreeBSD.org>
AuthorDate: 2022-08-08 22:21:02 +0000
Commit:     Eugene Grosbein <eugen@FreeBSD.org>
CommitDate: 2022-08-22 02:38:44 +0000

    syslog(3): unbreak log generation using fabricated PID
    
    Recover application ability to supply fabricated PID
    embedded into ident that was lost when libc switched
    to generation of RFC 5424 log messages, for example:
    
    logger -t "ident[$$]" -p user.notice "test"
    
    It is essential for long running scripts.
    Also, this change unbreaks matching resulted entries
    by ident in syslog.conf:
    
    !ident
    *.* /var/log/ident.log
    
    Without the fix, the log (and matching) was broken:
    
    Aug  1 07:36:58 hostname ident[123][86483]: test
    
    Now it works as expected and worked before breakage:
    
    Aug  1 07:39:40 hostname ident[123]: test
    
    Differential:   https://reviews.freebsd.org/D36005
    
    (cherry picked from commit e9ae9fa93745669b7dd0341d333257ad6cfe8e37)
---
 lib/libc/gen/syslog.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 51 insertions(+), 3 deletions(-)

diff --git a/lib/libc/gen/syslog.c b/lib/libc/gen/syslog.c
index 19d44db0075a..41b243627a17 100644
--- a/lib/libc/gen/syslog.c
+++ b/lib/libc/gen/syslog.c
@@ -61,7 +61,9 @@ static int	LogFile = -1;		/* fd for log */
 static int	status;			/* connection status */
 static int	opened;			/* have done openlog() */
 static int	LogStat = 0;		/* status bits, set by openlog() */
+static pid_t	LogPid = -1;		/* process id to tag the entry with */
 static const char *LogTag = NULL;	/* string to tag the entry with */
+static int	LogTagLength = -1;	/* usable part of LogTag */
 static int	LogFacility = LOG_USER;	/* default facility code */
 static int	LogMask = 0xff;		/* mask of priorities to be logged */
 static pthread_mutex_t	syslog_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -81,6 +83,7 @@ static pthread_mutex_t	syslog_mutex = PTHREAD_MUTEX_INITIALIZER;
 static void	disconnectlog(void); /* disconnect from syslogd */
 static void	connectlog(void);	/* (re)connect to syslogd */
 static void	openlog_unlocked(const char *, int, int);
+static void	parse_tag(void);	/* parse ident[NNN] if needed */
 
 enum {
 	NOCONN = 0,
@@ -206,13 +209,20 @@ vsyslog1(int pri, const char *fmt, va_list ap)
 	/* Application name. */
 	if (LogTag == NULL)
 		LogTag = _getprogname();
-	(void)fprintf(fp, "%s ", LogTag == NULL ? NILVALUE : LogTag);
+	else if (LogTagLength == -1)
+		parse_tag();
+	if (LogTagLength > 0)
+		(void)fprintf(fp, "%.*s ", LogTagLength, LogTag);
+	else
+		(void)fprintf(fp, "%s ", LogTag == NULL ? NILVALUE : LogTag);
 	/*
 	 * Provide the process ID regardless of whether LOG_PID has been
 	 * specified, as it provides valuable information. Many
 	 * applications tend not to use this, even though they should.
 	 */
-	(void)fprintf(fp, "%d ", getpid());
+	if (LogPid == -1)
+		LogPid = getpid();
+	(void)fprintf(fp, "%d ", (int)LogPid);
 	/* Message ID. */
 	(void)fputs(NILVALUE " ", fp);
 	/* Structured data. */
@@ -444,9 +454,12 @@ connectlog(void)
 static void
 openlog_unlocked(const char *ident, int logstat, int logfac)
 {
-	if (ident != NULL)
+	if (ident != NULL) {
 		LogTag = ident;
+		LogTagLength = -1;
+	}
 	LogStat = logstat;
+	parse_tag();
 	if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
 		LogFacility = logfac;
 
@@ -476,6 +489,7 @@ closelog(void)
 		LogFile = -1;
 	}
 	LogTag = NULL;
+	LogTagLength = -1;
 	status = NOCONN;
 	THREAD_UNLOCK();
 }
@@ -493,3 +507,37 @@ setlogmask(int pmask)
 	THREAD_UNLOCK();
 	return (omask);
 }
+
+/*
+ * Obtain LogPid from LogTag formatted as following: ident[NNN]
+ */
+static void
+parse_tag(void)
+{
+	char *begin, *end, *p;
+	pid_t pid;
+
+	if (LogTag == NULL || (LogStat & LOG_PID) != 0)
+		return;
+	/*
+	 * LogTagLength is -1 if LogTag was not parsed yet.
+	 * Avoid multiple passes over same LogTag.
+	 */
+	LogTagLength = 0;
+
+	/* Check for presence of opening [ and non-empty ident. */
+	if ((begin = strchr(LogTag, '[')) == NULL || begin == LogTag)
+		return;
+	/* Check for presence of closing ] at the very end and non-empty pid. */
+	if ((end = strchr(begin + 1, ']')) == NULL || end[1] != 0 ||
+	    (end - begin) < 2)
+		return;
+
+	/* Check for pid to contain digits only. */
+	pid = (pid_t)strtol(begin + 1, &p, 10);
+	if (p != end)
+		return;
+
+	LogPid = pid;
+	LogTagLength = begin - LogTag;
+}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202208220239.27M2d4YU083044>