Print this page
Code review comments from jeffpc
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.


  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 /*
  27  * Copyright 2012 DEY Storage Systems, Inc.  All rights reserved.
  28  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  29  */
  30 
  31 #include <stdlib.h>
  32 #include <stdio.h>
  33 #include <string.h>
  34 #include <sys/types.h>
  35 #include <unistd.h>
  36 #include <sys/corectl.h>

  37 #include <msg.h>
  38 #include <_elfdump.h>
  39 #include <struct_layout.h>
  40 #include <conv.h>
  41 
  42 
  43 /*
  44  * This module contains the code that displays data from the note
  45  * sections found in Solaris core files. The format of these
  46  * note sections are described in the core(4) manpage.
  47  */
  48 
  49 
  50 
  51 
  52 /*
  53  * Much of the code in this file uses the "%*s" format to set
  54  * the left margin indentation. This macro combines the indent
  55  * integer argument and the NULL string that follows it.
  56  */


 149         i = (n >= sizeof (buf)) ? (sizeof (buf) - 4) : (n - 1);
 150         (void) memcpy(buf, str, i);
 151         s = buf + i;
 152         if (n >= sizeof (buf)) {
 153                 *s++ = '.';
 154                 *s++ = '.';
 155                 *s++ = '.';
 156         }
 157         *s = '\0';
 158         return (buf);
 159 }
 160 
 161 /*
 162  * Convenience wrappers on top of the corresponding sl_XXX() functions.
 163  */
 164 static Word
 165 extract_as_word(note_state_t *state, const sl_field_t *fdesc)
 166 {
 167         return (sl_extract_as_word(state->ns_data, state->ns_swap, fdesc));
 168 }
 169 static Word
 170 extract_as_lword(note_state_t *state, const sl_field_t *fdesc)
 171 {
 172         return (sl_extract_as_lword(state->ns_data, state->ns_swap, fdesc));
 173 }
 174 static int
 175 extract_as_sword(note_state_t *state, const sl_field_t *fdesc)
 176 {
 177         return (sl_extract_as_sword(state->ns_data, state->ns_swap, fdesc));
 178 }
 179 static const char *
 180 fmt_num(note_state_t *state, const sl_field_t *fdesc,
 181     sl_fmt_num_t fmt_type, sl_fmtbuf_t buf)
 182 {
 183         return (sl_fmt_num(state->ns_data, state->ns_swap, fdesc,
 184             fmt_type, buf));
 185 }
 186 
 187 
 188 /*
 189  * Return true of the data for the specified field is available.


 419                 fdesc1.slf_offset += 2 * fdesc1.slf_eltlen;
 420                 i += 2;
 421         }
 422 
 423         indent_exit(state);
 424 }
 425 
 426 
 427 /*
 428  * Output information from auxv_t structure.
 429  */
 430 static void
 431 dump_auxv(note_state_t *state, const char *title)
 432 {
 433         const sl_auxv_layout_t  *layout = state->ns_arch->auxv;
 434         union {
 435                 Conv_cap_val_hw1_buf_t          hw1;
 436                 Conv_cap_val_hw2_buf_t          hw2;
 437                 Conv_cnote_auxv_af_buf_t        auxv_af;
 438                 Conv_ehdr_flags_buf_t           ehdr_flags;

 439                 Conv_inv_buf_t                  inv;
 440         } conv_buf;
 441         sl_fmtbuf_t     buf;
 442         int             ndx, ndx_start;
 443         Word            sizeof_auxv;
 444 
 445         sizeof_auxv = layout->sizeof_struct.slf_eltlen;
 446 
 447         indent_enter(state, title, &layout->sizeof_struct);
 448 
 449         /*
 450          * Immediate indent_exit() restores the indent level to
 451          * that of the title. We include indentation as part of
 452          * the index string, which is right justified, and don't
 453          * want the usual indentation spacing.
 454          */
 455         indent_exit(state);
 456 
 457         ndx = 0;
 458         while (state->ns_len > sizeof_auxv) {


 810 #undef NELTS
 811 }
 812 
 813 
 814 /*
 815  * Output information from timestruc_t structure.
 816  */
 817 static void
 818 dump_timestruc(note_state_t *state, const char *title)
 819 {
 820         const sl_timestruc_layout_t *layout = state->ns_arch->timestruc;
 821 
 822         indent_enter(state, title, &layout->tv_sec);
 823 
 824         PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_TV_SEC), tv_sec,
 825             MSG_ORIG(MSG_CNOTE_T_TV_NSEC), tv_nsec);
 826 
 827         indent_exit(state);
 828 }
 829 








































 830 
 831 /*
 832  * Output information from utsname structure.
 833  */
 834 static void
 835 dump_utsname(note_state_t *state, const char *title)
 836 {
 837         const sl_utsname_layout_t       *layout = state->ns_arch->utsname;
 838 
 839         indent_enter(state, title, &layout->sysname);
 840 
 841         PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_SYSNAME), sysname);
 842         PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_NODENAME), nodename);
 843         PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_RELEASE), release);
 844         PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_VERSION), version);
 845         PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_MACHINE), machine);
 846 
 847         indent_exit(state);
 848 }
 849 


1080                 w = extract_as_word(state, &layout->pr_dmodel);
1081                 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_DMODEL),
1082                     conv_cnote_pr_dmodel(w, 0, &conv_buf.inv));
1083         }
1084 
1085         PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_TASKID), pr_taskid,
1086             MSG_ORIG(MSG_CNOTE_T_PR_PROJID), pr_projid);
1087         PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_NZOMB), pr_nzomb,
1088             MSG_ORIG(MSG_CNOTE_T_PR_ZONEID), pr_zoneid);
1089 
1090         /*
1091          * In order to line up all the values in a single column,
1092          * we would have to set vcol to a very high value, which results
1093          * in ugly looking output that runs off column 80. So, we use
1094          * two levels of vcol, one for the contents so far, and a
1095          * higher one for the pr_lwp sub-struct.
1096          */
1097         state->ns_vcol += 5;
1098         state->ns_t2col += 5;
1099         state->ns_v2col += 5;

1100         PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_LWP), pr_lwp, dump_lwpstatus);
1101         state->ns_vcol -= 5;
1102         state->ns_t2col -= 5;
1103         state->ns_v2col -= 5;
1104 
1105         indent_exit(state);
1106 }
1107 
1108 
1109 /*
1110  * Output information from prstatus_t (<sys/old_procfs.h>) structure.
1111  */
1112 static void
1113 dump_prstatus(note_state_t *state, const char *title)
1114 {
1115         const sl_prstatus_layout_t      *layout = state->ns_arch->prstatus;
1116         Word                            w, w2;
1117         int                             i;
1118         union {
1119                 Conv_inv_buf_t                  inv;


1840 
1841         case NT_ZONENAME:               /* string from getzonenamebyid(3C) */
1842                 dbg_print(0, MSG_ORIG(MSG_NOTE_DESC));
1843                 dbg_print(0, MSG_ORIG(MSG_FMT_INDENT), safe_str(desc, descsz));
1844                 return (CORENOTE_R_OK);
1845 
1846 
1847         case NT_FDINFO:
1848                 state.ns_vcol = 22;
1849                 state.ns_t2col = 41;
1850                 state.ns_v2col = 54;
1851                 dump_prfdinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_PRFDINFO_T));
1852                 return (CORENOTE_R_OK);
1853 
1854         case NT_SPYMASTER:
1855                 state.ns_vcol = 25;
1856                 state.ns_t2col = 45;
1857                 state.ns_v2col = 58;
1858                 dump_psinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_PSINFO_T));
1859                 return (CORENOTE_R_OK);







1860         }
1861 
1862         return (CORENOTE_R_BADTYPE);
1863 }


  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 /*
  27  * Copyright 2012 DEY Storage Systems, Inc.  All rights reserved.
  28  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  29  */
  30 
  31 #include <stdlib.h>
  32 #include <stdio.h>
  33 #include <string.h>
  34 #include <sys/types.h>
  35 #include <unistd.h>
  36 #include <sys/corectl.h>
  37 #include <procfs.h>
  38 #include <msg.h>
  39 #include <_elfdump.h>
  40 #include <struct_layout.h>
  41 #include <conv.h>
  42 
  43 
  44 /*
  45  * This module contains the code that displays data from the note
  46  * sections found in Solaris core files. The format of these
  47  * note sections are described in the core(4) manpage.
  48  */
  49 
  50 
  51 
  52 
  53 /*
  54  * Much of the code in this file uses the "%*s" format to set
  55  * the left margin indentation. This macro combines the indent
  56  * integer argument and the NULL string that follows it.
  57  */


 150         i = (n >= sizeof (buf)) ? (sizeof (buf) - 4) : (n - 1);
 151         (void) memcpy(buf, str, i);
 152         s = buf + i;
 153         if (n >= sizeof (buf)) {
 154                 *s++ = '.';
 155                 *s++ = '.';
 156                 *s++ = '.';
 157         }
 158         *s = '\0';
 159         return (buf);
 160 }
 161 
 162 /*
 163  * Convenience wrappers on top of the corresponding sl_XXX() functions.
 164  */
 165 static Word
 166 extract_as_word(note_state_t *state, const sl_field_t *fdesc)
 167 {
 168         return (sl_extract_as_word(state->ns_data, state->ns_swap, fdesc));
 169 }
 170 static Lword
 171 extract_as_lword(note_state_t *state, const sl_field_t *fdesc)
 172 {
 173         return (sl_extract_as_lword(state->ns_data, state->ns_swap, fdesc));
 174 }
 175 static int
 176 extract_as_sword(note_state_t *state, const sl_field_t *fdesc)
 177 {
 178         return (sl_extract_as_sword(state->ns_data, state->ns_swap, fdesc));
 179 }
 180 static const char *
 181 fmt_num(note_state_t *state, const sl_field_t *fdesc,
 182     sl_fmt_num_t fmt_type, sl_fmtbuf_t buf)
 183 {
 184         return (sl_fmt_num(state->ns_data, state->ns_swap, fdesc,
 185             fmt_type, buf));
 186 }
 187 
 188 
 189 /*
 190  * Return true of the data for the specified field is available.


 420                 fdesc1.slf_offset += 2 * fdesc1.slf_eltlen;
 421                 i += 2;
 422         }
 423 
 424         indent_exit(state);
 425 }
 426 
 427 
 428 /*
 429  * Output information from auxv_t structure.
 430  */
 431 static void
 432 dump_auxv(note_state_t *state, const char *title)
 433 {
 434         const sl_auxv_layout_t  *layout = state->ns_arch->auxv;
 435         union {
 436                 Conv_cap_val_hw1_buf_t          hw1;
 437                 Conv_cap_val_hw2_buf_t          hw2;
 438                 Conv_cnote_auxv_af_buf_t        auxv_af;
 439                 Conv_ehdr_flags_buf_t           ehdr_flags;
 440                 Conv_secflags_buf_t             secflags;
 441                 Conv_inv_buf_t                  inv;
 442         } conv_buf;
 443         sl_fmtbuf_t     buf;
 444         int             ndx, ndx_start;
 445         Word            sizeof_auxv;
 446 
 447         sizeof_auxv = layout->sizeof_struct.slf_eltlen;
 448 
 449         indent_enter(state, title, &layout->sizeof_struct);
 450 
 451         /*
 452          * Immediate indent_exit() restores the indent level to
 453          * that of the title. We include indentation as part of
 454          * the index string, which is right justified, and don't
 455          * want the usual indentation spacing.
 456          */
 457         indent_exit(state);
 458 
 459         ndx = 0;
 460         while (state->ns_len > sizeof_auxv) {


 812 #undef NELTS
 813 }
 814 
 815 
 816 /*
 817  * Output information from timestruc_t structure.
 818  */
 819 static void
 820 dump_timestruc(note_state_t *state, const char *title)
 821 {
 822         const sl_timestruc_layout_t *layout = state->ns_arch->timestruc;
 823 
 824         indent_enter(state, title, &layout->tv_sec);
 825 
 826         PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_TV_SEC), tv_sec,
 827             MSG_ORIG(MSG_CNOTE_T_TV_NSEC), tv_nsec);
 828 
 829         indent_exit(state);
 830 }
 831 
 832 /*
 833  * Output information from prsecflags_t structure.
 834  */
 835 static void
 836 dump_secflags(note_state_t *state, const char *title)
 837 {
 838         const sl_prsecflags_layout_t *layout = state->ns_arch->prsecflags;
 839         Conv_secflags_buf_t inv;
 840         Lword lw;
 841         Word w;
 842 
 843         indent_enter(state, title, &layout->pr_version);
 844 
 845         w = extract_as_word(state, &layout->pr_version);
 846 
 847         if (w != PRSECFLAGS_VERSION_1) {
 848                 PRINT_DEC(MSG_INTL(MSG_NOTE_BAD_SECFLAGS_VER), pr_version);
 849                 dump_hex_bytes(state->ns_data, state->ns_len, state->ns_indent,
 850                     4, 3);
 851         } else {
 852                 PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_VERSION), pr_version);
 853                 lw = extract_as_lword(state, &layout->pr_effective);
 854                 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_EFFECTIVE),
 855                     conv_prsecflags(lw, 0, &inv));
 856 
 857                 lw = extract_as_lword(state, &layout->pr_inherit);
 858                 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_INHERIT),
 859                     conv_prsecflags(lw, 0, &inv));
 860 
 861                 lw = extract_as_lword(state, &layout->pr_lower);
 862                 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_LOWER),
 863                     conv_prsecflags(lw, 0, &inv));
 864 
 865                 lw = extract_as_lword(state, &layout->pr_upper);
 866                 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_UPPER),
 867                     conv_prsecflags(lw, 0, &inv));
 868         }
 869 
 870         indent_exit(state);
 871 }
 872 
 873 /*
 874  * Output information from utsname structure.
 875  */
 876 static void
 877 dump_utsname(note_state_t *state, const char *title)
 878 {
 879         const sl_utsname_layout_t       *layout = state->ns_arch->utsname;
 880 
 881         indent_enter(state, title, &layout->sysname);
 882 
 883         PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_SYSNAME), sysname);
 884         PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_NODENAME), nodename);
 885         PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_RELEASE), release);
 886         PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_VERSION), version);
 887         PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_UTS_MACHINE), machine);
 888 
 889         indent_exit(state);
 890 }
 891 


1122                 w = extract_as_word(state, &layout->pr_dmodel);
1123                 print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_DMODEL),
1124                     conv_cnote_pr_dmodel(w, 0, &conv_buf.inv));
1125         }
1126 
1127         PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_TASKID), pr_taskid,
1128             MSG_ORIG(MSG_CNOTE_T_PR_PROJID), pr_projid);
1129         PRINT_DEC_2UP(MSG_ORIG(MSG_CNOTE_T_PR_NZOMB), pr_nzomb,
1130             MSG_ORIG(MSG_CNOTE_T_PR_ZONEID), pr_zoneid);
1131 
1132         /*
1133          * In order to line up all the values in a single column,
1134          * we would have to set vcol to a very high value, which results
1135          * in ugly looking output that runs off column 80. So, we use
1136          * two levels of vcol, one for the contents so far, and a
1137          * higher one for the pr_lwp sub-struct.
1138          */
1139         state->ns_vcol += 5;
1140         state->ns_t2col += 5;
1141         state->ns_v2col += 5;
1142 
1143         PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_LWP), pr_lwp, dump_lwpstatus);
1144         state->ns_vcol -= 5;
1145         state->ns_t2col -= 5;
1146         state->ns_v2col -= 5;
1147 
1148         indent_exit(state);
1149 }
1150 
1151 
1152 /*
1153  * Output information from prstatus_t (<sys/old_procfs.h>) structure.
1154  */
1155 static void
1156 dump_prstatus(note_state_t *state, const char *title)
1157 {
1158         const sl_prstatus_layout_t      *layout = state->ns_arch->prstatus;
1159         Word                            w, w2;
1160         int                             i;
1161         union {
1162                 Conv_inv_buf_t                  inv;


1883 
1884         case NT_ZONENAME:               /* string from getzonenamebyid(3C) */
1885                 dbg_print(0, MSG_ORIG(MSG_NOTE_DESC));
1886                 dbg_print(0, MSG_ORIG(MSG_FMT_INDENT), safe_str(desc, descsz));
1887                 return (CORENOTE_R_OK);
1888 
1889 
1890         case NT_FDINFO:
1891                 state.ns_vcol = 22;
1892                 state.ns_t2col = 41;
1893                 state.ns_v2col = 54;
1894                 dump_prfdinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_PRFDINFO_T));
1895                 return (CORENOTE_R_OK);
1896 
1897         case NT_SPYMASTER:
1898                 state.ns_vcol = 25;
1899                 state.ns_t2col = 45;
1900                 state.ns_v2col = 58;
1901                 dump_psinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_PSINFO_T));
1902                 return (CORENOTE_R_OK);
1903 
1904         case NT_SECFLAGS:
1905                 state.ns_vcol = 23;
1906                 state.ns_t2col = 41;
1907                 state.ns_v2col = 54;
1908                 dump_secflags(&state, MSG_ORIG(MSG_CNOTE_DESC_PRSECFLAGS_T));
1909                 return (CORENOTE_R_OK);
1910         }
1911 
1912         return (CORENOTE_R_BADTYPE);
1913 }