From nobody@FreeBSD.org  Tue Feb 29 15:20:14 2000
Return-Path: <nobody@FreeBSD.org>
Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21])
	by hub.freebsd.org (Postfix) with ESMTP id 7E68D37B925
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 29 Feb 2000 15:20:14 -0800 (PST)
	(envelope-from nobody@FreeBSD.org)
Received: (from nobody@localhost)
	by freefall.freebsd.org (8.9.3/8.9.2) id PAA93631;
	Tue, 29 Feb 2000 15:20:14 -0800 (PST)
	(envelope-from nobody@FreeBSD.org)
Message-Id: <200002292320.PAA93631@freefall.freebsd.org>
Date: Tue, 29 Feb 2000 15:20:14 -0800 (PST)
From: vova@express.ru
Sender: nobody@FreeBSD.org
To: freebsd-gnats-submit@FreeBSD.org
Subject: memory leak in getcap.c (libc)
X-Send-Pr-Version: www-1.0

>Number:         17084
>Category:       bin
>Synopsis:       memory leak in getcap.c (libc)
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Feb 29 15:30:01 PST 2000
>Closed-Date:    Sat May 20 19:55:16 PDT 2000
>Last-Modified:  Sat May 20 19:56:05 PDT 2000
>Originator:     Vladimir B. Grebenschikov
>Release:        FreeBSD-4.0-CURRENT
>Organization:
TSB Russian Express
>Environment:
FreeBSD lightning.express.ru 4.0-CURRENT FreeBSD 4.0-CURRENT #3: Sun Feb 27 09:26:03 MSK 2000     root@lightning.express.ru:/usr/local/src/fbsd/src/sys/compile/LIGHTNING  i386

>Description:
Compile ang run program below
and all your memory will eaten very quckly
each itteration "eats" about 1.5k memory
---
I have dip a bit into problem and found that memory leaks in
cgetent() called from login_getclassbyname()
>How-To-Repeat:
#include <stdio.h>
#include <sys/types.h>
#include <login_cap.h>
#include <pwd.h>


main()
{

  struct passwd *ent;
  int uid;
  
  ent = getpwnam("nobody"); 
  while(1) {
    login_cap_t *lc;
    uid = ent->pw_uid;
    if ( (lc = login_getclassbyname("root", ent)) == NULL )
                perror("login_getclassbyname: ");
    login_close(lc);      
  }
}

>Fix:
don't know

>Release-Note:
>Audit-Trail:

From: Ruslan Ermilov <ru@ucb.crimea.ua>
To: vova@express.ru
Cc: freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: bin/17084: memory leak in getcap.c (libc)
Date: Wed, 1 Mar 2000 09:56:39 +0200

 On Tue, Feb 29, 2000 at 03:20:14PM -0800, vova@express.ru wrote:
 > 
 > Compile ang run program below
 > and all your memory will eaten very quckly
 > each itteration "eats" about 1.5k memory
 > ---
 > I have dip a bit into problem and found that memory leaks in
 > cgetent() called from login_getclassbyname()
 > >How-To-Repeat:
 > #include <stdio.h>
 > #include <sys/types.h>
 > #include <login_cap.h>
 > #include <pwd.h>
 > 
 > 
 > main()
 > {
 > 
 >   struct passwd *ent;
 >   int uid;
 >   
 >   ent = getpwnam("nobody"); 
 >   while(1) {
 >     login_cap_t *lc;
 >     uid = ent->pw_uid;
 >     if ( (lc = login_getclassbyname("root", ent)) == NULL )
 >                 perror("login_getclassbyname: ");
 >     login_close(lc);      
 >   }
 > }
 > 
 Your code sucks :-)
 
 You should be calling login_close() before each subsequent call of
 function returning login_cap_t object, i.e. login_getclassbyname(),
 login_getclass(), login_getpwclass() and login_getuserclass().
 
 : The login_cap interface provides a convenient means of retrieving login
 : class records with all tc= references expanded.  A program will typically
 : call one of login_getclass(), login_getpwclass(), login_getuserclass() or
 : login_getclassbyname() according to its requirements.  Each of these
 : functions returns a login capabilities structure, login_cap_t which may
 : subsequently be used to interrogate the database for specific values us-
 : ing the rest of the API.  Once the login_cap_t is of no further use, the
 : login_close() function should be called to free all resources used.
 
 
 Cheers,
 -- 
 Ruslan Ermilov		Sysadmin and DBA of the
 ru@ucb.crimea.ua	United Commercial Bank,
 ru@FreeBSD.org		FreeBSD committer,
 +380.652.247.647	Simferopol, Ukraine
 
 http://www.FreeBSD.org	The Power To Serve
 http://www.oracle.com	Enabling The Information Age
 

From: "Vladimir B. Grebenschikov" <vova@express.ru>
To: Ruslan Ermilov <ru@ucb.crimea.ua>
Cc: freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: bin/17084: memory leak in getcap.c (libc)
Date: Sat, 1 May 1999 01:18:50 +0400 (MSD)

 On Wed, 1 Mar 2000, Ruslan Ermilov wrote:
 
 > On Tue, Feb 29, 2000 at 03:20:14PM -0800, vova@express.ru wrote:
 > > 
 > > Compile ang run program below
 > > and all your memory will eaten very quckly
 > > each itteration "eats" about 1.5k memory
 > > ---
 > > I have dip a bit into problem and found that memory leaks in
 > > cgetent() called from login_getclassbyname()
 > > >How-To-Repeat:
 > > #include <stdio.h>
 > > #include <sys/types.h>
 > > #include <login_cap.h>
 > > #include <pwd.h>
 > > 
 > > 
 > > main()
 > > {
 > > 
 > >   struct passwd *ent;
 > >   int uid;
 > >   
 > >   ent = getpwnam("nobody"); 
 > >   while(1) {
 > >     login_cap_t *lc;
 > >     uid = ent->pw_uid;
 > >     if ( (lc = login_getclassbyname("root", ent)) == NULL )
 > >                 perror("login_getclassbyname: ");
 > >     login_close(lc);      
 > >   }
 > > }
 > > 
 > Your code sucks :-)
 > 
 > You should be calling login_close() before each subsequent call of
 > function returning login_cap_t object, i.e. login_getclassbyname(),
 > login_getclass(), login_getpwclass() and login_getuserclass().
 
 I am a bit missunderstand you, my alghorithm is:
 
 cycle begin:
   call login_getclassbyname
   call login_close
 go to cycle begin
 
 exectly what you say: login_close called before each subsequient call of
 login_getclassbyname.
  
 > : The login_cap interface provides a convenient means of retrieving login
 > : class records with all tc= references expanded.  A program will typically
 > : call one of login_getclass(), login_getpwclass(), login_getuserclass() or
 > : login_getclassbyname() according to its requirements.  Each of these
 > : functions returns a login capabilities structure, login_cap_t which may
 > : subsequently be used to interrogate the database for specific values us-
 > : ing the rest of the API.  Once the login_cap_t is of no further use, the
 > : login_close() function should be called to free all resources used.
 > 
 > 
 > Cheers,
 > -- 
 > Ruslan Ermilov		Sysadmin and DBA of the
 > ru@ucb.crimea.ua	United Commercial Bank,
 > ru@FreeBSD.org		FreeBSD committer,
 > +380.652.247.647	Simferopol, Ukraine
 > 
 > http://www.FreeBSD.org	The Power To Serve
 > http://www.oracle.com	Enabling The Information Age
 > 
 
 --
 TSB Russian Express, Moscow
 Vladimir B. Grebenschikov, vova@express.ru
 
 

From: Tim Vanderhoek <tim@localhost.nowhere>
To: freebsd-gnats-submit@FreeBSD.org, vova@express.ru
Cc: vanderh@ecf.toronto.edu
Subject: Re: bin/17084: memory leak in getcap.c (libc)
Date: Tue, 16 May 2000 11:44:41 -0400 (EDT)

 >
 >I have dip a bit into problem and found that memory leaks in
 >cgetent() called from login_getclassbyname()
 
 Will you please tell me if the following patch solves the problem.
 
 This patch solves what appear to be two memory leaks.  There may be
 more memory leaks and which ones you run into may depend on your
 system's specific login.conf configuration.
 
 I can send you copies of the post-patched files to compile with your
 program if you'll find that easier.
 
 Please be sure to Cc: freebsd-gnats-submit@FreeBSD.org and don't change
 the Subject: line in your reply.
 
 Thanks.
 
 --- src/lib/libutil/~login_cap.c	Tue May 16 11:26:03 2000
 +++ src/lib/libutil/login_cap.c	Tue May 16 11:26:19 2000
 @@ -150,10 +150,11 @@ void
  login_close(login_cap_t * lc)
  {
      if (lc) {
  	free(lc->lc_style);
  	free(lc->lc_class);
 +	free(lc->lc_cap);
  	free(lc);
  	if (--lc_object_count == 0) {
  	    free(internal_string);
  	    free(internal_array);
  	    internal_array = NULL;
 --- src/lib/libc/gen/~getcap.c	Tue May 16 11:25:16 2000
 +++ src/lib/libc/gen/getcap.c	Tue May 16 11:39:29 2000
 @@ -380,12 +380,14 @@ getent(cap, len, db_array, fd, name, dep
  	}
  		if (foundit)
  			break;
  	}
  
 -	if (!foundit)
 +	if (!foundit) {
 +		free(record);
  		return (-1);
 +	}
  
  	/*
  	 * Got the capability record, but now we have to expand all tc=name
  	 * references in it ...
  	 */
 
 
State-Changed-From-To: open->closed 
State-Changed-By: hoek 
State-Changed-When: Sat May 20 19:55:16 PDT 2000 
State-Changed-Why:  
Fixed, found one leak in getcap and one leak in login_getclass.  Thanks! 
>Unformatted:
