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

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/ls/ls.c
          +++ new/usr/src/cmd/ls/ls.c
↓ open down ↓ 224 lines elided ↑ open up ↑
 225  225  static struct dchain *cdfirst;  /* start of the current dir chain */
 226  226  static struct dchain *dtemp;    /* temporary - used for linking */
 227  227  static char *curdir;            /* the current directory */
 228  228  
 229  229  static int      first = 1;      /* true if first line is not yet printed */
 230  230  static int      nfiles = 0;     /* number of flist entries in current use */
 231  231  static int      nargs = 0;      /* number of flist entries used for arguments */
 232  232  static int      maxfils = 0;    /* number of flist/lbuf entries allocated */
 233  233  static int      maxn = 0;       /* number of flist entries with lbufs asigned */
 234  234  static int      quantn = 64;    /* allocation growth quantum */
      235 +static size_t   hlbfsz = 1;
 235  236  
 236  237  static struct lbuf      *nxtlbf;        /* ptr to next lbuf to be assigned */
      238 +static struct lbuf      **hlbf;         /* lbuf bookkeeping */
 237  239  static struct lbuf      **flist;        /* ptr to list of lbuf pointers */
 238  240  static struct lbuf      *gstat(char *, int, struct ditem *);
 239  241  static char             *getname(uid_t);
 240  242  static char             *getgroup(gid_t);
 241  243  static char             *makename(char *, char *);
 242  244  static void             pentry(struct lbuf *);
 243  245  static void             column(void);
 244  246  static void             pmode(mode_t aflag);
 245  247  static void             selection(int *);
 246  248  static void             new_line(void);
 247  249  static void             rddir(char *, struct ditem *);
 248  250  static int              strcol(unsigned char *);
 249  251  static void             pem(struct lbuf **, struct lbuf **, int);
 250  252  static void             pdirectory(char *, int, int, int, struct ditem *);
 251  253  static struct cachenode *findincache(struct cachenode **, long);
      254 +static void             freecachenodes(void);
 252  255  static void             csi_pprintf(unsigned char *);
 253  256  static void             pprintf(char *, char *);
 254  257  static int              compar(struct lbuf **pp1, struct lbuf **pp2);
 255  258  static char             *number_to_scaled_string(numbuf_t buf,
 256  259                              unsigned long long number,
 257  260                              long scale);
 258  261  static void             record_ancestry(char *, struct stat *, struct lbuf *,
 259  262                              int, struct ditem *);
 260  263  static void             ls_color_init(void);
 261  264  static ls_color_t       *ls_color_find(const char *, mode_t);
↓ open down ↓ 144 lines elided ↑ open up ↑
 406  409  
 407  410  int
 408  411  main(int argc, char *argv[])
 409  412  {
 410  413          int             c;
 411  414          int             i;
 412  415          int             width;
 413  416          int             amino = 0;
 414  417          int             opterr = 0;
 415  418          int             option_index = 0;
      419 +        char            *told = NULL;
 416  420          struct lbuf     *ep;
 417  421          struct lbuf     lb;
 418  422          struct ditem    *myinfo = NULL;
 419  423  
 420  424          (void) setlocale(LC_ALL, "");
 421  425  #if !defined(TEXT_DOMAIN)       /* Should be defined by cc -D */
 422  426  #define TEXT_DOMAIN "SYS_TEST"  /* Use this only if it weren't */
 423  427  #endif
 424  428          (void) textdomain(TEXT_DOMAIN);
 425  429  #ifdef STANDALONE
↓ open down ↓ 201 lines elided ↑ open up ↑
 627  631                                          time_fmt_new = FORMAT_ISO_NEW;
 628  632                                          continue;
 629  633                                  }
 630  634                                  /* should be the default */
 631  635                                  if (strcmp(optarg, "locale") == 0) {
 632  636                                          time_fmt_old = FORMAT_OLD;
 633  637                                          time_fmt_new = FORMAT_NEW;
 634  638                                          continue;
 635  639                                  }
 636  640                                  if (optarg[0] == '+') {
 637      -                                        char    *told, *tnew;
      641 +                                        char    *tnew;
 638  642                                          char    *p;
 639  643                                          size_t  timelen = strlen(optarg);
 640  644  
 641  645                                          p = strchr(optarg, '\n');
 642  646                                          if (p != NULL)
 643  647                                                  *p++ = '\0';
 644  648  
 645  649                                          /*
 646  650                                           * Time format requires a leading and
 647  651                                           * trailing space
 648  652                                           * Add room for 3 spaces + 2 nulls
 649  653                                           * The + in optarg is replaced with
 650  654                                           * a space.
 651  655                                           */
 652  656                                          timelen += 2 + 3;
 653      -                                        told = malloc(timelen);
      657 +                                        told = realloc(told, timelen);
 654  658                                          if (told == NULL) {
 655  659                                                  perror("ls");
 656  660                                                  exit(2);
 657  661                                          }
 658  662  
 659  663                                          (void) memset(told, 0, timelen);
 660  664                                          told[0] = ' ';
 661  665                                          (void) strlcat(told, &optarg[1],
 662  666                                              timelen);
 663  667                                          (void) strlcat(told, " ", timelen);
 664  668  
 665  669                                          if (p != NULL) {
 666  670                                                  size_t tnew_len;
      671 +                                                size_t told_len =strlen(told);
 667  672  
 668      -                                                tnew = told + strlen(told) + 1;
      673 +                                                tnew = told + told_len + 1;
 669  674                                                  tnew_len = timelen -
 670      -                                                    strlen(told) - 1;
      675 +                                                    told_len - 1;
 671  676  
 672  677                                                  tnew[0] = ' ';
 673  678                                                  (void) strlcat(tnew, p,
 674  679                                                      tnew_len);
 675  680                                                  (void) strlcat(tnew, " ",
 676  681                                                      tnew_len);
 677  682                                                  time_fmt_new =
 678  683                                                      (const char *)tnew;
 679  684                                          } else {
 680  685                                                  time_fmt_new =
↓ open down ↓ 334 lines elided ↑ open up ↑
1015 1020                  num_cols = 80;
1016 1021  
1017 1022          /* allocate space for flist and the associated  */
1018 1023          /* data structures (lbufs)                      */
1019 1024          maxfils = quantn;
1020 1025          if (((flist = malloc(maxfils * sizeof (struct lbuf *))) == NULL) ||
1021 1026              ((nxtlbf = malloc(quantn * sizeof (struct lbuf))) == NULL)) {
1022 1027                  perror("ls");
1023 1028                  exit(2);
1024 1029          }
     1030 +        if ((hlbf = malloc(sizeof(*hlbf))) == NULL) {
     1031 +                perror("ls");
     1032 +                exit(2);
     1033 +        }
     1034 +        hlbf[0] = nxtlbf;
1025 1035          if ((amino = (argc-optind)) == 0) {
1026 1036                                          /*
1027 1037                                           * case when no names are given
1028 1038                                           * in ls-command and current
1029 1039                                           * directory is to be used
1030 1040                                           */
1031 1041                  argv[optind] = dotp;
1032 1042          }
1033 1043  
1034 1044          if (colorflg)
↓ open down ↓ 87 lines elided ↑ open up ↑
1122 1132                          dfirst = dfirst->dc_next;
1123 1133                          pdirectory(dtemp->dc_name, 1, nargs,
1124 1134                              dtemp->cycle_detected, dtemp->myancinfo);
1125 1135                          if (nomocore)
1126 1136                                  exit(2);
1127 1137                          free(dtemp->dc_name);
1128 1138                          free(dtemp);
1129 1139                  }
1130 1140          }
1131 1141  
     1142 +        for (i = 0; i < hlbfsz; i ++)
     1143 +                free(hlbf[i]);
     1144 +
     1145 +        free(told);
     1146 +        free(hlbf);
     1147 +        free(flist);
     1148 +        freecachenodes();
     1149 +
1132 1150          return (err);
1133 1151  }
1134 1152  
1135 1153  /*
1136 1154   * pdirectory: print the directory name, labelling it if title is
1137 1155   * nonzero, using lp as the place to start reading in the dir.
1138 1156   */
1139 1157  static void
1140 1158  pdirectory(char *name, int title, int lp, int cdetect, struct ditem *myinfo)
1141 1159  {
↓ open down ↓ 648 lines elided ↑ open up ↑
1790 1808                   */
1791 1809                  maxfils += quantn;
1792 1810                  if (((flist = realloc(flist,
1793 1811                      maxfils * sizeof (struct lbuf *))) == NULL) ||
1794 1812                      ((nxtlbf = malloc(quantn *
1795 1813                      sizeof (struct lbuf))) == NULL)) {
1796 1814                          perror("ls");
1797 1815                          nomocore = 1;
1798 1816                          return (NULL);
1799 1817                  }
     1818 +                if ((hlbf = realloc(hlbf, sizeof(*hlbf) * (hlbfsz + 1))) == NULL) {
     1819 +                        perror("ls");
     1820 +                        nomocore = 1;
     1821 +                        return (NULL);
     1822 +                }
     1823 +                hlbf[hlbfsz++] = nxtlbf;
1800 1824          }
1801 1825  
1802 1826          /*
1803 1827           * nfiles is reset to nargs for each directory
1804 1828           * that is given as an argument maxn is checked
1805 1829           * to prevent the assignment of an lbuf to a flist entry
1806 1830           * that already has one assigned.
1807 1831           */
1808 1832          if (nfiles >= maxn) {
1809 1833                  rep = nxtlbf++;
↓ open down ↓ 404 lines elided ↑ open up ↑
2214 2238          c = calloc(1, sizeof (struct cachenode));
2215 2239          if (c == NULL) {
2216 2240                  perror("ls");
2217 2241                  exit(2);
2218 2242          }
2219 2243          *parent = c;
2220 2244          c->val = val;
2221 2245          return (c);
2222 2246  }
2223 2247  
     2248 +void
     2249 +freecachenode(struct cachenode *node)
     2250 +{
     2251 +        struct cachenode *current = node;
     2252 +        if (current != NULL) {
     2253 +                struct cachenode *grt = NULL;
     2254 +                struct cachenode *lss = NULL;
     2255 +
     2256 +                if (current->grtrchild != NULL) {
     2257 +                        grt = current->grtrchild;
     2258 +                        freecachenode(grt);
     2259 +                }
     2260 +                if (current->lesschild != NULL) {
     2261 +                        lss = current->lesschild;
     2262 +                        freecachenode(lss);
     2263 +                }
     2264 +
     2265 +                free(current);
     2266 +                current = NULL;
     2267 +        }
     2268 +}
     2269 +
     2270 +void
     2271 +freecachenodes(void)
     2272 +{
     2273 +        freecachenode(groups);
     2274 +        freecachenode(names);
     2275 +}
     2276 +
     2277 +
2224 2278  /*
2225 2279   * get name from cache, or passwd file for a given uid;
2226 2280   * lastuid is set to uid.
2227 2281   */
2228 2282  static char *
2229 2283  getname(uid_t uid)
2230 2284  {
2231 2285          struct passwd *pwent;
2232 2286          struct cachenode *c;
2233 2287  
↓ open down ↓ 382 lines elided ↑ open up ↑
2616 2670  
2617 2671  void
2618 2672  set_sysattrtm_display(char *name, struct lbuf *rep)
2619 2673  {
2620 2674          uint_t          nelem;
2621 2675          uint64_t        *value;
2622 2676          int             i;
2623 2677          size_t          len;
2624 2678  
2625 2679          if (nvpair_value_uint64_array(pair, &value, &nelem) == 0) {
2626      -                if (*value != NULL) {
     2680 +                if (value != NULL) {
2627 2681                          len = strlen(name);
2628 2682                          i = 0;
2629 2683                          while (rep->extm[i].stm != 0 && i < sacnt)
2630 2684                                  i++;
2631 2685                          rep->extm[i].stm = value[0];
2632 2686                          rep->extm[i].nstm = value[1];
2633 2687                          rep->extm[i].name = xmalloc(len + 1, rep);
2634 2688                          (void) strlcpy(rep->extm[i].name, name, len + 1);
2635 2689                  }
2636 2690          }
↓ open down ↓ 571 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX