Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 Jun 2001 13:40:02 -0700 (PDT)
From:      mark@whistle.com
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   bin/28108: [PATCH] cron leaks memory when reloading crontab files
Message-ID:  <200106122040.f5CKe2K09865@whistle.com>

next in thread | raw e-mail | index | archive | help

>Number:         28108
>Category:       bin
>Synopsis:       [PATCH] cron leaks memory when reloading crontab files
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Jun 12 13:50:01 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Mark Peek
>Release:        FreeBSD 4.3-RELEASE i386
>Organization:
Whistle Communications, Inc.
>Environment:
System: FreeBSD shark.whistle.com 4.3-RELEASE FreeBSD 4.3-RELEASE #5: Mon May 7 11:42:59 PDT 2001 root@shark.whistle.com:/usr/obj/usr/src/sys/INTELLISTATION_SMP i386


>Description:
Based on a cron.core image from my favorite, long running internet server
appliance, I discovered (with help from gdb) that cron was leaking memory.

By code inspection, I discovered 2 leaks.

1. Calls were made to login_getclass() without a cooresponding call to
login_close(). This leaks 1 login_cap_t (plus associated data storage) for
every crontab entry. It appears this bug was introduced back in late 1997.

2. There was a possibility of additional leakage (e->class) due to the way
storage was freed in the error case for the call to entry.c:loadentry().

>How-To-Repeat:
Fire up cron and keep touching crontab files to ensure it reloads the files
often. Use ps to check on the memory usage or wait long enough for it to
exhaust its memory limit. (While testing, I also put in a syslog() in to
verify it is leaking the login_cap_t once per entry.)

>Fix:
Apply the patch below.

Index: usr.sbin/cron/lib/entry.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/cron/lib/entry.c,v
retrieving revision 1.9.2.2
diff -u -r1.9.2.2 entry.c
--- usr.sbin/cron/lib/entry.c	2000/07/01 10:35:07	1.9.2.2
+++ usr.sbin/cron/lib/entry.c	2001/06/12 18:13:53
@@ -262,6 +262,9 @@
 		char		*username = cmd;	/* temp buffer */
 		char            *s, *group;
 		struct group    *grp;
+#ifdef LOGIN_CAP
+		login_cap_t *lc;
+#endif
 
 		Debug(DPARS, ("load_entry()...about to parse username\n"))
 		ch = get_string(username, MAX_COMMAND, file, " \t");
@@ -287,10 +290,11 @@
 			ecode = e_mem;
 			goto eof;
 		}
-		if (login_getclass(e->class) == NULL) {
+		if ((lc = login_getclass(e->class)) == NULL) {
 			ecode = e_class;
 			goto eof;
 		}
+		login_close(lc);
 #endif
 		grp = NULL;
 		if ((s = strrchr(username, ':')) != NULL) {
@@ -416,7 +420,7 @@
 	return e;
 
  eof:
-	free(e);
+	free_entry(e);
 	if (ecode != e_none && error_func)
 		(*error_func)(ecodes[(int)ecode]);
 	while (ch != EOF && ch != '\n')
>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200106122040.f5CKe2K09865>