Print this page
6565 pargs crashes on growing env


  67 #include <sys/types.h>
  68 #include <sys/auxv.h>
  69 #include <sys/archsystm.h>
  70 #include <sys/proc.h>
  71 #include <sys/elf.h>
  72 #include <libproc.h>
  73 #include <wctype.h>
  74 #include <widec.h>
  75 #include <elfcap.h>
  76 
  77 typedef struct pargs_data {
  78         struct ps_prochandle *pd_proc;  /* target proc handle */
  79         psinfo_t *pd_psinfo;            /* target psinfo */
  80         char *pd_locale;                /* target process locale */
  81         int pd_conv_flags;              /* flags governing string conversion */
  82         iconv_t pd_iconv;               /* iconv conversion descriptor */
  83         size_t pd_argc;
  84         uintptr_t *pd_argv;
  85         char **pd_argv_strs;
  86         size_t pd_envc;

  87         uintptr_t *pd_envp;
  88         char **pd_envp_strs;
  89         size_t pd_auxc;
  90         auxv_t *pd_auxv;
  91         char **pd_auxv_strs;
  92         char *pd_execname;
  93 } pargs_data_t;
  94 
  95 #define CONV_USE_ICONV          0x01
  96 #define CONV_STRICT_ASCII       0x02
  97 
  98 static char *command;
  99 static int dmodel;
 100 
 101 #define EXTRACT_BUFSZ 128               /* extract_string() initial size */
 102 #define ENV_CHUNK 16                    /* #env ptrs to read at a time */
 103 
 104 static jmp_buf env;                     /* malloc failure handling */
 105 
 106 static void *


 617                 datap->pd_argv = NULL;
 618                 return;
 619         }
 620 
 621         datap->pd_argv_strs = safe_zalloc(argc * sizeof (char *));
 622         for (i = 0; i < argc; i++) {
 623                 if (datap->pd_argv[i] == 0)
 624                         continue;
 625                 datap->pd_argv_strs[i] = extract_string(datap,
 626                     datap->pd_argv[i]);
 627         }
 628 }
 629 
 630 /*ARGSUSED*/
 631 static int
 632 build_env(void *data, struct ps_prochandle *pr, uintptr_t addr, const char *str)
 633 {
 634         pargs_data_t *datap = data;
 635 
 636         if (datap->pd_envp != NULL) {




 637                 datap->pd_envp[datap->pd_envc] = addr;
 638                 if (str == NULL)
 639                         datap->pd_envp_strs[datap->pd_envc] = NULL;
 640                 else
 641                         datap->pd_envp_strs[datap->pd_envc] = strdup(str);
 642         }
 643 
 644         datap->pd_envc++;
 645 
 646         return (0);
 647 }
 648 
 649 static void
 650 get_env(pargs_data_t *datap)
 651 {
 652         struct ps_prochandle *pr = datap->pd_proc;
 653 
 654         datap->pd_envc = 0;
 655         (void) Penv_iter(pr, build_env, datap);

 656 
 657         datap->pd_envp = safe_zalloc(sizeof (uintptr_t) * datap->pd_envc);
 658         datap->pd_envp_strs = safe_zalloc(sizeof (char *) * datap->pd_envc);
 659 
 660         datap->pd_envc = 0;
 661         (void) Penv_iter(pr, build_env, datap);
 662 }
 663 
 664 /*
 665  * The following at_* routines are used to decode data from the aux vector.
 666  */
 667 
 668 /*ARGSUSED*/
 669 static void
 670 at_null(long val, char *instr, size_t n, char *str)
 671 {
 672         str[0] = '\0';
 673 }
 674 
 675 /*ARGSUSED*/




  67 #include <sys/types.h>
  68 #include <sys/auxv.h>
  69 #include <sys/archsystm.h>
  70 #include <sys/proc.h>
  71 #include <sys/elf.h>
  72 #include <libproc.h>
  73 #include <wctype.h>
  74 #include <widec.h>
  75 #include <elfcap.h>
  76 
  77 typedef struct pargs_data {
  78         struct ps_prochandle *pd_proc;  /* target proc handle */
  79         psinfo_t *pd_psinfo;            /* target psinfo */
  80         char *pd_locale;                /* target process locale */
  81         int pd_conv_flags;              /* flags governing string conversion */
  82         iconv_t pd_iconv;               /* iconv conversion descriptor */
  83         size_t pd_argc;
  84         uintptr_t *pd_argv;
  85         char **pd_argv_strs;
  86         size_t pd_envc;
  87         size_t pd_envc_curr;
  88         uintptr_t *pd_envp;
  89         char **pd_envp_strs;
  90         size_t pd_auxc;
  91         auxv_t *pd_auxv;
  92         char **pd_auxv_strs;
  93         char *pd_execname;
  94 } pargs_data_t;
  95 
  96 #define CONV_USE_ICONV          0x01
  97 #define CONV_STRICT_ASCII       0x02
  98 
  99 static char *command;
 100 static int dmodel;
 101 
 102 #define EXTRACT_BUFSZ 128               /* extract_string() initial size */
 103 #define ENV_CHUNK 16                    /* #env ptrs to read at a time */
 104 
 105 static jmp_buf env;                     /* malloc failure handling */
 106 
 107 static void *


 618                 datap->pd_argv = NULL;
 619                 return;
 620         }
 621 
 622         datap->pd_argv_strs = safe_zalloc(argc * sizeof (char *));
 623         for (i = 0; i < argc; i++) {
 624                 if (datap->pd_argv[i] == 0)
 625                         continue;
 626                 datap->pd_argv_strs[i] = extract_string(datap,
 627                     datap->pd_argv[i]);
 628         }
 629 }
 630 
 631 /*ARGSUSED*/
 632 static int
 633 build_env(void *data, struct ps_prochandle *pr, uintptr_t addr, const char *str)
 634 {
 635         pargs_data_t *datap = data;
 636 
 637         if (datap->pd_envp != NULL) {
 638                 /* env has more items than last time, skip the newer ones */
 639                 if (datap->pd_envc > datap->pd_envc_curr)
 640                         return (0);
 641 
 642                 datap->pd_envp[datap->pd_envc] = addr;
 643                 if (str == NULL)
 644                         datap->pd_envp_strs[datap->pd_envc] = NULL;
 645                 else
 646                         datap->pd_envp_strs[datap->pd_envc] = strdup(str);
 647         }
 648 
 649         datap->pd_envc++;
 650 
 651         return (0);
 652 }
 653 
 654 static void
 655 get_env(pargs_data_t *datap)
 656 {
 657         struct ps_prochandle *pr = datap->pd_proc;
 658 
 659         datap->pd_envc = 0;
 660         (void) Penv_iter(pr, build_env, datap);
 661         datap->pd_envc_curr = datap->pd_envc;
 662 
 663         datap->pd_envp = safe_zalloc(sizeof (uintptr_t) * datap->pd_envc);
 664         datap->pd_envp_strs = safe_zalloc(sizeof (char *) * datap->pd_envc);
 665 
 666         datap->pd_envc = 0;
 667         (void) Penv_iter(pr, build_env, datap);
 668 }
 669 
 670 /*
 671  * The following at_* routines are used to decode data from the aux vector.
 672  */
 673 
 674 /*ARGSUSED*/
 675 static void
 676 at_null(long val, char *instr, size_t n, char *str)
 677 {
 678         str[0] = '\0';
 679 }
 680 
 681 /*ARGSUSED*/