Print this page
8175/8183: memory leak fixes + incorrect test of dereferenced pointer

@@ -230,12 +230,14 @@
 static int      nfiles = 0;     /* number of flist entries in current use */
 static int      nargs = 0;      /* number of flist entries used for arguments */
 static int      maxfils = 0;    /* number of flist/lbuf entries allocated */
 static int      maxn = 0;       /* number of flist entries with lbufs asigned */
 static int      quantn = 64;    /* allocation growth quantum */
+static size_t   hlbfsz = 1;
 
 static struct lbuf      *nxtlbf;        /* ptr to next lbuf to be assigned */
+static struct lbuf      **hlbf;         /* lbuf bookkeeping */
 static struct lbuf      **flist;        /* ptr to list of lbuf pointers */
 static struct lbuf      *gstat(char *, int, struct ditem *);
 static char             *getname(uid_t);
 static char             *getgroup(gid_t);
 static char             *makename(char *, char *);

@@ -247,10 +249,11 @@
 static void             rddir(char *, struct ditem *);
 static int              strcol(unsigned char *);
 static void             pem(struct lbuf **, struct lbuf **, int);
 static void             pdirectory(char *, int, int, int, struct ditem *);
 static struct cachenode *findincache(struct cachenode **, long);
+static void             freecachenodes(void);
 static void             csi_pprintf(unsigned char *);
 static void             pprintf(char *, char *);
 static int              compar(struct lbuf **pp1, struct lbuf **pp2);
 static char             *number_to_scaled_string(numbuf_t buf,
                             unsigned long long number,

@@ -411,10 +414,11 @@
         int             i;
         int             width;
         int             amino = 0;
         int             opterr = 0;
         int             option_index = 0;
+        char            *told = NULL;
         struct lbuf     *ep;
         struct lbuf     lb;
         struct ditem    *myinfo = NULL;
 
         (void) setlocale(LC_ALL, "");

@@ -632,11 +636,11 @@
                                         time_fmt_old = FORMAT_OLD;
                                         time_fmt_new = FORMAT_NEW;
                                         continue;
                                 }
                                 if (optarg[0] == '+') {
-                                        char    *told, *tnew;
+                                        char    *tnew;
                                         char    *p;
                                         size_t  timelen = strlen(optarg);
 
                                         p = strchr(optarg, '\n');
                                         if (p != NULL)

@@ -648,11 +652,11 @@
                                          * Add room for 3 spaces + 2 nulls
                                          * The + in optarg is replaced with
                                          * a space.
                                          */
                                         timelen += 2 + 3;
-                                        told = malloc(timelen);
+                                        told = realloc(told, timelen);
                                         if (told == NULL) {
                                                 perror("ls");
                                                 exit(2);
                                         }
 

@@ -662,14 +666,15 @@
                                             timelen);
                                         (void) strlcat(told, " ", timelen);
 
                                         if (p != NULL) {
                                                 size_t tnew_len;
+                                                size_t told_len =strlen(told);
 
-                                                tnew = told + strlen(told) + 1;
+                                                tnew = told + told_len + 1;
                                                 tnew_len = timelen -
-                                                    strlen(told) - 1;
+                                                    told_len - 1;
 
                                                 tnew[0] = ' ';
                                                 (void) strlcat(tnew, p,
                                                     tnew_len);
                                                 (void) strlcat(tnew, " ",

@@ -1020,10 +1025,15 @@
         if (((flist = malloc(maxfils * sizeof (struct lbuf *))) == NULL) ||
             ((nxtlbf = malloc(quantn * sizeof (struct lbuf))) == NULL)) {
                 perror("ls");
                 exit(2);
         }
+        if ((hlbf = malloc(sizeof(*hlbf))) == NULL) {
+                perror("ls");
+                exit(2);
+        }
+        hlbf[0] = nxtlbf;
         if ((amino = (argc-optind)) == 0) {
                                         /*
                                          * case when no names are given
                                          * in ls-command and current
                                          * directory is to be used

@@ -1127,10 +1137,18 @@
                         free(dtemp->dc_name);
                         free(dtemp);
                 }
         }
 
+        for (i = 0; i < hlbfsz; i ++)
+                free(hlbf[i]);
+
+        free(told);
+        free(hlbf);
+        free(flist);
+        freecachenodes();
+
         return (err);
 }
 
 /*
  * pdirectory: print the directory name, labelling it if title is

@@ -1795,11 +1813,17 @@
                     sizeof (struct lbuf))) == NULL)) {
                         perror("ls");
                         nomocore = 1;
                         return (NULL);
                 }
+                if ((hlbf = realloc(hlbf, sizeof(*hlbf) * (hlbfsz + 1))) == NULL) {
+                        perror("ls");
+                        nomocore = 1;
+                        return (NULL);
         }
+                hlbf[hlbfsz++] = nxtlbf;
+        }
 
         /*
          * nfiles is reset to nargs for each directory
          * that is given as an argument maxn is checked
          * to prevent the assignment of an lbuf to a flist entry

@@ -2219,10 +2243,40 @@
         *parent = c;
         c->val = val;
         return (c);
 }
 
+void
+freecachenode(struct cachenode *node)
+{
+        struct cachenode *current = node;
+        if (current != NULL) {
+                struct cachenode *grt = NULL;
+                struct cachenode *lss = NULL;
+
+                if (current->grtrchild != NULL) {
+                        grt = current->grtrchild;
+                        freecachenode(grt);
+                }
+                if (current->lesschild != NULL) {
+                        lss = current->lesschild;
+                        freecachenode(lss);
+                }
+
+                free(current);
+                current = NULL;
+        }
+}
+
+void
+freecachenodes(void)
+{
+        freecachenode(groups);
+        freecachenode(names);
+}
+
+
 /*
  * get name from cache, or passwd file for a given uid;
  * lastuid is set to uid.
  */
 static char *

@@ -2621,11 +2675,11 @@
         uint64_t        *value;
         int             i;
         size_t          len;
 
         if (nvpair_value_uint64_array(pair, &value, &nelem) == 0) {
-                if (*value != NULL) {
+                if (value != NULL) {
                         len = strlen(name);
                         i = 0;
                         while (rep->extm[i].stm != 0 && i < sacnt)
                                 i++;
                         rep->extm[i].stm = value[0];