Print this page
smatch clean rtld


 379 int
 380 fpavl_insert(Lm_list *lml, Rt_map *lmp, const char *name, avl_index_t where)
 381 {
 382         FullPathNode    *fpnp;
 383         uint_t          hash = sgs_str_hash(name);
 384 
 385         if (where == 0) {
 386                 /* LINTED */
 387                 Rt_map  *_lmp = fpavl_recorded(lml, name, hash, &where);
 388 
 389                 /*
 390                  * We better not get a hit now, we do not want duplicates in
 391                  * the tree.
 392                  */
 393                 ASSERT(_lmp == NULL);
 394         }
 395 
 396         /*
 397          * Insert new node in tree.
 398          */
 399         if ((fpnp = calloc(sizeof (FullPathNode), 1)) == NULL)
 400                 return (0);
 401 
 402         fpnp->fpn_node.pn_name = name;
 403         fpnp->fpn_node.pn_hash = hash;
 404         fpnp->fpn_lmp = lmp;
 405 
 406         if (aplist_append(&FPNODE(lmp), fpnp, AL_CNT_FPNODE) == NULL) {
 407                 free(fpnp);
 408                 return (0);
 409         }
 410 
 411         ASSERT(lml->lm_fpavl != NULL);
 412         avl_insert(lml->lm_fpavl, fpnp, where);
 413         return (1);
 414 }
 415 
 416 /*
 417  * Remove an object from the FullPathNode AVL tree.
 418  */
 419 void


 442 void
 443 nfavl_insert(const char *name, avl_index_t where)
 444 {
 445         PathNode        *pnp;
 446         uint_t          hash = sgs_str_hash(name);
 447 
 448         if (where == 0) {
 449                 /* LINTED */
 450                 int     in_nfavl = pnavl_recorded(&nfavl, name, hash, &where);
 451 
 452                 /*
 453                  * We better not get a hit now, we do not want duplicates in
 454                  * the tree.
 455                  */
 456                 ASSERT(in_nfavl == 0);
 457         }
 458 
 459         /*
 460          * Insert new node in tree.
 461          */
 462         if ((pnp = calloc(sizeof (PathNode), 1)) != NULL) {
 463                 pnp->pn_name = name;
 464                 pnp->pn_hash = hash;
 465                 avl_insert(nfavl, pnp, where);
 466         }
 467 }
 468 
 469 /*
 470  * Insert the directory name, of a full path name, into the secure path AVL
 471  * tree.
 472  *
 473  * This tree is used to maintain a list of directories in which the dependencies
 474  * of a secure process have been found.  This list provides a fall-back in the
 475  * case that a $ORIGIN expansion is deemed insecure, when the expansion results
 476  * in a path name that has already provided dependencies.
 477  */
 478 void
 479 spavl_insert(const char *name)
 480 {
 481         char            buffer[PATH_MAX], *str;
 482         size_t          size;


 489          */
 490         if ((str = strrchr(name, '/')) == name)
 491                 size = 1;
 492         else
 493                 size = str - name;
 494 
 495         (void) strncpy(buffer, name, size);
 496         buffer[size] = '\0';
 497         hash = sgs_str_hash(buffer);
 498 
 499         /*
 500          * Determine whether this directory name is already recorded, or if
 501          * not, 'where" will provide the insertion point for the new string.
 502          */
 503         if (pnavl_recorded(&spavl, buffer, hash, &where))
 504                 return;
 505 
 506         /*
 507          * Insert new node in tree.
 508          */
 509         if ((pnp = calloc(sizeof (PathNode), 1)) != NULL) {
 510                 pnp->pn_name = strdup(buffer);
 511                 pnp->pn_hash = hash;
 512                 avl_insert(spavl, pnp, where);
 513         }
 514 }
 515 
 516 /*
 517  * Inspect the generic string AVL tree for the given string.  If the string is
 518  * not present, duplicate it, and insert the string in the AVL tree.  Return the
 519  * duplicated string to the caller.
 520  *
 521  * These strings are maintained for the life of ld.so.1 and represent path
 522  * names, file names, and search paths.  All other AVL trees that maintain
 523  * FullPathNode and not-found path names use the same string pointer
 524  * established for this string.
 525  */
 526 static avl_tree_t       *stravl = NULL;
 527 static char             *strbuf = NULL;
 528 static PathNode         *pnbuf = NULL;
 529 static size_t           strsize = 0, pnsize = 0;


2871 
2872 static char     errbuf[ERRSIZE], *nextptr = errbuf, *prevptr = NULL;
2873 
2874 /*
2875  * All error messages go through eprintf().  During process initialization,
2876  * these messages are directed to the standard error, however once control has
2877  * been passed to the applications code these messages are stored in an internal
2878  * buffer for use with dlerror().  Note, fatal error conditions that may occur
2879  * while running the application will still cause a standard error message, see
2880  * rtldexit() in this file for details.
2881  * The RT_FL_APPLIC flag serves to indicate the transition between process
2882  * initialization and when the applications code is running.
2883  */
2884 void
2885 veprintf(Lm_list *lml, Error error, const char *format, va_list args)
2886 {
2887         int             overflow = 0;
2888         static int      lock = 0;
2889         Prfbuf          prf;
2890 
2891         if (lock || (nextptr == (errbuf + ERRSIZE)))
2892                 return;
2893 
2894         /*
2895          * Note: this lock is here to prevent the same thread from recursively
2896          * entering itself during a eprintf.  ie: during eprintf malloc() fails
2897          * and we try and call eprintf ... and then malloc() fails ....
2898          */
2899         lock = 1;
2900 
2901         /*
2902          * If we have completed startup initialization, all error messages
2903          * must be saved.  These are reported through dlerror().  If we're
2904          * still in the initialization stage, output the error directly and
2905          * add a newline.
2906          */
2907         prf.pr_buf = prf.pr_cur = nextptr;
2908         prf.pr_len = ERRSIZE - (nextptr - errbuf);
2909 
2910         if ((rtld_flags & RT_FL_APPLIC) == 0)
2911                 prf.pr_fd = 2;


3109                         /*
3110                          * If the error buffer has been used, write out all
3111                          * pending messages - lasterr is simply a pointer to
3112                          * the last message in this buffer.  However, if the
3113                          * buffer couldn't be created at all, lasterr points
3114                          * to a constant error message string.
3115                          */
3116                         if (*errbuf) {
3117                                 char    *errptr = errbuf;
3118                                 char    *errend = errbuf + ERRSIZE;
3119 
3120                                 while ((errptr < errend) && *errptr) {
3121                                         size_t  size = strlen(errptr);
3122                                         (void) write(2, errptr, size);
3123                                         (void) write(2, MSG_ORIG(MSG_STR_NL),
3124                                             MSG_STR_NL_SIZE);
3125                                         errptr += (size + 1);
3126                                 }
3127                         }
3128                         if (lasterr && ((lasterr < errbuf) ||
3129                             (lasterr > (errbuf + ERRSIZE)))) {
3130                                 (void) write(2, lasterr, strlen(lasterr));
3131                                 (void) write(2, MSG_ORIG(MSG_STR_NL),
3132                                     MSG_STR_NL_SIZE);
3133                         }
3134                 }
3135                 leave(lml, 0);
3136                 (void) _lwp_kill(_lwp_self(), killsig);
3137         }
3138         _exit(status);
3139 }
3140 
3141 /*
3142  * Map anonymous memory via MAP_ANON (added in Solaris 8).
3143  */
3144 void *
3145 dz_map(Lm_list *lml, caddr_t addr, size_t len, int prot, int flags)
3146 {
3147         caddr_t va;
3148 
3149         if ((va = (caddr_t)mmap(addr, len, prot,




 379 int
 380 fpavl_insert(Lm_list *lml, Rt_map *lmp, const char *name, avl_index_t where)
 381 {
 382         FullPathNode    *fpnp;
 383         uint_t          hash = sgs_str_hash(name);
 384 
 385         if (where == 0) {
 386                 /* LINTED */
 387                 Rt_map  *_lmp = fpavl_recorded(lml, name, hash, &where);
 388 
 389                 /*
 390                  * We better not get a hit now, we do not want duplicates in
 391                  * the tree.
 392                  */
 393                 ASSERT(_lmp == NULL);
 394         }
 395 
 396         /*
 397          * Insert new node in tree.
 398          */
 399         if ((fpnp = calloc(1, sizeof (FullPathNode))) == NULL)
 400                 return (0);
 401 
 402         fpnp->fpn_node.pn_name = name;
 403         fpnp->fpn_node.pn_hash = hash;
 404         fpnp->fpn_lmp = lmp;
 405 
 406         if (aplist_append(&FPNODE(lmp), fpnp, AL_CNT_FPNODE) == NULL) {
 407                 free(fpnp);
 408                 return (0);
 409         }
 410 
 411         ASSERT(lml->lm_fpavl != NULL);
 412         avl_insert(lml->lm_fpavl, fpnp, where);
 413         return (1);
 414 }
 415 
 416 /*
 417  * Remove an object from the FullPathNode AVL tree.
 418  */
 419 void


 442 void
 443 nfavl_insert(const char *name, avl_index_t where)
 444 {
 445         PathNode        *pnp;
 446         uint_t          hash = sgs_str_hash(name);
 447 
 448         if (where == 0) {
 449                 /* LINTED */
 450                 int     in_nfavl = pnavl_recorded(&nfavl, name, hash, &where);
 451 
 452                 /*
 453                  * We better not get a hit now, we do not want duplicates in
 454                  * the tree.
 455                  */
 456                 ASSERT(in_nfavl == 0);
 457         }
 458 
 459         /*
 460          * Insert new node in tree.
 461          */
 462         if ((pnp = calloc(1, sizeof (PathNode))) != NULL) {
 463                 pnp->pn_name = name;
 464                 pnp->pn_hash = hash;
 465                 avl_insert(nfavl, pnp, where);
 466         }
 467 }
 468 
 469 /*
 470  * Insert the directory name, of a full path name, into the secure path AVL
 471  * tree.
 472  *
 473  * This tree is used to maintain a list of directories in which the dependencies
 474  * of a secure process have been found.  This list provides a fall-back in the
 475  * case that a $ORIGIN expansion is deemed insecure, when the expansion results
 476  * in a path name that has already provided dependencies.
 477  */
 478 void
 479 spavl_insert(const char *name)
 480 {
 481         char            buffer[PATH_MAX], *str;
 482         size_t          size;


 489          */
 490         if ((str = strrchr(name, '/')) == name)
 491                 size = 1;
 492         else
 493                 size = str - name;
 494 
 495         (void) strncpy(buffer, name, size);
 496         buffer[size] = '\0';
 497         hash = sgs_str_hash(buffer);
 498 
 499         /*
 500          * Determine whether this directory name is already recorded, or if
 501          * not, 'where" will provide the insertion point for the new string.
 502          */
 503         if (pnavl_recorded(&spavl, buffer, hash, &where))
 504                 return;
 505 
 506         /*
 507          * Insert new node in tree.
 508          */
 509         if ((pnp = calloc(1, sizeof (PathNode))) != NULL) {
 510                 pnp->pn_name = strdup(buffer);
 511                 pnp->pn_hash = hash;
 512                 avl_insert(spavl, pnp, where);
 513         }
 514 }
 515 
 516 /*
 517  * Inspect the generic string AVL tree for the given string.  If the string is
 518  * not present, duplicate it, and insert the string in the AVL tree.  Return the
 519  * duplicated string to the caller.
 520  *
 521  * These strings are maintained for the life of ld.so.1 and represent path
 522  * names, file names, and search paths.  All other AVL trees that maintain
 523  * FullPathNode and not-found path names use the same string pointer
 524  * established for this string.
 525  */
 526 static avl_tree_t       *stravl = NULL;
 527 static char             *strbuf = NULL;
 528 static PathNode         *pnbuf = NULL;
 529 static size_t           strsize = 0, pnsize = 0;


2871 
2872 static char     errbuf[ERRSIZE], *nextptr = errbuf, *prevptr = NULL;
2873 
2874 /*
2875  * All error messages go through eprintf().  During process initialization,
2876  * these messages are directed to the standard error, however once control has
2877  * been passed to the applications code these messages are stored in an internal
2878  * buffer for use with dlerror().  Note, fatal error conditions that may occur
2879  * while running the application will still cause a standard error message, see
2880  * rtldexit() in this file for details.
2881  * The RT_FL_APPLIC flag serves to indicate the transition between process
2882  * initialization and when the applications code is running.
2883  */
2884 void
2885 veprintf(Lm_list *lml, Error error, const char *format, va_list args)
2886 {
2887         int             overflow = 0;
2888         static int      lock = 0;
2889         Prfbuf          prf;
2890 
2891         if (lock || (nextptr > (errbuf + (ERRSIZE - 1))))
2892                 return;
2893 
2894         /*
2895          * Note: this lock is here to prevent the same thread from recursively
2896          * entering itself during a eprintf.  ie: during eprintf malloc() fails
2897          * and we try and call eprintf ... and then malloc() fails ....
2898          */
2899         lock = 1;
2900 
2901         /*
2902          * If we have completed startup initialization, all error messages
2903          * must be saved.  These are reported through dlerror().  If we're
2904          * still in the initialization stage, output the error directly and
2905          * add a newline.
2906          */
2907         prf.pr_buf = prf.pr_cur = nextptr;
2908         prf.pr_len = ERRSIZE - (nextptr - errbuf);
2909 
2910         if ((rtld_flags & RT_FL_APPLIC) == 0)
2911                 prf.pr_fd = 2;


3109                         /*
3110                          * If the error buffer has been used, write out all
3111                          * pending messages - lasterr is simply a pointer to
3112                          * the last message in this buffer.  However, if the
3113                          * buffer couldn't be created at all, lasterr points
3114                          * to a constant error message string.
3115                          */
3116                         if (*errbuf) {
3117                                 char    *errptr = errbuf;
3118                                 char    *errend = errbuf + ERRSIZE;
3119 
3120                                 while ((errptr < errend) && *errptr) {
3121                                         size_t  size = strlen(errptr);
3122                                         (void) write(2, errptr, size);
3123                                         (void) write(2, MSG_ORIG(MSG_STR_NL),
3124                                             MSG_STR_NL_SIZE);
3125                                         errptr += (size + 1);
3126                                 }
3127                         }
3128                         if (lasterr && ((lasterr < errbuf) ||
3129                             (lasterr > (errbuf + (ERRSIZE - 1))))) {
3130                                 (void) write(2, lasterr, strlen(lasterr));
3131                                 (void) write(2, MSG_ORIG(MSG_STR_NL),
3132                                     MSG_STR_NL_SIZE);
3133                         }
3134                 }
3135                 leave(lml, 0);
3136                 (void) _lwp_kill(_lwp_self(), killsig);
3137         }
3138         _exit(status);
3139 }
3140 
3141 /*
3142  * Map anonymous memory via MAP_ANON (added in Solaris 8).
3143  */
3144 void *
3145 dz_map(Lm_list *lml, caddr_t addr, size_t len, int prot, int flags)
3146 {
3147         caddr_t va;
3148 
3149         if ((va = (caddr_t)mmap(addr, len, prot,