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