Print this page
7029 want per-process exploit mitigation features (secflags)
7030 want basic address space layout randomization (aslr)
7031 noexec_user_stack should be a secflag
7032 want a means to forbid mappings around NULL.


 142         if (core->core_cred != NULL) {
 143                 /*
 144                  * Avoid returning more supplementary group data than the
 145                  * caller has allocated in their buffer.  We expect them to
 146                  * check pr_ngroups afterward and potentially call us again.
 147                  */
 148                 ngroups = MIN(ngroups, core->core_cred->pr_ngroups);
 149 
 150                 (void) memcpy(pcrp, core->core_cred,
 151                     sizeof (prcred_t) + (ngroups - 1) * sizeof (gid_t));
 152 
 153                 return (0);
 154         }
 155 
 156         errno = ENODATA;
 157         return (-1);
 158 }
 159 
 160 /*ARGSUSED*/
 161 static int



















 162 Ppriv_core(struct ps_prochandle *P, prpriv_t **pprv, void *data)
 163 {
 164         core_info_t *core = data;
 165 
 166         if (core->core_priv == NULL) {
 167                 errno = ENODATA;
 168                 return (-1);
 169         }
 170 
 171         *pprv = malloc(core->core_priv_size);
 172         if (*pprv == NULL) {
 173                 return (-1);
 174         }
 175 
 176         (void) memcpy(*pprv, core->core_priv, core->core_priv_size);
 177         return (0);
 178 }
 179 
 180 /*ARGSUSED*/
 181 static const psinfo_t *


 205                         if (lwp->lwp_asrs != NULL)
 206                                 free(lwp->lwp_asrs);
 207 #endif
 208                         free(lwp);
 209                 }
 210 
 211                 if (core->core_platform != NULL)
 212                         free(core->core_platform);
 213                 if (core->core_uts != NULL)
 214                         free(core->core_uts);
 215                 if (core->core_cred != NULL)
 216                         free(core->core_cred);
 217                 if (core->core_priv != NULL)
 218                         free(core->core_priv);
 219                 if (core->core_privinfo != NULL)
 220                         __priv_free_info(core->core_privinfo);
 221                 if (core->core_ppii != NULL)
 222                         free(core->core_ppii);
 223                 if (core->core_zonename != NULL)
 224                         free(core->core_zonename);


 225 #ifdef __x86
 226                 if (core->core_ldt != NULL)
 227                         free(core->core_ldt);
 228 #endif
 229 
 230                 free(core);
 231         }
 232 }
 233 
 234 /*ARGSUSED*/
 235 static char *
 236 Pplatform_core(struct ps_prochandle *P, char *s, size_t n, void *data)
 237 {
 238         core_info_t *core = data;
 239 
 240         if (core->core_platform == NULL) {
 241                 errno = ENODATA;
 242                 return (NULL);
 243         }
 244         (void) strncpy(s, core->core_platform, n - 1);


 291                     nldt * sizeof (struct ssd));
 292 
 293                 return (nldt);
 294         }
 295 
 296         errno = ENODATA;
 297         return (-1);
 298 }
 299 #endif
 300 
 301 static const ps_ops_t P_core_ops = {
 302         .pop_pread      = Pread_core,
 303         .pop_pwrite     = Pwrite_core,
 304         .pop_cred       = Pcred_core,
 305         .pop_priv       = Ppriv_core,
 306         .pop_psinfo     = Ppsinfo_core,
 307         .pop_fini       = Pfini_core,
 308         .pop_platform   = Pplatform_core,
 309         .pop_uname      = Puname_core,
 310         .pop_zonename   = Pzonename_core,

 311 #ifdef __x86
 312         .pop_ldt        = Pldt_core
 313 #endif
 314 };
 315 
 316 /*
 317  * Return the lwp_info_t for the given lwpid.  If no such lwpid has been
 318  * encountered yet, allocate a new structure and return a pointer to it.
 319  * Create a list of lwp_info_t structures sorted in decreasing lwp_id order.
 320  */
 321 static lwp_info_t *
 322 lwpid2info(struct ps_prochandle *P, lwpid_t id)
 323 {
 324         core_info_t *core = P->data;
 325         lwp_info_t *lwp = list_next(&core->core_lwp_head);
 326         lwp_info_t *next;
 327         uint_t i;
 328 
 329         for (i = 0; i < core->core_nlwp; i++, lwp = list_next(lwp)) {
 330                 if (lwp->lwp_id == id) {


 729         core_info_t *core = P->data;
 730         char *plat;
 731 
 732         if (core->core_platform != NULL)
 733                 return (0);     /* Already seen */
 734 
 735         if (nbytes != 0 && ((plat = malloc(nbytes + 1)) != NULL)) {
 736                 if (read(P->asfd, plat, nbytes) != nbytes) {
 737                         dprintf("Pgrab_core: failed to read NT_PLATFORM\n");
 738                         free(plat);
 739                         return (-1);
 740                 }
 741                 plat[nbytes - 1] = '\0';
 742                 core->core_platform = plat;
 743         }
 744 
 745         return (0);
 746 }
 747 
 748 static int




























 749 note_utsname(struct ps_prochandle *P, size_t nbytes)
 750 {
 751         core_info_t *core = P->data;
 752         size_t ubytes = sizeof (struct utsname);
 753         struct utsname *utsp;
 754 
 755         if (core->core_uts != NULL || nbytes < ubytes)
 756                 return (0);     /* Already seen or bad size */
 757 
 758         if ((utsp = malloc(ubytes)) == NULL)
 759                 return (-1);
 760 
 761         if (read(P->asfd, utsp, ubytes) != ubytes) {
 762                 dprintf("Pgrab_core: failed to read NT_UTSNAME\n");
 763                 free(utsp);
 764                 return (-1);
 765         }
 766 
 767         if (_libproc_debug) {
 768                 dprintf("uts.sysname = \"%s\"\n", utsp->sysname);


1163 #endif
1164 #ifdef __x86
1165         note_ldt,               /*  9   NT_LDT                  */
1166 #else
1167         note_notsup,            /*  9   NT_LDT                  */
1168 #endif
1169         note_pstatus,           /* 10   NT_PSTATUS              */
1170         note_notsup,            /* 11   unassigned              */
1171         note_notsup,            /* 12   unassigned              */
1172         note_psinfo,            /* 13   NT_PSINFO               */
1173         note_cred,              /* 14   NT_PRCRED               */
1174         note_utsname,           /* 15   NT_UTSNAME              */
1175         note_lwpstatus,         /* 16   NT_LWPSTATUS            */
1176         note_lwpsinfo,          /* 17   NT_LWPSINFO             */
1177         note_priv,              /* 18   NT_PRPRIV               */
1178         note_priv_info,         /* 19   NT_PRPRIVINFO           */
1179         note_content,           /* 20   NT_CONTENT              */
1180         note_zonename,          /* 21   NT_ZONENAME             */
1181         note_fdinfo,            /* 22   NT_FDINFO               */
1182         note_spymaster,         /* 23   NT_SPYMASTER            */

1183 };
1184 
1185 static void
1186 core_report_mapping(struct ps_prochandle *P, GElf_Phdr *php)
1187 {
1188         prkillinfo_t killinfo;
1189         siginfo_t *si = &killinfo.prk_info;
1190         char signame[SIG2STR_MAX], sig[64], info[64];
1191         void *addr = (void *)(uintptr_t)php->p_vaddr;
1192 
1193         const char *errfmt = "core file data for mapping at %p not saved: %s\n";
1194         const char *incfmt = "core file incomplete due to %s%s\n";
1195         const char *msgfmt = "mappings at and above %p are missing\n";
1196 
1197         if (!(php->p_flags & PF_SUNW_KILLED)) {
1198                 int err = 0;
1199 
1200                 (void) pread64(P->asfd, &err,
1201                     sizeof (err), (off64_t)php->p_offset);
1202 




 142         if (core->core_cred != NULL) {
 143                 /*
 144                  * Avoid returning more supplementary group data than the
 145                  * caller has allocated in their buffer.  We expect them to
 146                  * check pr_ngroups afterward and potentially call us again.
 147                  */
 148                 ngroups = MIN(ngroups, core->core_cred->pr_ngroups);
 149 
 150                 (void) memcpy(pcrp, core->core_cred,
 151                     sizeof (prcred_t) + (ngroups - 1) * sizeof (gid_t));
 152 
 153                 return (0);
 154         }
 155 
 156         errno = ENODATA;
 157         return (-1);
 158 }
 159 
 160 /*ARGSUSED*/
 161 static int
 162 Psecflags_core(struct ps_prochandle *P, prsecflags_t **psf, void *data)
 163 {
 164         core_info_t *core = data;
 165 
 166         if (core->core_secflags == NULL) {
 167                 errno = ENODATA;
 168                 return (-1);
 169         }
 170 
 171         if ((*psf = calloc(1, sizeof (prsecflags_t))) == NULL)
 172                 return (-1);
 173 
 174         (void) memcpy(*psf, core->core_secflags, sizeof (prsecflags_t));
 175 
 176         return (0);
 177 }
 178 
 179 /*ARGSUSED*/
 180 static int
 181 Ppriv_core(struct ps_prochandle *P, prpriv_t **pprv, void *data)
 182 {
 183         core_info_t *core = data;
 184 
 185         if (core->core_priv == NULL) {
 186                 errno = ENODATA;
 187                 return (-1);
 188         }
 189 
 190         *pprv = malloc(core->core_priv_size);
 191         if (*pprv == NULL) {
 192                 return (-1);
 193         }
 194 
 195         (void) memcpy(*pprv, core->core_priv, core->core_priv_size);
 196         return (0);
 197 }
 198 
 199 /*ARGSUSED*/
 200 static const psinfo_t *


 224                         if (lwp->lwp_asrs != NULL)
 225                                 free(lwp->lwp_asrs);
 226 #endif
 227                         free(lwp);
 228                 }
 229 
 230                 if (core->core_platform != NULL)
 231                         free(core->core_platform);
 232                 if (core->core_uts != NULL)
 233                         free(core->core_uts);
 234                 if (core->core_cred != NULL)
 235                         free(core->core_cred);
 236                 if (core->core_priv != NULL)
 237                         free(core->core_priv);
 238                 if (core->core_privinfo != NULL)
 239                         __priv_free_info(core->core_privinfo);
 240                 if (core->core_ppii != NULL)
 241                         free(core->core_ppii);
 242                 if (core->core_zonename != NULL)
 243                         free(core->core_zonename);
 244                 if (core->core_secflags != NULL)
 245                         free(core->core_secflags);
 246 #ifdef __x86
 247                 if (core->core_ldt != NULL)
 248                         free(core->core_ldt);
 249 #endif
 250 
 251                 free(core);
 252         }
 253 }
 254 
 255 /*ARGSUSED*/
 256 static char *
 257 Pplatform_core(struct ps_prochandle *P, char *s, size_t n, void *data)
 258 {
 259         core_info_t *core = data;
 260 
 261         if (core->core_platform == NULL) {
 262                 errno = ENODATA;
 263                 return (NULL);
 264         }
 265         (void) strncpy(s, core->core_platform, n - 1);


 312                     nldt * sizeof (struct ssd));
 313 
 314                 return (nldt);
 315         }
 316 
 317         errno = ENODATA;
 318         return (-1);
 319 }
 320 #endif
 321 
 322 static const ps_ops_t P_core_ops = {
 323         .pop_pread      = Pread_core,
 324         .pop_pwrite     = Pwrite_core,
 325         .pop_cred       = Pcred_core,
 326         .pop_priv       = Ppriv_core,
 327         .pop_psinfo     = Ppsinfo_core,
 328         .pop_fini       = Pfini_core,
 329         .pop_platform   = Pplatform_core,
 330         .pop_uname      = Puname_core,
 331         .pop_zonename   = Pzonename_core,
 332         .pop_secflags   = Psecflags_core,
 333 #ifdef __x86
 334         .pop_ldt        = Pldt_core
 335 #endif
 336 };
 337 
 338 /*
 339  * Return the lwp_info_t for the given lwpid.  If no such lwpid has been
 340  * encountered yet, allocate a new structure and return a pointer to it.
 341  * Create a list of lwp_info_t structures sorted in decreasing lwp_id order.
 342  */
 343 static lwp_info_t *
 344 lwpid2info(struct ps_prochandle *P, lwpid_t id)
 345 {
 346         core_info_t *core = P->data;
 347         lwp_info_t *lwp = list_next(&core->core_lwp_head);
 348         lwp_info_t *next;
 349         uint_t i;
 350 
 351         for (i = 0; i < core->core_nlwp; i++, lwp = list_next(lwp)) {
 352                 if (lwp->lwp_id == id) {


 751         core_info_t *core = P->data;
 752         char *plat;
 753 
 754         if (core->core_platform != NULL)
 755                 return (0);     /* Already seen */
 756 
 757         if (nbytes != 0 && ((plat = malloc(nbytes + 1)) != NULL)) {
 758                 if (read(P->asfd, plat, nbytes) != nbytes) {
 759                         dprintf("Pgrab_core: failed to read NT_PLATFORM\n");
 760                         free(plat);
 761                         return (-1);
 762                 }
 763                 plat[nbytes - 1] = '\0';
 764                 core->core_platform = plat;
 765         }
 766 
 767         return (0);
 768 }
 769 
 770 static int
 771 note_secflags(struct ps_prochandle *P, size_t nbytes)
 772 {
 773         core_info_t *core = P->data;
 774         prsecflags_t *psf;
 775 
 776         if (core->core_secflags != NULL)
 777                 return (0);     /* Already seen */
 778 
 779         if (sizeof (*psf) != nbytes) {
 780                 dprintf("Pgrab_core: NT_SECFLAGS changed size."
 781                     "  Need to handle a version change?\n");
 782                 return (-1);
 783         }
 784 
 785         if (nbytes != 0 && ((psf = malloc(nbytes)) != NULL)) {
 786                 if (read(P->asfd, psf, nbytes) != nbytes) {
 787                         dprintf("Pgrab_core: failed to read NT_SECFLAGS\n");
 788                         free(psf);
 789                         return (-1);
 790                 }
 791 
 792                 core->core_secflags = psf;
 793         }
 794 
 795         return (0);
 796 }
 797 
 798 static int
 799 note_utsname(struct ps_prochandle *P, size_t nbytes)
 800 {
 801         core_info_t *core = P->data;
 802         size_t ubytes = sizeof (struct utsname);
 803         struct utsname *utsp;
 804 
 805         if (core->core_uts != NULL || nbytes < ubytes)
 806                 return (0);     /* Already seen or bad size */
 807 
 808         if ((utsp = malloc(ubytes)) == NULL)
 809                 return (-1);
 810 
 811         if (read(P->asfd, utsp, ubytes) != ubytes) {
 812                 dprintf("Pgrab_core: failed to read NT_UTSNAME\n");
 813                 free(utsp);
 814                 return (-1);
 815         }
 816 
 817         if (_libproc_debug) {
 818                 dprintf("uts.sysname = \"%s\"\n", utsp->sysname);


1213 #endif
1214 #ifdef __x86
1215         note_ldt,               /*  9   NT_LDT                  */
1216 #else
1217         note_notsup,            /*  9   NT_LDT                  */
1218 #endif
1219         note_pstatus,           /* 10   NT_PSTATUS              */
1220         note_notsup,            /* 11   unassigned              */
1221         note_notsup,            /* 12   unassigned              */
1222         note_psinfo,            /* 13   NT_PSINFO               */
1223         note_cred,              /* 14   NT_PRCRED               */
1224         note_utsname,           /* 15   NT_UTSNAME              */
1225         note_lwpstatus,         /* 16   NT_LWPSTATUS            */
1226         note_lwpsinfo,          /* 17   NT_LWPSINFO             */
1227         note_priv,              /* 18   NT_PRPRIV               */
1228         note_priv_info,         /* 19   NT_PRPRIVINFO           */
1229         note_content,           /* 20   NT_CONTENT              */
1230         note_zonename,          /* 21   NT_ZONENAME             */
1231         note_fdinfo,            /* 22   NT_FDINFO               */
1232         note_spymaster,         /* 23   NT_SPYMASTER            */
1233         note_secflags,          /* 24   NT_SECFLAGS             */
1234 };
1235 
1236 static void
1237 core_report_mapping(struct ps_prochandle *P, GElf_Phdr *php)
1238 {
1239         prkillinfo_t killinfo;
1240         siginfo_t *si = &killinfo.prk_info;
1241         char signame[SIG2STR_MAX], sig[64], info[64];
1242         void *addr = (void *)(uintptr_t)php->p_vaddr;
1243 
1244         const char *errfmt = "core file data for mapping at %p not saved: %s\n";
1245         const char *incfmt = "core file incomplete due to %s%s\n";
1246         const char *msgfmt = "mappings at and above %p are missing\n";
1247 
1248         if (!(php->p_flags & PF_SUNW_KILLED)) {
1249                 int err = 0;
1250 
1251                 (void) pread64(P->asfd, &err,
1252                     sizeof (err), (off64_t)php->p_offset);
1253