FreeBSD Bugzilla – Attachment 188530 Details for
Bug 200933
syslog is not RFC-compliant when receiving remote UDP messages
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
doubled logging fixed
syslogd.diff (text/plain), 10.67 KB, created by
Gleb Smirnoff
on 2017-12-04 19:02:23 UTC
(
hide
)
Description:
doubled logging fixed
Filename:
MIME Type:
Creator:
Gleb Smirnoff
Created:
2017-12-04 19:02:23 UTC
Size:
10.67 KB
patch
obsolete
>Index: syslogd.8 >=================================================================== >--- syslogd.8 (revision 326343) >+++ syslogd.8 (working copy) >@@ -28,7 +28,7 @@ > .\" @(#)syslogd.8 8.1 (Berkeley) 6/6/93 > .\" $FreeBSD$ > .\" >-.Dd March 3, 2017 >+.Dd November 28, 2017 > .Dt SYSLOGD 8 > .Os > .Sh NAME >@@ -36,7 +36,7 @@ > .Nd log systems messages > .Sh SYNOPSIS > .Nm >-.Op Fl 468ACcdFkNnosTuv >+.Op Fl 468ACcdFHkNnosTuv > .Op Fl a Ar allowed_peer > .Op Fl b Ar bind_address > .Op Fl f Ar config_file >@@ -229,6 +229,9 @@ and > to run > .Nm , > and wants to monitor when and how it exits. >+.It Fl H >+When logging remote messages use hostname from the message (if supplied) >+instead of using address from which the message was received. > .It Fl k > Disable the translation of > messages received with facility >Index: syslogd.c >=================================================================== >--- syslogd.c (revision 326343) >+++ syslogd.c (working copy) >@@ -173,7 +173,6 @@ static STAILQ_HEAD(, socklist) shead = STAILQ_HEAD > > #define IGN_CONS 0x001 /* don't print on console */ > #define SYNC_FILE 0x002 /* do fsync on file after printing */ >-#define ADDDATE 0x004 /* add a date to the message */ > #define MARK 0x008 /* this message is a mark */ > #define ISKERNEL 0x010 /* kernel generated message */ > >@@ -324,6 +323,7 @@ static int logflags = O_WRONLY|O_APPEND; /* flags > static char bootfile[MAXLINE+1]; /* booted kernel file */ > > static int RemoteAddDate; /* Always set the date on remote messages */ >+static int RemoteHostname; /* Log remote hostname from the message */ > > static int UniquePriority; /* Only log specified priority? */ > static int LogFacPri; /* Put facility and priority in log message: */ >@@ -352,7 +352,7 @@ static void domark(int); > static void fprintlog(struct filed *, int, const char *); > static void init(int); > static void logerror(const char *); >-static void logmsg(int, const char *, const char *, int); >+static void logmsg(int, const char *, const char *, const char *, int); > static void log_deadchild(pid_t, int, const char *); > static void markit(void); > static int socksetup(struct peer *); >@@ -361,7 +361,7 @@ static int socklist_recv_sock(struct socklist *); > static int socklist_recv_signal(struct socklist *); > static void sighandler(int); > static int skip_message(const char *, const char *, int); >-static void printline(const char *, char *, int); >+static void parsemsg(const char *, char *); > static void printsys(char *); > static int p_open(const char *, pid_t *); > static void reapchild(int); >@@ -454,7 +454,7 @@ main(int argc, char *argv[]) > if (madvise(NULL, 0, MADV_PROTECT) != 0) > dprintf("madvise() failed: %s\n", strerror(errno)); > >- while ((ch = getopt(argc, argv, "468Aa:b:cCdf:Fkl:m:nNop:P:sS:Tuv")) >+ while ((ch = getopt(argc, argv, "468Aa:b:cCdf:FHkl:m:nNop:P:sS:Tuv")) > != -1) > switch (ch) { > #ifdef INET >@@ -518,6 +518,9 @@ main(int argc, char *argv[]) > case 'F': /* run in foreground instead of daemon */ > Foreground++; > break; >+ case 'H': >+ RemoteHostname = 1; >+ break; > case 'k': /* keep remote kern fac */ > KeepKernFac = 1; > break; >@@ -772,7 +775,7 @@ socklist_recv_sock(struct socklist *sl) > socklen_t sslen; > const char *hname; > char line[MAXLINE + 1]; >- int date, len; >+ int len; > > sslen = sizeof(ss); > len = recvfrom(sl->sl_socket, line, sizeof(line) - 1, 0, sa, &sslen); >@@ -786,10 +789,9 @@ socklist_recv_sock(struct socklist *sl) > } > /* Received valid data. */ > line[len] = '\0'; >- if (sl->sl_ss.ss_family == AF_LOCAL) { >+ if (sl->sl_ss.ss_family == AF_LOCAL) > hname = LocalHostName; >- date = 0; >- } else { >+ else { > hname = cvthname(sa); > unmapped(sa); > if (validate(sa, hname) == 0) { >@@ -796,9 +798,8 @@ socklist_recv_sock(struct socklist *sl) > dprintf("Message from %s was ignored.", hname); > return (-1); > } >- date = RemoteAddDate ? ADDDATE : 0; > } >- printline(hname, line, date); >+ parsemsg(hname, line); > > return (0); > } >@@ -836,7 +837,7 @@ usage(void) > { > > fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n", >- "usage: syslogd [-468ACcdFknosTuv] [-a allowed_peer]", >+ "usage: syslogd [-468ACcdFHknosTuv] [-a allowed_peer]", > " [-b bind_address] [-f config_file]", > " [-l [mode:]path] [-m mark_interval]", > " [-P pid_file] [-p log_socket]", >@@ -845,28 +846,43 @@ usage(void) > } > > /* >- * Take a raw input line, decode the message, and print the message >- * on the appropriate log files. >+ * Take a raw input line, extract PRI, TIMESTAMP and HOSTNAME from the message, >+ * and print the message on the appropriate log files. > */ > static void >-printline(const char *hname, char *msg, int flags) >+parsemsg(const char *from, char *msg) > { >- char *p, *q; >+ const char *timestamp; >+ char *q; > long n; >- int c, pri; >+ int i, c, pri, msglen; > char line[MAXLINE + 1]; > >- /* test for special codes */ >- p = msg; >- pri = DEFUPRI; >- if (*p == '<') { >- errno = 0; >- n = strtol(p + 1, &q, 10); >- if (*q == '>' && n >= 0 && n < INT_MAX && errno == 0) { >- p = q + 1; >- pri = n; >+ /* Parse PRI. */ >+ if (msg[0] != '<' || !isdigit(msg[1])) { >+ dprintf("Invalid PRI from %s\n", from); >+ return; >+ } >+ for (i = 2; i <= 4; i++) { >+ if (msg[i] == '>') >+ break; >+ if (!isdigit(msg[i])) { >+ dprintf("Invalid PRI header from %s\n", from); >+ return; > } > } >+ if (msg[i] != '>') { >+ dprintf("Invalid PRI header from %s\n", from); >+ return; >+ } >+ errno = 0; >+ n = strtol(msg + 1, &q, 10); >+ if (errno != 0 || *q != msg[i] || n < 0 || n >= INT_MAX) { >+ dprintf("Invalid PRI %ld from %s: %s\n", >+ n, from, strerror(errno)); >+ return; >+ } >+ pri = n; > if (pri &~ (LOG_FACMASK|LOG_PRIMASK)) > pri = DEFUPRI; > >@@ -878,9 +894,53 @@ static void > if ((pri & LOG_FACMASK) == LOG_KERN && !KeepKernFac) > pri = LOG_MAKEPRI(LOG_USER, LOG_PRI(pri)); > >+ /* >+ * The TIMESTAMP field is the local time and is in the format of >+ * "Mmm dd hh:mm:ss" (without the quote marks). >+ * A single space character MUST follow the TIMESTAMP field. >+ * >+ * XXXGL: the check can be improved. >+ */ >+ msg += i + 1; >+ msglen = strlen(msg); >+ if (msglen < MAXDATELEN || msg[3] != ' ' || msg[6] != ' ' || >+ msg[9] != ':' || msg[12] != ':' || msg[15] != ' ') { >+ dprintf("Invalid TIMESTAMP from %s: %s\n", from, msg); >+ return; >+ } >+ >+ if (!RemoteAddDate) >+ timestamp = msg; >+ else >+ timestamp = NULL; >+ msg += MAXDATELEN; >+ msglen -= MAXDATELEN; >+ >+ /* >+ * A single space character MUST also follow the HOSTNAME field. >+ */ >+ for (i = 0; i < MIN(MAXHOSTNAMELEN, msglen); i++) { >+ if (msg[i] == ' ') { >+ if (RemoteHostname) { >+ msg[i] = '\0'; >+ from = msg; >+ } >+ msg += i + 1; >+ break; >+ } >+ /* >+ * Support non RFC compliant messages, without hostname. >+ */ >+ if (msg[i] == ':') >+ break; >+ } >+ if (i == MIN(MAXHOSTNAMELEN, msglen)) { >+ dprintf("Invalid HOSTNAME from %s: %s\n", from, msg); >+ return; >+ } >+ > q = line; >- >- while ((c = (unsigned char)*p++) != '\0' && >+ while ((c = (unsigned char)*msg++) != '\0' && > q < &line[sizeof(line) - 4]) { > if (mask_C1 && (c & 0x80) && c < 0xA0) { > c &= 0x7F; >@@ -902,7 +962,7 @@ static void > } > *q = '\0'; > >- logmsg(pri, line, hname, flags); >+ logmsg(pri, timestamp, line, from, 0); > } > > /* >@@ -956,7 +1016,7 @@ printsys(char *msg) > long n; > int flags, isprintf, pri; > >- flags = ISKERNEL | SYNC_FILE | ADDDATE; /* fsync after write */ >+ flags = ISKERNEL | SYNC_FILE; /* fsync after write */ > p = msg; > pri = DEFSPRI; > isprintf = 1; >@@ -977,7 +1037,7 @@ printsys(char *msg) > flags |= IGN_CONS; > if (pri &~ (LOG_FACMASK|LOG_PRIMASK)) > pri = DEFSPRI; >- logmsg(pri, p, LocalHostName, flags); >+ logmsg(pri, NULL, p, LocalHostName, flags); > } > > static time_t now; >@@ -1032,11 +1092,11 @@ skip_message(const char *name, const char *spec, i > * the priority. > */ > static void >-logmsg(int pri, const char *msg, const char *from, int flags) >+logmsg(int pri, const char *timestamp, const char *msg, const char *from, >+ int flags) > { > struct filed *f; > int i, fac, msglen, prilev; >- const char *timestamp; > char prog[NAME_MAX+1]; > char buf[MAXLINE+1]; > >@@ -1043,29 +1103,10 @@ static void > dprintf("logmsg: pri %o, flags %x, from %s, msg %s\n", > pri, flags, from, msg); > >- /* >- * Check to see if msg looks non-standard. >- */ >- msglen = strlen(msg); >- if (msglen < MAXDATELEN || msg[3] != ' ' || msg[6] != ' ' || >- msg[9] != ':' || msg[12] != ':' || msg[15] != ' ') >- flags |= ADDDATE; >- > (void)time(&now); >- if (flags & ADDDATE) { >+ if (timestamp == NULL) > timestamp = ctime(&now) + 4; >- } else { >- timestamp = msg; >- msg += MAXDATELEN; >- msglen -= MAXDATELEN; >- } > >- /* skip leading blanks */ >- while (isspace(*msg)) { >- msg++; >- msglen--; >- } >- > /* extract facility and priority level */ > if (flags & MARK) > fac = LOG_NFACILITIES; >@@ -1078,7 +1119,7 @@ static void > > prilev = LOG_PRI(pri); > >- /* extract program name */ >+ /* Extract TAG part of the message (usually program name). */ > for (i = 0; i < NAME_MAX; i++) { > if (!isprint(msg[i]) || msg[i] == ':' || msg[i] == '[' || > msg[i] == '/' || isspace(msg[i])) >@@ -1092,8 +1133,8 @@ static void > snprintf(buf, sizeof(buf), "%s: %s", > use_bootfile ? bootfile : "kernel", msg); > msg = buf; >- msglen = strlen(buf); > } >+ msglen = strlen(msg); > > /* log the message to the particular outputs */ > if (!Initialized) { >@@ -1643,7 +1684,7 @@ logerror(const char *type) > (void)snprintf(buf, sizeof buf, "syslogd: %s", type); > errno = 0; > dprintf("%s\n", buf); >- logmsg(LOG_SYSLOG|LOG_ERR, buf, LocalHostName, ADDDATE); >+ logmsg(LOG_SYSLOG|LOG_ERR, NULL, buf, LocalHostName, 0); > recursed--; > } > >@@ -1987,7 +2028,7 @@ init(int signo) > } > } > >- logmsg(LOG_SYSLOG|LOG_INFO, "syslogd: restart", LocalHostName, ADDDATE); >+ logmsg(LOG_SYSLOG|LOG_INFO, NULL, "syslogd: restart", LocalHostName, 0); > dprintf("syslogd: restarted\n"); > /* > * Log a change in hostname, but only on a restart. >@@ -1996,7 +2037,7 @@ init(int signo) > (void)snprintf(hostMsg, sizeof(hostMsg), > "syslogd: hostname changed, \"%s\" to \"%s\"", > oldLocalHostName, LocalHostName); >- logmsg(LOG_SYSLOG|LOG_INFO, hostMsg, LocalHostName, ADDDATE); >+ logmsg(LOG_SYSLOG|LOG_INFO, NULL, hostMsg, LocalHostName, 0); > dprintf("%s\n", hostMsg); > } > /* >@@ -2006,7 +2047,7 @@ init(int signo) > if (signo == 0 && !use_bootfile) { > (void)snprintf(bootfileMsg, sizeof(bootfileMsg), > "syslogd: kernel boot file is %s", bootfile); >- logmsg(LOG_KERN|LOG_INFO, bootfileMsg, LocalHostName, ADDDATE); >+ logmsg(LOG_KERN|LOG_INFO, NULL, bootfileMsg, LocalHostName, 0); > dprintf("%s\n", bootfileMsg); > } > } >@@ -2315,8 +2356,7 @@ markit(void) > now = time((time_t *)NULL); > MarkSeq += TIMERINTVL; > if (MarkSeq >= MarkInterval) { >- logmsg(LOG_INFO, "-- MARK --", >- LocalHostName, ADDDATE|MARK); >+ logmsg(LOG_INFO, NULL, "-- MARK --", LocalHostName, MARK); > MarkSeq = 0; > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 200933
:
163083
|
188379
| 188530