summaryrefslogtreecommitdiffstats
path: root/rtemsbsd/rtems/syslog.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-10-09 14:34:13 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-10-09 14:56:29 +0200
commitd5eac12255b03d0da1c7509ca4b61c7ab7fdf290 (patch)
treed2e9215edd7646935ebe9578c89661cb20cbbb78 /rtemsbsd/rtems/syslog.c
parenttestsuite: Fix lo0 ifconfig error (diff)
downloadrtems-libbsd-d5eac12255b03d0da1c7509ca4b61c7ab7fdf290.tar.bz2
SYSLOG(3): Replace implementation
Avoid potential buffer overflows on the stack. Expand the %m in the format string.
Diffstat (limited to 'rtemsbsd/rtems/syslog.c')
-rw-r--r--rtemsbsd/rtems/syslog.c307
1 files changed, 153 insertions, 154 deletions
diff --git a/rtemsbsd/rtems/syslog.c b/rtemsbsd/rtems/syslog.c
index 7d3128bc..23420233 100644
--- a/rtemsbsd/rtems/syslog.c
+++ b/rtemsbsd/rtems/syslog.c
@@ -1,194 +1,193 @@
+/**
+ * @file
+ *
+ * @ingroup rtems_bsd_rtems
+ *
+ * @brief TODO.
+ */
+
/*
- * RTEMS version of syslog and associated routines
+ * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#include <machine/rtems-bsd-user-space.h>
+#include <machine/rtems-bsd-program.h>
-#include <rtems.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <errno.h>
#include <syslog.h>
-#include <rtems/bsd/sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
+#include <errno.h>
+#include <stdio.h>
#include <string.h>
-#include <unistd.h>
-
-#include <machine/rtems-bsd-printf-to-iprintf.h>
-
-static int LogStatus = LOG_CONS;
-static const char *LogTag = "syslog";
-static int LogFacility = LOG_USER;
-static int LogMask = 0xff;
-
-static int LogFd = -1;
-static rtems_id LogSemaphore;
-extern struct in_addr rtems_bsdnet_log_host_address;
+typedef struct {
+ int mask;
+} rtems_bsd_syslog_context;
+
+/* FIXME: This should be thread specific */
+static rtems_bsd_syslog_context rtems_bsd_syslog_instance = {
+ .mask = LOG_UPTO(LOG_DEBUG)
+};
+
+static const char * const rtems_bsd_syslog_priorities[] = {
+ [LOG_EMERG] = "emerg",
+ [LOG_ALERT] = "alert",
+ [LOG_CRIT] = "crit",
+ [LOG_ERR] = "err",
+ [LOG_WARNING] = "warning",
+ [LOG_NOTICE] = "notice",
+ [LOG_INFO] = "info",
+ [LOG_DEBUG] = "debug"
+};
+
+static rtems_bsd_syslog_context *
+rtems_bsd_syslog_get_context(void)
+{
+ return &rtems_bsd_syslog_instance;
+}
-#define SYSLOG_PORT 514
+static void
+rtems_bsd_syslog_format_buffer_overflow(void)
+{
+ fputs("err: syslog: format buffer overflow\n", stderr);
+}
void
-syslog (int pri, const char *fmt, ...)
+syslog(int priority, const char *format, ...)
{
va_list ap;
- va_start (ap, fmt);
- vsyslog (pri, fmt, ap);
- va_end (ap);
+ va_start(ap, format);
+ vsyslog(priority, format, ap);
+ va_end(ap);
}
-/*
- * FIXME: Should cbuf be static? It could be if we put the mutex
- * around the entire body of this routine. Then we wouldn't
- * have to worry about blowing stacks with a local variable
- * that large. Could make cbuf bigger, too.
- */
void
-vsyslog (int pri, const char *fmt, va_list ap)
+vsyslog(int priority, const char *format, va_list ap)
{
- int cnt;
- char *cp;
- char *msgp, cbuf[200];
- int sent;
-
- if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) {
- syslog (LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID,
- "syslog: unknown facility/priority: %#x", pri);
- pri &= LOG_PRIMASK|LOG_FACMASK;
+ rtems_bsd_syslog_context *ctx = rtems_bsd_syslog_get_context();
+ int pri = LOG_PRI(priority);
+ char fmt[128];
+ char buf[128];
+ const char *src;
+ char *dst;
+ size_t rem;
+ char *m;
+ int n;
+ size_t len;
+
+ if ((LOG_MASK(pri) & ctx->mask) == 0) {
+ return;
}
- if (!(LOG_MASK(LOG_PRI(pri)) & LogMask))
- return;
+ /* Expand the %m in the format string and add a newline character */
- if ((pri & LOG_FACMASK) == 0)
- pri |= LogFacility;
+ src = format;
+ dst = &fmt[0];
+ rem = sizeof(fmt) - 2;
- cnt = sprintf (cbuf, "<%d>", pri);
- cp = msgp = cbuf + cnt;
- if (LogTag) {
- const char *lp = LogTag;
- while ((*cp = *lp++) != '\0')
- cp++;
- }
- if (LogStatus & LOG_PID) {
- rtems_id tid;
- rtems_task_ident (RTEMS_SELF, 0, &tid);
- cnt = sprintf (cp, "[%#lx]", (unsigned long)tid);
- cp += cnt;
- }
- if (LogTag) {
- *cp++ = ':';
- *cp++ = ' ';
- }
- cnt = vsprintf (cp, fmt, ap);
- cnt += cp - cbuf;
- if (cbuf[cnt-1] == '\n')
- cbuf[--cnt] = '\0';
-
- if (LogStatus & LOG_PERROR)
- printf ("%s\n", cbuf);
-
- /*
- * Grab the mutex
- */
- sent = 0;
- if ((rtems_bsdnet_log_host_address.s_addr != INADDR_ANY)
- && (LogFd >= 0)
- && (rtems_semaphore_obtain (LogSemaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT) == RTEMS_SUCCESSFUL)) {
- /*
- * Set the destination address/port
- */
- struct sockaddr_in farAddress;
- farAddress.sin_family = AF_INET;
- farAddress.sin_port = htons (SYSLOG_PORT);
- farAddress.sin_addr = rtems_bsdnet_log_host_address;
- memset (farAddress.sin_zero, '\0', sizeof farAddress.sin_zero);
-
- /*
- * Send the message
- */
- if (sendto (LogFd, cbuf, cnt, 0, (struct sockaddr *)&farAddress, sizeof farAddress) >= 0)
- sent = 1;
- rtems_semaphore_release (LogSemaphore);
+ while ((m = strstr(src, "%m")) != NULL) {
+ size_t c = m - src;
+
+ if (c > rem) {
+ rtems_bsd_syslog_format_buffer_overflow();
+ return;
+ }
+
+ memcpy(dst, src, c);
+ dst += c;
+ src += c + 2;
+ rem -= c;
+
+ n = sniprintf(dst, rem, "%s", strerror(errno));
+ if (n > rem || n < 0) {
+ rtems_bsd_syslog_format_buffer_overflow();
+ return;
+ }
+
+ dst += (size_t) n;
+ rem -= (size_t) n;
}
- if (!sent && (LogStatus & LOG_CONS) && !(LogStatus & LOG_PERROR))
- printf ("%s\n", msgp);
-}
-void
-openlog (const char *ident, int logstat, int logfac)
-{
- rtems_status_code sc;
- struct sockaddr_in myAddress;
-
- if (ident != NULL)
- LogTag = ident;
- LogStatus = logstat;
- if (logfac != 0 && (logfac & ~LOG_FACMASK) == 0)
- LogFacility = logfac;
-
- /*
- * Create the socket
- */
- if ((LogFd = socket (AF_INET, SOCK_DGRAM, 0)) < 0) {
- printf ("Can't create syslog socket: %d\n", errno);
+ len = strlen(src);
+ if (len > rem) {
+ rtems_bsd_syslog_format_buffer_overflow();
return;
}
- /*
- * Bind socket to name
- */
- myAddress.sin_family = AF_INET;
- myAddress.sin_addr.s_addr = INADDR_ANY;
- myAddress.sin_port = 0;
- memset (myAddress.sin_zero, '\0', sizeof myAddress.sin_zero);
- if (bind (LogFd, (struct sockaddr *)&myAddress, sizeof (myAddress)) < 0) {
- close (LogFd);
- LogFd = -1;
- printf ("Can't bind syslog socket: %d\n", errno);
- return;
+ memcpy(dst, src, len);
+ dst += len;
+ dst[0] = '\n';
+ dst[1] = '\0';
+
+ /* Print into buffer */
+
+ dst = &buf[0];
+ rem = sizeof(buf) - 1;
+
+ n = sniprintf(dst, rem, "%s: ", rtems_bsd_syslog_priorities[pri]);
+ if (n <= rem) {
+ dst += (size_t) n;
+ rem -= (size_t) n;
}
- /*
- * Create the mutex
- */
- sc = rtems_semaphore_create (rtems_build_name('s', 'L', 'o', 'g'),
- 1,
- RTEMS_PRIORITY |
- RTEMS_BINARY_SEMAPHORE |
- RTEMS_INHERIT_PRIORITY |
- RTEMS_NO_PRIORITY_CEILING |
- RTEMS_LOCAL,
- 0,
- &LogSemaphore);
- if (sc != RTEMS_SUCCESSFUL) {
- printf ("Can't create syslog semaphore: %d\n", sc);
- close (LogFd);
- LogFd = -1;
+ n = sniprintf(dst, rem, "%s: ", rtems_bsd_program_get_name());
+ if (n <= rem) {
+ dst += (size_t) n;
+ rem -= (size_t) n;
}
+
+ vsniprintf(dst, rem, &fmt[0], ap);
+
+ /* Write in one rush */
+
+ fputs(&buf[0], stderr);
+}
+
+void
+openlog(const char *ident, int option, int facility)
+{
+ /* TODO */
}
void
closelog(void)
{
- if (LogFd >= 0) {
- close (LogFd);
- LogFd = -1;
- rtems_semaphore_delete (LogSemaphore);
- }
+ /* TODO */
}
int
-setlogmask (int pmask)
+setlogmask(int mask)
{
- int omask;
+ rtems_bsd_syslog_context *ctx = rtems_bsd_syslog_get_context();
+ int cur = ctx->mask;
+
+ ctx->mask = mask & LOG_UPTO(LOG_DEBUG);
- omask = LogMask;
- if (pmask != 0)
- LogMask = pmask;
- return (omask);
+ return cur;
}