Convert syslog_r(3) to using sendsyslog(2). This ensures that syslog_r(3)
authorderaadt <deraadt@openbsd.org>
Mon, 14 Jul 2014 03:52:04 +0000 (03:52 +0000)
committerderaadt <deraadt@openbsd.org>
Mon, 14 Jul 2014 03:52:04 +0000 (03:52 +0000)
can be used anywhere (signal handler, stack protector fault handler) as
long as the format string does not contain floating point.
ok tedu miod beck

lib/libc/gen/syslog_r.c
sys/sys/syslog.h

index e74479f..3b3058a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: syslog_r.c,v 1.4 2013/04/29 00:28:23 okan Exp $ */
+/*     $OpenBSD: syslog_r.c,v 1.5 2014/07/14 03:52:04 deraadt Exp $ */
 /*
  * Copyright (c) 1983, 1988, 1993
  *     The Regents of the University of California.  All rights reserved.
  */
 
 #include <sys/types.h>
-#include <sys/socket.h>
 #include <sys/syslog.h>
 #include <sys/uio.h>
-#include <sys/un.h>
 #include <netdb.h>
 
 #include <errno.h>
@@ -46,8 +44,7 @@
 
 extern char    *__progname;            /* Program name, from crt0. */
 
-static void    disconnectlog_r(struct syslog_data *);  /* disconnect from syslogd */
-static void    connectlog_r(struct syslog_data *);     /* (re)connect to syslogd */
+int    sendsyslog(const char *, size_t);
 
 void   __vsyslog_r(int pri, struct syslog_data *, size_t (*)(char *, size_t),
     const char *, va_list);
@@ -210,32 +207,11 @@ __vsyslog_r(int pri, struct syslog_data *data,
                (void)writev(STDERR_FILENO, iov, 2);
        }
 
-       /* Get connected, output the message to the local logger. */
-       if (!data->opened)
-               openlog_r(data->log_tag, data->log_stat, 0, data);
-       connectlog_r(data);
-
        /*
-        * If the send() failed, there are two likely scenarios:
-        *  1) syslogd was restarted
-        *  2) /dev/log is out of socket buffer space
-        * We attempt to reconnect to /dev/log 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 sendsyslog() fails, it means that syslogd
+        * is not running.
         */
-       if ((error = send(data->log_file, tbuf, cnt, 0)) < 0) {
-               if (errno != ENOBUFS) {
-                       disconnectlog_r(data);
-                       connectlog_r(data);
-               }
-               do {
-                       struct timespec rqt = { 0, 1000 };
-
-                       nanosleep(&rqt, NULL);
-                       if ((error = send(data->log_file, tbuf, cnt, 0)) >= 0)
-                               break;
-               } while (errno == ENOBUFS);
-       }
+       error = sendsyslog(tbuf, cnt);
 
        /*
         * Output the message to the console; try not to block
@@ -256,46 +232,6 @@ __vsyslog_r(int pri, struct syslog_data *data,
        }
 }
 
-static void
-disconnectlog_r(struct syslog_data *data)
-{
-       /*
-        * If the user closed the FD and opened another in the same slot,
-        * that's their problem.  They should close it before calling on
-        * system services.
-        */
-       if (data->log_file != -1) {
-               close(data->log_file);
-               data->log_file = -1;
-       }
-       data->connected = 0;            /* retry connect */
-}
-
-static void
-connectlog_r(struct syslog_data *data)
-{
-       struct sockaddr_un SyslogAddr;  /* AF_UNIX address of local logger */
-
-       if (data->log_file == -1) {
-               if ((data->log_file = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1)
-                       return;
-               (void)fcntl(data->log_file, F_SETFD, FD_CLOEXEC);
-       }
-       if (data->log_file != -1 && !data->connected) {
-               memset(&SyslogAddr, '\0', sizeof(SyslogAddr));
-               SyslogAddr.sun_len = sizeof(SyslogAddr);
-               SyslogAddr.sun_family = AF_UNIX;
-               strlcpy(SyslogAddr.sun_path, _PATH_LOG,
-                   sizeof(SyslogAddr.sun_path));
-               if (connect(data->log_file, (struct sockaddr *)&SyslogAddr,
-                   sizeof(SyslogAddr)) == -1) {
-                       (void)close(data->log_file);
-                       data->log_file = -1;
-               } else
-                       data->connected = 1;
-       }
-}
-
 void
 openlog_r(const char *ident, int logstat, int logfac, struct syslog_data *data)
 {
@@ -304,19 +240,11 @@ openlog_r(const char *ident, int logstat, int logfac, struct syslog_data *data)
        data->log_stat = logstat;
        if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
                data->log_fac = logfac;
-
-       if (data->log_stat & LOG_NDELAY)        /* open immediately */
-               connectlog_r(data);
-
-       data->opened = 1;       /* ident and facility has been set */
 }
 
 void
 closelog_r(struct syslog_data *data)
 {
-       (void)close(data->log_file);
-       data->log_file = -1;
-       data->connected = 0;
        data->log_tag = NULL;
 }
 
index 5632de7..b255bbd 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: syslog.h,v 1.14 2014/07/10 08:55:35 deraadt Exp $     */
+/*     $OpenBSD: syslog.h,v 1.15 2014/07/14 03:52:04 deraadt Exp $     */
 /*     $NetBSD: syslog.h,v 1.14 1996/04/03 20:46:44 christos Exp $     */
 
 /*
@@ -147,16 +147,13 @@ CODE facilitynames[] = {
 /* Used by reentrant functions */
 
 struct syslog_data {
-       int     log_file;
-       int     connected;
-       int     opened;
        int     log_stat;
        const char      *log_tag;
        int     log_fac;
        int     log_mask;
 };
 
-#define SYSLOG_DATA_INIT {-1, 0, 0, 0, (const char *)0, LOG_USER, 0xff}
+#define SYSLOG_DATA_INIT {0, (const char *)0, LOG_USER, 0xff}
 
 #ifdef _KERNEL
 #define        LOG_PRINTF      -1      /* pseudo-priority to indicate use of printf */