Author: delphij
Date: Tue Dec  9 00:47:46 2014
New Revision: 275627
URL: https://svnweb.freebsd.org/changeset/base/275627

Log:
  MFC r275071:
  
  Reinstitate send() after syslogd restarts.
  
  In r228193 the test of CONNPRIV have been moved to before the _usleep
  and send in vsyslog().  When syslogd restarts, this would prevent the
  message being logged after the disconnect/connect dance for
  scenario #1.
  
  PR:           194751
  Submitted by: Peter Creath <pjcreath+freebsd gmail com>
  Reviewed By:  glebius

Modified:
  stable/9/lib/libc/gen/syslog.c
Directory Properties:
  stable/9/lib/libc/   (props changed)

Modified: stable/9/lib/libc/gen/syslog.c
==============================================================================
--- stable/9/lib/libc/gen/syslog.c      Tue Dec  9 00:47:02 2014        
(r275626)
+++ stable/9/lib/libc/gen/syslog.c      Tue Dec  9 00:47:46 2014        
(r275627)
@@ -261,26 +261,45 @@ vsyslog(int pri, const char *fmt, va_lis
        connectlog();
 
        /*
-        * If the send() failed, there are two likely scenarios: 
+        * If the send() fails, there are two likely scenarios: 
         *  1) syslogd was restarted
         *  2) /var/run/log is out of socket buffer space, which
         *     in most cases means local DoS.
-        * We attempt to reconnect to /var/run/log[priv] to take care of
-        * case #1 and keep send()ing data to cover case #2
-        * to give syslogd a chance to empty its socket buffer.
+        * If the error does not indicate a full buffer, we address
+        * case #1 by attempting to reconnect to /var/run/log[priv]
+        * and resending the message once.
         *
-        * If we are working with a priveleged socket, then take
-        * only one attempt, because we don't want to freeze a
+        * If we are working with a privileged socket, the retry
+        * attempts end there, because we don't want to freeze a
         * critical application like su(1) or sshd(8).
         *
+        * Otherwise, we address case #2 by repeatedly retrying the
+        * send() to give syslogd a chance to empty its socket buffer.
         */
 
        if (send(LogFile, tbuf, cnt, 0) < 0) {
                if (errno != ENOBUFS) {
+                       /*
+                        * Scenario 1: syslogd was restarted
+                        * reconnect and resend once
+                        */
                        disconnectlog();
                        connectlog();
+                       if (send(LogFile, tbuf, cnt, 0) >= 0) {
+                               THREAD_UNLOCK();
+                               return;
+                       }
+                       /*
+                        * if the resend failed, fall through to
+                        * possible scenario 2
+                        */
                }
-               do {
+               while (errno == ENOBUFS) {
+                       /*
+                        * Scenario 2: out of socket buffer space
+                        * possible DoS, fail fast on a privileged
+                        * socket
+                        */
                        if (status == CONNPRIV)
                                break;
                        _usleep(1);
@@ -288,7 +307,7 @@ vsyslog(int pri, const char *fmt, va_lis
                                THREAD_UNLOCK();
                                return;
                        }
-               } while (errno == ENOBUFS);
+               }
        } else {
                THREAD_UNLOCK();
                return;
@@ -350,7 +369,7 @@ connectlog(void)
                SyslogAddr.sun_family = AF_UNIX;
 
                /*
-                * First try priveleged socket. If no success,
+                * First try privileged socket. If no success,
                 * then try default socket.
                 */
                (void)strncpy(SyslogAddr.sun_path, _PATH_LOG_PRIV,
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to