misc/118380: libkvm - kvm_close doesn't dealocate all used memory

Michal Vranek michal.vranek at seznam.cz
Sun Dec 2 02:00:04 PST 2007


>Number:         118380
>Category:       misc
>Synopsis:       libkvm - kvm_close doesn't dealocate all used memory
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Dec 02 10:00:03 UTC 2007
>Closed-Date:
>Last-Modified:
>Originator:     Michal Vranek
>Release:        6.2, 6.3
>Organization:
>Environment:
FreeBSD xerius.felk.cvut.cz 6.3-PRERELEASE FreeBSD 6.3-PRERELEASE #3: Sun Nov  4                                           22:19:33 CET 2007     root at xerius.felk.cvut.cz:/usr/obj/usr/src/sys/XERIUS  i38                                          6
>Description:
Using more times sequencely kvm-library functions to get environment variables of  other running proceses causes memory consume in the questioning process.

I think the reason is kd->argspc and kd->argbuf nowhere dealocated.


>How-To-Repeat:
Run this code and watch its size in memory.

void main()
{
pid_t pid;
scanf("%d",&pid); // input pid of another running proces
while(1) 
{
  int count;

  char errbuf[_POSIX2_LINE_MAX];

  struct kinfo_proc *process_identity;

  kvm_t *kd;

  char **environment_variables;

  kd = kvm_openfiles( NULL , NULL, NULL, O_RDONLY, errbuf );

  if ( kd == NULL ) exit(1);

  process_identity = kvm_getprocs( kd, KERN_PROC_PID, pid, &count );

  if ( process_identity == NULL )
  {
   kvm_close( kd );

   exit(1);
  }

  environment_variables = kvm_getenvv( kd, process_identity, 0 );

  if( environment_variables == NULL )
  {
   kvm_close( kd );

   exit(1);
  }

  /* here could be variables listing */

  kvm_close( kd );
}
}
>Fix:
Most probably the solution is to modify (add two times free()) kvm_close() in /usr/src/lib/libkvm/kvm.c .

int
kvm_close(kd)
        kvm_t *kd;
{
        int error = 0;

        if (kd->pmfd >= 0)
                error |= close(kd->pmfd);
        if (kd->vmfd >= 0)
                error |= close(kd->vmfd);
        if (kd->nlfd >= 0)
                error |= close(kd->nlfd);
        if (kd->vmst)
                _kvm_freevtop(kd);
        if (kd->procbase != 0)
                free((void *)kd->procbase);
        if (kd->argv != 0)
                free((void *)kd->argv);
/////////////////////////////////////////////
        if (kd->argspc != 0)
                free((void *) kd->argspc);
        if (kd->argbuf != 0)
                free((void *) kd->argbuf);
/////////////////////////////////////////////
        free((void *)kd);

        return (0);
}


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list