From 0e0b663c816ebf096ca340eac7288e824868b491 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 18 Jul 2014 15:29:39 +0200 Subject: [PATCH 1/2] [BUGFIX] debug logging writing into netlink socket If mipv6-daemon daemonizes, it closes all file descriptors. Including stderr which is left pointing to a closed file descriptor. Later the code opens the netlink socket, which gets fd #2. Thus, in daemonized mode (without explicit log-file), debug logging writes garbage into the netlink file descriptor. This is especially visible when killing the process. In this case terminate writes "got SIGINT, exiting", which then causes the following warning in /var/log/audit/audit.log: type=SELINUX_ERR msg=audit(1405686464.890:1134): SELinux: unrecognized netlink message type=30026 for sclass=34 type=SYSCALL msg=audit(1405686464.890:1134): arch=c000003e syscall=1 success=yes exit=20 a0=2 a1=7f08198baa50 a2=14 a3=13 items=0 ppid=1 pid=19313 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=1 comm="mip6d" exe="/data/src/rhpkg/mipv6-daemon/umip-1.0/src/mip6d" subj=system_u:system_r:mip6d_t:s0 key=(null) type=PROCTITLE msg=audit(1405686464.890:1134): proctitle="./src/mip6d" backtrace: #0 write () at ../sysdeps/unix/syscall-template.S:81 #1 0x000000336e476c83 in _IO_new_file_write (f=0x336e7b91c0 <_IO_2_1_stderr_>, data=0x7f08198baa50, n=20) at fileops.c:1254 #2 0x000000336e47741f in new_do_write (to_do=20, data=0x7f08198baa50 "Fri Jul 18 14:27:35 ", fp=0x336e7b91c0 <_IO_2_1_stderr_>) at fileops.c:530 #3 _IO_new_file_xsputn (f=0x336e7b91c0 <_IO_2_1_stderr_>, data=, n=20) at fileops.c:1338 #4 0x000000336e44cb96 in buffered_vfprintf (s=s@entry=0x336e7b91c0 <_IO_2_1_stderr_>, format=format@entry=0x43208c "%s ", args=args@entry=0x7f08198bd068) at vfprintf.c:2349 #5 0x000000336e447ffe in _IO_vfprintf_internal (s=s@entry=0x336e7b91c0 <_IO_2_1_stderr_>, format=format@entry=0x43208c "%s ", ap=ap@entry=0x7f08198bd068) at vfprintf.c:1289 #6 0x000000336e50471e in ___fprintf_chk (fp=0x336e7b91c0 <_IO_2_1_stderr_>, flag=flag@entry=1, format=format@entry=0x43208c "%s ") at fprintf_chk.c:35 #7 0x000000000040b0ef in fprintf (__fmt=0x43208c "%s ", __stream=) at /usr/include/bits/stdio2.h:97 #8 dbgprint (fname=fname@entry=0x42c9bf <__FUNCTION__.8423> "terminate", fmt=fmt@entry=0x42c887 "got SIGINT, exiting\n") at debug.c:75 #9 0x000000000040371f in terminate () at main.c:91 #10 sigh (arg=) at main.c:169 #11 0x000000336f007f33 in start_thread (arg=0x7f08198be700) at pthread_create.c:309 #12 0x000000336e4f4ded in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111 As workaround, set the debug file stream to NULL, indicating that there is nothing to log. https://bugzilla.redhat.com/show_bug.cgi?id=804105 https://bugzilla.redhat.com/show_bug.cgi?id=804124 Signed-off-by: Thomas Haller --- src/bul.c | 3 +++ src/debug.c | 17 +++++++++++++++-- src/debug.h | 2 ++ src/main.c | 2 ++ 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/bul.c b/src/bul.c index d1045ae..c85b4da 100644 --- a/src/bul.c +++ b/src/bul.c @@ -81,6 +81,9 @@ void dump_bule(void *bule, void *os) struct bulentry *e = (struct bulentry *)bule; FILE *out = (FILE *)os; + if (!out) + return; + if (e->type == BUL_ENTRY) fprintf(out, "== BUL_ENTRY ==\n"); else if (e->type == NON_MIP_CN_ENTRY) diff --git a/src/debug.c b/src/debug.c index 4177982..36b4767 100644 --- a/src/debug.c +++ b/src/debug.c @@ -35,6 +35,7 @@ #include "debug.h" static FILE *sdbg; +static int stderr_closed = 0; static const char *dbg_strdate(char *str) { @@ -66,7 +67,10 @@ void dbgprint(const char *fname, const char *fmt, ...) char s[1024]; char stime[1024]; va_list args; - + + if (!sdbg) + return; + va_start(args, fmt); vsprintf(s, fmt, args); va_end(args); @@ -87,6 +91,9 @@ void debug_print_buffer(const void *data, int len, const char *fname, char s[1024]; va_list args; + if (!sdbg) + return; + va_start(args, fmt); vsprintf(s, fmt, args); fprintf(sdbg, "%s: %s", fname, s); @@ -131,6 +138,12 @@ void debug_close(void) void debug_init(void) { - sdbg = stderr; + sdbg = stderr_closed ? NULL : stderr; } +void debug_stderr_closed(void) +{ + if (sdbg == stderr) + sdbg = NULL; + stderr_closed = 1; +} diff --git a/src/debug.h b/src/debug.h index dde22f2..8134894 100644 --- a/src/debug.h +++ b/src/debug.h @@ -17,6 +17,7 @@ static inline int debug_open(const char *path){ return 0; } static inline void debug_close(void){} static inline void debug_init(void){} +static inline void debug_stderr_closed(void){} #else #define dbg(...) dbgprint(__FUNCTION__, __VA_ARGS__) #define cdbg(...) dbgprint(NULL, __VA_ARGS__) @@ -36,6 +37,7 @@ void debug_print_func(void *arg, void (*func)(void *arg, void *stream)); int debug_open(const char *path); void debug_close(void); void debug_init(void); +void debug_stderr_closed(void); #ifndef DEBUG_LOCKING diff --git a/src/main.c b/src/main.c index 79db0ec..6d30bbe 100644 --- a/src/main.c +++ b/src/main.c @@ -128,6 +128,8 @@ static void daemon_start(int ignsigcld) for (fd = 0; fd < NOFILE; fd++) close(fd); errno = 0; + debug_stderr_closed(); + chdir("/tmp"); umask(0); -- 1.9.3 From 46190b25e8a61309846e60fa2b01f9a7007a98bd Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 18 Jul 2014 15:39:32 +0200 Subject: [PATCH 2/2] [BUGFIX] avoid buffer overflow in debug by using vsnprintf() Signed-off-by: Thomas Haller --- src/debug.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/debug.c b/src/debug.c index 36b4767..5688e24 100644 --- a/src/debug.c +++ b/src/debug.c @@ -72,7 +72,8 @@ void dbgprint(const char *fname, const char *fmt, ...) return; va_start(args, fmt); - vsprintf(s, fmt, args); + vsnprintf(s, sizeof(s), fmt, args); + s[sizeof(s) - 1] = '\0'; va_end(args); memset(stime, '\0', sizeof(stime)); @@ -95,7 +96,8 @@ void debug_print_buffer(const void *data, int len, const char *fname, return; va_start(args, fmt); - vsprintf(s, fmt, args); + vsnprintf(s, sizeof(s), fmt, args); + s[sizeof(s) - 1] = '\0'; fprintf(sdbg, "%s: %s", fname, s); va_end(args); for (i = 0; i < len; i++) { -- 1.9.3