Browse Source

Fix syslog messages lost if syslogd is temporary busy

Commit 4139fe5aec935ba3f462dcaf6aafb6e5eadf1ab9 fixes SIGSTOPed syslogd issue.
but introduced new one - messages will be lost when socket buffer gets full,
not only if syslogd is stalled, but even if it accepts message slower than
someone sends and possibly leads to security hole, when important messages get
lost as result of attacker flooding.

Patch adds 1 second waiting for socket buffer can accept the message, helps
when syslogd is working hard. If it's stalled/SIGSTOPed, message will be sent
to errout as before. After that, further non-blocking /dev/log connect attempts
will fail immediately with EAGAIN error until syslogd reads some from it.

function                                             old     new   delta
openlog_intern                                       259     355     +96
static.tv                                              -       8      +8
.rodata                                              151     159      +8
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 2/0 up/down: 112/0)             Total: 112 bytes

Signed-off-by: Vladislav Grishenko <themiron@mail.ru>
Vladislav Grishenko 11 years ago
parent
commit
eaedbdaa08
1 changed files with 4 additions and 0 deletions
  1. 4 0
      libc/misc/syslog/syslog.c

+ 4 - 0
libc/misc/syslog/syslog.c

@@ -126,6 +126,7 @@ openlog_intern(void)
 {
 	int fd;
 	int logType = SOCK_DGRAM;
+	static const struct timeval tv = { 1, 0 };
 
 	fd = LogFile;
 	if (fd == -1) {
@@ -143,6 +144,9 @@ openlog_intern(void)
 
 	if (fd != -1 && !connected) {
 		if (connect(fd, &SyslogAddr, sizeof(SyslogAddr)) != -1) {
+			/* We want to block send if e.g. syslogd is SIGSTOPed */
+			fcntl(fd, F_SETFL, ~O_NONBLOCK & fcntl(fd, F_GETFL));
+			setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
 			connected = 1;
 		} else {
 			if (fd != -1) {