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.

Reply via email to