Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.sbin/syslogd Open and write to ttys using non-blocking I...



details:   https://anonhg.NetBSD.org/src/rev/ec5bb6410141
branches:  trunk
changeset: 779618:ec5bb6410141
user:      christos <christos%NetBSD.org@localhost>
date:      Tue Jun 05 19:33:17 2012 +0000

description:
Open and write to ttys using non-blocking I/O to prevent DoS when hardware
or software flow control prevents tty writes or when the tty line is too
slow to respond.

diffstat:

 usr.sbin/syslogd/syslogd.c |  71 +++++++++++++++++++++++++++++++++++++--------
 1 files changed, 58 insertions(+), 13 deletions(-)

diffs (144 lines):

diff -r f0d0612592d5 -r ec5bb6410141 usr.sbin/syslogd/syslogd.c
--- a/usr.sbin/syslogd/syslogd.c        Tue Jun 05 17:31:04 2012 +0000
+++ b/usr.sbin/syslogd/syslogd.c        Tue Jun 05 19:33:17 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: syslogd.c,v 1.107 2012/05/15 01:22:50 christos Exp $   */
+/*     $NetBSD: syslogd.c,v 1.108 2012/06/05 19:33:17 christos Exp $   */
 
 /*
  * Copyright (c) 1983, 1988, 1993, 1994
@@ -39,7 +39,7 @@
 #if 0
 static char sccsid[] = "@(#)syslogd.c  8.3 (Berkeley) 4/4/94";
 #else
-__RCSID("$NetBSD: syslogd.c,v 1.107 2012/05/15 01:22:50 christos Exp $");
+__RCSID("$NetBSD: syslogd.c,v 1.108 2012/06/05 19:33:17 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -70,6 +70,7 @@
  * TLS, syslog-protocol, and syslog-sign code by Martin Schuette.
  */
 #define SYSLOG_NAMES
+#include <poll.h>
 #include "syslogd.h"
 #include "extern.h"
 
@@ -266,6 +267,7 @@
 static inline void
                free_incoming_tls_sockets(void);
 #endif /* !DISABLE_TLS */
+static int writev1(int, struct iovec *, size_t);
 
 /* for make_timestamp() */
 #define TIMESTAMPBUFSIZE 35
@@ -1835,7 +1837,7 @@
        /* log the message to the particular outputs */
        if (!Initialized) {
                f = &consfile;
-               f->f_file = open(ctty, O_WRONLY, 0);
+               f->f_file = open(ctty, O_WRONLY | O_NDELAY, 0);
 
                if (f->f_file >= 0) {
                        DELREF(f->f_prevmsg);
@@ -2404,7 +2406,8 @@
                DPRINTF(D_MISC, "Logging to %s %s\n",
                        TypeInfo[f->f_type].name, f->f_un.f_fname);
        again:
-               if (writev(f->f_file, iov, v - iov) < 0) {
+               if ((f->f_type == F_FILE ? writev(f->f_file, iov, v - iov) :
+                   writev1(f->f_file, iov, v - iov)) < 0) {
                        e = errno;
                        if (f->f_type == F_FILE && e == ENOSPC) {
                                int lasterror = f->f_lasterror;
@@ -2419,7 +2422,7 @@
                         */
                        if ((e == EIO || e == EBADF) && f->f_type != F_FILE) {
                                f->f_file = open(f->f_un.f_fname,
-                                   O_WRONLY|O_APPEND, 0);
+                                   O_WRONLY|O_APPEND|O_NDELAY, 0);
                                if (f->f_file < 0) {
                                        f->f_type = F_UNUSED;
                                        logerror("%s", f->f_un.f_fname);
@@ -3605,7 +3608,7 @@
     const char *host)
 {
        struct addrinfo hints, *res;
-       int    error, i, pri, syncfile;
+       int    error, i, pri, syncfile, flags;
        const char   *p, *q;
        char *bp;
        char   buf[MAXLINE];
@@ -3819,19 +3822,22 @@
                        f->f_flags |= FFLAG_SIGN;
 #endif /* !DISABLE_SIGN */
                (void)strlcpy(f->f_un.f_fname, p, sizeof(f->f_un.f_fname));
-               if ((f->f_file = open(p, O_WRONLY|O_APPEND, 0)) < 0) {
+               if (isatty(f->f_file)) {
+                       f->f_type = F_TTY;
+                       if (strcmp(p, ctty) == 0)
+                               f->f_type = F_CONSOLE;
+                       flags = O_NDELAY;
+               } else {
+                       f->f_type = F_FILE;
+                       flags = 0;
+               }
+               if ((f->f_file = open(p, O_WRONLY|O_APPEND|flags, 0)) < 0) {
                        f->f_type = F_UNUSED;
                        logerror("%s", p);
                        break;
                }
                if (syncfile)
                        f->f_flags |= FFLAG_SYNC;
-               if (isatty(f->f_file))
-                       f->f_type = F_TTY;
-               else
-                       f->f_type = F_FILE;
-               if (strcmp(p, ctty) == 0)
-                       f->f_type = F_CONSOLE;
                break;
 
        case '|':
@@ -4695,3 +4701,42 @@
        *p = ++q;
        return true;
 }
+
+static int
+writev1(int fd, struct iovec *iov, size_t count)
+{
+       ssize_t nw = 0, tot = 0;
+       size_t ntries = 5;
+
+       while (ntries--) {
+               switch ((nw = writev(fd, iov, count))) {
+               case -1:
+                       if (errno == EAGAIN || errno == EWOULDBLOCK) {
+                               struct pollfd pfd;
+                               pfd.fd = fd;
+                               pfd.events = POLLOUT;
+                               pfd.revents = 0;
+                               (void)poll(&pfd, 1, 500);
+                               continue;
+                       } else
+                               return -1;
+               case 0:
+                       return 0;
+               default:
+                       tot += nw;
+                       while (nw > 0) {
+                               if (iov->iov_len > nw) {
+                                       iov->iov_len -= nw;
+                                       iov->iov_base += nw;
+                                       break;
+                               } else {
+                                       if (count-- == 0)
+                                               return tot;
+                                       nw -= iov->iov_len;
+                                       iov++;
+                               }
+                       }
+               }
+       }
+       return tot == 0 ? nw : tot;
+}



Home | Main Index | Thread Index | Old Index