From owner-svn-src-stable-9@FreeBSD.ORG Tue Dec 9 00:47:47 2014 Return-Path: Delivered-To: svn-src-stable-9@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 75630964; Tue, 9 Dec 2014 00:47:47 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 56457BE7; Tue, 9 Dec 2014 00:47:47 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id sB90llP7065424; Tue, 9 Dec 2014 00:47:47 GMT (envelope-from delphij@FreeBSD.org) Received: (from delphij@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id sB90llHM065423; Tue, 9 Dec 2014 00:47:47 GMT (envelope-from delphij@FreeBSD.org) Message-Id: <201412090047.sB90llHM065423@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: delphij set sender to delphij@FreeBSD.org using -f From: Xin LI Date: Tue, 9 Dec 2014 00:47:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r275627 - stable/9/lib/libc/gen X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-9@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for only the 9-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 09 Dec 2014 00:47:47 -0000 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 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,