From 2e7dc5d37bb3b10c486496fa15b8ff366d8a6d66 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Wed, 19 Nov 2008 07:59:49 +0000 Subject: klogctl: fix a problem where we don't terminate read data with '\0' and then misinterpret it. Code shrink while at it. function old new delta klogd_main 404 362 -42 --- sysklogd/klogd.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) (limited to 'sysklogd') diff --git a/sysklogd/klogd.c b/sysklogd/klogd.c index 723ca8067..a0e0bf724 100644 --- a/sysklogd/klogd.c +++ b/sysklogd/klogd.c @@ -42,14 +42,14 @@ int klogd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int klogd_main(int argc UNUSED_PARAM, char **argv) { int i = 0; - char *start; + char *opt_c; int opt; int used = 0; - opt = getopt32(argv, "c:n", &start); + opt = getopt32(argv, "c:n", &opt_c); if (opt & OPT_LEVEL) { /* Valid levels are between 1 and 8 */ - i = xatou_range(start, 1, 8); + i = xatou_range(opt_c, 1, 8); } if (!(opt & OPT_FOREGROUND)) { bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv); @@ -57,10 +57,7 @@ int klogd_main(int argc UNUSED_PARAM, char **argv) openlog("kernel", 0, LOG_KERN); - bb_signals(0 - + (1 << SIGINT) - + (1 << SIGTERM) - , klogd_signal); + bb_signals(BB_FATAL_SIGS, klogd_signal); signal(SIGHUP, SIG_IGN); /* "Open the log. Currently a NOP" */ @@ -73,15 +70,14 @@ int klogd_main(int argc UNUSED_PARAM, char **argv) syslog(LOG_NOTICE, "klogd started: %s", bb_banner); - /* Initially null terminate the buffer in case of a very long line */ - log_buffer[KLOGD_LOGBUF_SIZE - 1] = '\0'; - while (1) { int n; int priority; + char *start; /* "2 -- Read from the log." */ - n = klogctl(2, log_buffer + used, KLOGD_LOGBUF_SIZE-1 - used); + start = log_buffer + used; + n = klogctl(2, start, KLOGD_LOGBUF_SIZE-1 - used); if (n < 0) { if (errno == EINTR) continue; @@ -89,25 +85,25 @@ int klogd_main(int argc UNUSED_PARAM, char **argv) errno); break; } + start[n] = '\0'; /* klogctl buffer parsing modelled after code in dmesg.c */ - start = &log_buffer[0]; - /* Process each newline-terminated line in the buffer */ while (1) { - char *newline = strchr(start, '\n'); + char *newline = strchrnul(start, '\n'); - if (!newline) { + if (*newline == '\0') { /* This line is incomplete... */ if (start != log_buffer) { /* move it to the front of the buffer */ - strcpy(log_buffer, start); + overlapping_strcpy(log_buffer, start); + used = newline - start; /* don't log it yet */ - used = strlen(log_buffer); break; } - /* ...but buffer is full, so log it anyway */ + /* ...but if buffer is full, log it anyway */ used = 0; + newline = NULL; } else { *newline++ = '\0'; } @@ -121,12 +117,13 @@ int klogd_main(int argc UNUSED_PARAM, char **argv) priority = (*start - '0'); start++; } - if (*start == '>') { + if (*start == '>') start++; - } } + /* Log (only non-empty lines) */ if (*start) syslog(priority, "%s", start); + if (!newline) break; start = newline; -- cgit v1.2.3