From owner-freebsd-bugs@FreeBSD.ORG Sat Mar 7 11:46:40 2015 Return-Path: Delivered-To: freebsd-bugs@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 3B8A8511 for ; Sat, 7 Mar 2015 11:46:40 +0000 (UTC) Received: from kenobi.freebsd.org (kenobi.freebsd.org [IPv6:2001:1900:2254:206a::16:76]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1CE481B0 for ; Sat, 7 Mar 2015 11:46:40 +0000 (UTC) Received: from bugs.freebsd.org ([127.0.1.118]) by kenobi.freebsd.org (8.14.9/8.14.9) with ESMTP id t27BkdSh071368 for ; Sat, 7 Mar 2015 11:46:39 GMT (envelope-from bugzilla-noreply@freebsd.org) From: bugzilla-noreply@freebsd.org To: freebsd-bugs@FreeBSD.org Subject: [Bug 198385] syslogd seems to leak memory under certain circumstances Date: Sat, 07 Mar 2015 11:46:40 +0000 X-Bugzilla-Reason: AssignedTo X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: Base System X-Bugzilla-Component: bin X-Bugzilla-Version: 10.1-RELEASE X-Bugzilla-Keywords: X-Bugzilla-Severity: Affects Some People X-Bugzilla-Who: sreeramabs@yahoo.com X-Bugzilla-Status: New X-Bugzilla-Priority: --- X-Bugzilla-Assigned-To: freebsd-bugs@FreeBSD.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: cc Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: https://bugs.freebsd.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 07 Mar 2015 11:46:40 -0000 https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=198385 Sreeram changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |sreeramabs@yahoo.com --- Comment #1 from Sreeram --- The syslogd daemon seems to be leaking few bytes of memory when modifications are done to the /etc/syslog.conf when it has entries to forward the syslog messages to a remote-host, and making syslogd read the new conf by signalling it with a SIGHUP. Consider the following entries in /etc/syslog.conf # $FreeBSD: releng/10.1/etc/syslog.conf 260519 2014-01-10 17:56:23Z asomers $ # # Spaces ARE valid field separators in this file. However, # other *nix-like systems still insist on using tabs as field # separators. If you are sharing this file between systems, you # may want to use only tabs as field separators here. # Consult the syslog.conf(5) manpage. *.err;kern.warning;auth.notice;mail.crit /dev/console *.notice;authpriv.none;kern.debug;lpr.info;mail.crit;news.err /var/log/messages security.* /var/log/security auth.info;authpriv.info /var/log/auth.log mail.info /var/log/maillog lpr.info /var/log/lpd-errs ftp.info /var/log/xferlog cron.* /var/log/cron !-devd *.=debug /var/log/debug.log *.emerg * # uncomment this to log all writes to /dev/console to /var/log/console.log # touch /var/log/console.log and chmod it to mode 600 before it will work #console.info /var/log/console.log # uncomment this to enable logging of all log messages to /var/log/all.log # touch /var/log/all.log and chmod it to mode 600 before it will work #*.* /var/log/all.log # uncomment this to enable logging to a remote loghost named loghost #*.* @loghost *.info @192.168.1.40 *.info @192.168.1.41 *.info @192.168.1.42 *.info @192.168.1.43 Now, the last three lines above are replaced with a line with different host, So, the file (at those lines) looks like this: *.info @192.168.1.40 *.info @192.168.1.51 << Two lines removed Now, I issue the 'kill -HUP ' This would re-read this conf file, by first flushing out the current entries. During this situation, the syslogd seems to be leaking few bytes of memory. This is because, whenever syslogd reads the conf-file, and finds an entry for remote-host, it issues a 'getaddrinfo' to get the name resolution for that entry. getaddrinfo() will internally allocated memory for linked-list of addresses related to that host, and will return the same. The caller is supposed to free that memory by issuing freeaddrinfo() once his task is done. The portion of code where getaddrinfo() is called in syslogd.c file of FreeBSD-10.1 is: 1776 1777 /* 1778 * Crack a configuration file line 1779 */ 1780 static void 1781 cfline(const char *line, struct filed *f, const char *prog, const char *host) 1782 { 1783 struct addrinfo hints, *res; 1784 int error, i, pri, syncfile; 1785 const char *p, *q; 1786 char *bp; ... ... 1939 1940 switch (*p) { 1941 case '@': 1942 { 1943 char *tp; 1944 char endkey = ':'; ... ... 1974 memset(&hints, 0, sizeof(hints)); 1975 hints.ai_family = family; 1976 hints.ai_socktype = SOCK_DGRAM; 1977 error = getaddrinfo(f->f_un.f_forw.f_hname, 1978 p ? p : "syslog", &hints, &res); 1979 if (error) { 1980 logerror(gai_strerror(error)); 1981 break; 1982 } 1983 f->f_un.f_forw.f_addr = res; 1984 f->f_type = F_FORW; 1985 break; The address is collected and set ready for remote-logging the syslog messages. Now, when changes are done to syslog.conf file, and SIGHUP issued, the init() function gets called, and in this function, arrangements to free up this memory returned by getaddrinfo() is not made. The init() function looks like this: 1533 1534 /* 1535 * INIT -- Initialize syslogd from configuration table 1536 */ 1537 static void 1538 init(int signo) 1539 { 1540 int i; 1541 FILE *cf; 1542 struct filed *f, *next, **nextp; 1543 char *p; 1544 char cline[LINE_MAX]; ... ... 1577 switch (f->f_type) { 1578 case F_FILE: 1579 case F_FORW: <<<<<<< No arrangements to call freeaddrinfo() 1588 case F_CONSOLE: 1581 case F_TTY: 1582 (void)close(f->f_file); 1583 break; 1584 case F_PIPE: 1585 if (f->f_un.f_pipe.f_pid > 0) { 1586 (void)close(f->f_file); 1587 deadq_enter(f->f_un.f_pipe.f_pid, 1588 f->f_un.f_pipe.f_pname); 1589 } 1590 f->f_un.f_pipe.f_pid = 0; 1591 break; 1592 } This results in a memory leak. Although this could be of few bytes, it would be nice to fix this, as the fix is simple. I have made the changes to syslogd.c (in my FreeBSD box) to fix this issue. The changes look like this: 1577 switch (f->f_type) { 1578 case F_FILE: 1579 case F_FORW: 1580 if (f->f_un.f_forw.f_addr) { <<< 1581 freeaddrinfo(f->f_un.f_forw.f_addr); <<< Call freeaddrinfo 1583 } <<< 1584 /* fall through */ <<< 1585 case F_CONSOLE: 1586 case F_TTY: 1587 (void)close(f->f_file); 1588 break; 1589 case F_PIPE: 1590 if (f->f_un.f_pipe.f_pid > 0) { 1591 (void)close(f->f_file); 1592 deadq_enter(f->f_un.f_pipe.f_pid, 1593 f->f_un.f_pipe.f_pname); 1594 } 1595 f->f_un.f_pipe.f_pid = 0; 1596 break; 1597 } Request: I would like to take up this task of fixing this issue. I have never contributed to FreeBSD-code before this, and this is a great opportunity for me to fix this and contribute. But, I request you to kindly suggest me the steps followed by other developers in FreeBSD for fixing BUGs. Please inform. Regards, Sreeram -- You are receiving this mail because: You are the assignee for the bug.