this is tricky, but not too hard. expanded dfff context to see the malloc.
Index: kern_descrip.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_descrip.c,v
retrieving revision 1.130
diff -u -p -u -1 -7 -r1.130 kern_descrip.c
--- kern_descrip.c 25 Apr 2016 20:18:31 -0000 1.130
+++ kern_descrip.c 10 May 2016 22:53:35 -0000
@@ -836,55 +836,57 @@ fdexpand(struct proc *p)
newofile = mallocarray(nfiles, OFILESIZE, M_FILEDESC, M_WAITOK);
newofileflags = (char *) &newofile[nfiles];
/*
* Copy the existing ofile and ofileflags arrays
* and zero the new portion of each array.
*/
copylen = sizeof(struct file *) * fdp->fd_nfiles;
memcpy(newofile, fdp->fd_ofiles, copylen);
memset((char *)newofile + copylen, 0,
nfiles * sizeof(struct file *) - copylen);
copylen = sizeof(char) * fdp->fd_nfiles;
memcpy(newofileflags, fdp->fd_ofileflags, copylen);
memset(newofileflags + copylen, 0, nfiles * sizeof(char) - copylen);
if (fdp->fd_nfiles > NDFILE)
- free(fdp->fd_ofiles, M_FILEDESC, 0);
+ free(fdp->fd_ofiles, M_FILEDESC, fdp->fd_nfiles * OFILESIZE);
if (NDHISLOTS(nfiles) > NDHISLOTS(fdp->fd_nfiles)) {
newhimap = mallocarray(NDHISLOTS(nfiles), sizeof(u_int),
M_FILEDESC, M_WAITOK);
newlomap = mallocarray(NDLOSLOTS(nfiles), sizeof(u_int),
M_FILEDESC, M_WAITOK);
copylen = NDHISLOTS(fdp->fd_nfiles) * sizeof(u_int);
memcpy(newhimap, fdp->fd_himap, copylen);
memset((char *)newhimap + copylen, 0,
NDHISLOTS(nfiles) * sizeof(u_int) - copylen);
copylen = NDLOSLOTS(fdp->fd_nfiles) * sizeof(u_int);
memcpy(newlomap, fdp->fd_lomap, copylen);
memset((char *)newlomap + copylen, 0,
NDLOSLOTS(nfiles) * sizeof(u_int) - copylen);
if (NDHISLOTS(fdp->fd_nfiles) > NDHISLOTS(NDFILE)) {
- free(fdp->fd_himap, M_FILEDESC, 0);
- free(fdp->fd_lomap, M_FILEDESC, 0);
+ free(fdp->fd_himap, M_FILEDESC,
+ NDHISLOTS(fdp->fd_nfiles) * sizeof(u_int));
+ free(fdp->fd_lomap, M_FILEDESC,
+ NDHISLOTS(fdp->fd_nfiles) * sizeof(u_int));
}
fdp->fd_himap = newhimap;
fdp->fd_lomap = newlomap;
}
fdp->fd_ofiles = newofile;
fdp->fd_ofileflags = newofileflags;
fdp->fd_nfiles = nfiles;
}
/*
* Create a new open file structure and allocate
* a file descriptor for the process that refers to it.
*/
int
falloc(struct proc *p, struct file **resultfp, int *resultfd)
{
struct file *fp, *fq;
@@ -1068,38 +1070,40 @@ fdfree(struct proc *p)
struct filedesc *fdp = p->p_fd;
struct file **fpp, *fp;
int i;
if (--fdp->fd_refcnt > 0)
return;
fpp = fdp->fd_ofiles;
for (i = fdp->fd_lastfile; i >= 0; i--, fpp++) {
fp = *fpp;
if (fp != NULL) {
FREF(fp);
*fpp = NULL;
(void) closef(fp, p);
}
}
p->p_fd = NULL;
if (fdp->fd_nfiles > NDFILE)
- free(fdp->fd_ofiles, M_FILEDESC, 0);
+ free(fdp->fd_ofiles, M_FILEDESC, fdp->fd_nfiles * OFILESIZE);
if (NDHISLOTS(fdp->fd_nfiles) > NDHISLOTS(NDFILE)) {
- free(fdp->fd_himap, M_FILEDESC, 0);
- free(fdp->fd_lomap, M_FILEDESC, 0);
+ free(fdp->fd_himap, M_FILEDESC,
+ NDHISLOTS(fdp->fd_nfiles) * sizeof(u_int));
+ free(fdp->fd_lomap, M_FILEDESC,
+ NDHISLOTS(fdp->fd_nfiles) * sizeof(u_int));
}
if (fdp->fd_cdir)
vrele(fdp->fd_cdir);
if (fdp->fd_rdir)
vrele(fdp->fd_rdir);
free(fdp->fd_knlist, M_TEMP, fdp->fd_knlistsize * sizeof(struct klist));
free(fdp->fd_knhash, M_TEMP, 0);
pool_put(&fdesc_pool, fdp);
}
/*
* Internal form of close.
* Decrement reference count on file structure.
* Note: p may be NULL when closing a file
* that was being passed in a message.
*
* The fp must have its usecount bumped and will be FRELEd here.