Hi,

I would like to increase the maximum message length in syslogd.
Newer RFCs suggest these values:

RFC 5424 The Syslog Protocol
- MUST support 480
- SHOULD accept 2048
- MAY receive larger

RFC 5426 Transmission of Syslog Messages over UDP
- MUST receive 480 over IPv4
- MUST receive 1180 over IPv6
- SHOULD receive 2048
- encouraged to receive more than 2048
- RECOMMENDED to restrict sending to MTU
- no fragmentation with 480 octets for IPv4 and 1180 octets for IPv6

RFC 5425 Transport Layer Security (TLS) Transport Mapping for Syslog
- MUST process 2048
- SHOULD process 8192

So I think a simple solution is to set the maximum line size to
8192 and to restrict UDP sending to 1180.  This is more than the
1024 we support now.  Only drawback is that more stack is used.

Also truncate the line in printline() to exactly 8192 bytes regardless
of visual encoding.  That is a more predictable behavior.

Although syslog(3) does not support long messages yet, make sure
that /dev/log can receive them.

ok?

bluhm

Index: usr.sbin/syslogd/syslogd.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/syslogd.c,v
retrieving revision 1.146
diff -u -p -r1.146 syslogd.c
--- usr.sbin/syslogd/syslogd.c  31 Jan 2015 00:58:35 -0000      1.146
+++ usr.sbin/syslogd/syslogd.c  1 Feb 2015 23:52:53 -0000
@@ -53,7 +53,8 @@
  * IPv6, libevent, sending over TCP and TLS by Alexander Bluhm
  */
 
-#define        MAXLINE         1024            /* maximum line length */
+#define MAXLINE                8192            /* maximum line length */
+#define MAX_UDPMSG     1180            /* maximum UDP send size */
 #define MIN_MEMBUF     (MAXLINE * 4)   /* Minimum memory buffer size */
 #define MAX_MEMBUF     (256 * 1024)    /* Maximum memory buffer size */
 #define MAX_MEMBUF_NAME        64              /* Max length of membuf log 
name */
@@ -98,6 +99,7 @@
 #include <vis.h>
 
 #define MAXIMUM(a, b)  (((a) > (b)) ? (a) : (b))
+#define MINIMUM(a, b)  (((a) < (b)) ? (a) : (b))
 
 #define SYSLOG_NAMES
 #include <sys/syslog.h>
@@ -920,7 +922,7 @@ void
 printline(char *hname, char *msg)
 {
        int pri;
-       char *p, *q, line[MAXLINE + 1];
+       char *p, *q, line[MAXLINE + 4 + 1];  /* message, encoding, NUL */
 
        /* test for special codes */
        pri = DEFUPRI;
@@ -943,13 +945,13 @@ printline(char *hname, char *msg)
        if (LOG_FAC(pri) == LOG_KERN)
                pri = LOG_USER | LOG_PRI(pri);
 
-       for (q = line; *p && q < &line[sizeof(line) - 4]; p++) {
+       for (q = line; *p && q < &line[MAXLINE]; p++) {
                if (*p == '\n')
                        *q++ = ' ';
                else
                        q = vis(q, *p, 0, 0);
        }
-       *q = '\0';
+       line[MAXLINE] = *q = '\0';
 
        logmsg(pri, line, hname, 0);
 }
@@ -1181,13 +1183,13 @@ fprintlog(struct filed *f, int flags, ch
 
        case F_FORWUDP:
                dprintf(" %s\n", f->f_un.f_forw.f_loghost);
-               l = snprintf(line, sizeof(line), "<%d>%.15s %s%s%s",
-                   f->f_prevpri, (char *)iov[0].iov_base,
+               l = snprintf(line, MINIMUM(MAX_UDPMSG + 1, sizeof(line)),
+                   "<%d>%.15s %s%s%s", f->f_prevpri, (char *)iov[0].iov_base,
                    IncludeHostname ? LocalHostName : "",
                    IncludeHostname ? " " : "",
                    (char *)iov[4].iov_base);
-               if (l < 0 || (size_t)l >= sizeof(line))
-                       l = strlen(line);
+               if (l < 0 || (size_t)l > MINIMUM(MAX_UDPMSG, sizeof(line)))
+                       l = MINIMUM(MAX_UDPMSG, sizeof(line));
                if (sendto(f->f_file, line, l, 0,
                    (struct sockaddr *)&f->f_un.f_forw.f_addr,
                    f->f_un.f_forw.f_addr.ss_len) != l) {
@@ -2120,7 +2122,7 @@ unix_socket(char *path, int type, mode_t
 {
        struct sockaddr_un s_un;
        char ebuf[512];
-       int fd;
+       int fd, optval;
        mode_t old_umask;
 
        memset(&s_un, 0, sizeof(s_un));
@@ -2167,6 +2169,11 @@ unix_socket(char *path, int type, mode_t
                unlink(path);
                return (-1);
        }
+
+       optval = MAXLINE + PATH_MAX;
+       if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &optval, sizeof(optval))
+           == -1)
+               logerror("cannot setsockopt unix");
 
        return (fd);
 }

Reply via email to