Print this page
10140 notify_params.c is walking past end of array
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/svc/common/notify_params.c
+++ new/usr/src/cmd/svc/common/notify_params.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 24 */
25 25
26 26 #include <libintl.h>
27 27 #include <libnvpair.h>
28 28 #include <libscf.h>
29 29 #include <libscf_priv.h>
30 30 #include <libuutil.h>
31 31 #include <stdarg.h>
32 32 #include <stdio.h>
33 33 #include <string.h>
34 34
35 35 #include "notify_params.h"
36 36
37 37 static struct events {
38 38 const char *s;
39 39 int32_t c;
40 40 } smf_st_events[] = {
41 41 { "to-uninitialized", SCF_TRANS(0, SCF_STATE_UNINIT) },
42 42 { "from-uninitialized", SCF_TRANS(SCF_STATE_UNINIT, 0) },
43 43 { "uninitialized", SCF_TRANS(SCF_STATE_UNINIT, SCF_STATE_UNINIT) },
44 44 { "to-maintenance", SCF_TRANS(0, SCF_STATE_MAINT) },
45 45 { "from-maintenance", SCF_TRANS(SCF_STATE_MAINT, 0) },
46 46 { "maintenance", SCF_TRANS(SCF_STATE_MAINT, SCF_STATE_MAINT) },
47 47 { "to-offline", SCF_TRANS(0, SCF_STATE_OFFLINE) },
48 48 { "from-offline", SCF_TRANS(SCF_STATE_OFFLINE, 0) },
49 49 { "offline", SCF_TRANS(SCF_STATE_OFFLINE, SCF_STATE_OFFLINE) },
50 50 { "to-disabled", SCF_TRANS(0, SCF_STATE_DISABLED) },
51 51 { "from-disabled", SCF_TRANS(SCF_STATE_DISABLED, 0) },
52 52 { "disabled", SCF_TRANS(SCF_STATE_DISABLED, SCF_STATE_DISABLED) },
53 53 { "to-online", SCF_TRANS(0, SCF_STATE_ONLINE) },
54 54 { "from-online", SCF_TRANS(SCF_STATE_ONLINE, 0) },
55 55 { "online", SCF_TRANS(SCF_STATE_ONLINE, SCF_STATE_ONLINE) },
56 56 { "to-degraded", SCF_TRANS(0, SCF_STATE_DEGRADED) },
57 57 { "from-degraded", SCF_TRANS(SCF_STATE_DEGRADED, 0) },
58 58 { "degraded", SCF_TRANS(SCF_STATE_DEGRADED, SCF_STATE_DEGRADED) },
59 59 { "to-all", SCF_TRANS(0, SCF_STATE_ALL) },
60 60 { "from-all", SCF_TRANS(SCF_STATE_ALL, 0) },
61 61 { "all", SCF_TRANS(SCF_STATE_ALL, SCF_STATE_ALL) },
62 62 { NULL, 0 }
63 63 };
64 64
65 65 static struct fma_tags {
66 66 const char *t;
67 67 const char *s;
68 68 } fma_tags[] = {
69 69 { "problem-diagnosed", "list.suspect" },
70 70 { "problem-updated", "list.updated" },
71 71 { "problem-repaired", "list.repaired" },
72 72 { "problem-resolved", "list.resolved" },
73 73 { NULL, NULL }
74 74 };
75 75
76 76 static char *fma_classes[] = {
77 77 "list.",
78 78 "ireport.",
79 79 NULL
↓ open down ↓ |
79 lines elided |
↑ open up ↑ |
80 80 };
81 81
82 82 /*
83 83 * get_fma_tag()
84 84 * return a pointer to the fma tag at the passed index. NULL if no entry exist
85 85 * for index
86 86 */
87 87 const char *
88 88 get_fma_tag(uint32_t index)
89 89 {
90 - if (index > (sizeof (fma_tags) / sizeof (struct fma_tags)))
90 + if (index >= (sizeof (fma_tags) / sizeof (struct fma_tags)))
91 91 return (NULL);
92 92
93 93 return (fma_tags[index].t);
94 94 }
95 95
96 96 /*
97 97 * get_fma_class()
98 98 * return a pointer to the fma class at the passed index. NULL if no entry exist
99 99 * for index
100 100 */
101 101 const char *
102 102 get_fma_class(uint32_t index)
103 103 {
104 - if (index > (sizeof (fma_tags) / sizeof (struct fma_tags)))
104 + if (index >= (sizeof (fma_tags) / sizeof (struct fma_tags)))
105 105 return (NULL);
106 106
107 107 return (fma_tags[index].s);
108 108 }
109 109
110 110 /*
111 111 * is_fma_token()
112 112 * check if the parameter is an fma token by comparing with the
113 113 * fma_classes[] and the fma_tags[] arrays.
114 114 */
115 115 int
116 116 is_fma_token(const char *t)
117 117 {
118 118 int i;
119 119
120 120 for (i = 0; fma_classes[i]; ++i)
121 121 if (strncmp(t, fma_classes[i], strlen(fma_classes[i])) == 0)
122 122 return (1);
123 123
124 124 for (i = 0; fma_tags[i].t; ++i)
125 125 if (strcmp(t, fma_tags[i].t) == 0)
126 126 return (1);
127 127
128 128 return (0);
129 129 }
130 130
131 131 /*
132 132 * has_fma_tag()
133 133 * returns 1 if there is an fma tag for the passed class, 0 otherwise
134 134 */
135 135 int
136 136 has_fma_tag(const char *c)
137 137 {
138 138 int i;
139 139
140 140 for (i = 0; fma_tags[i].s; ++i)
141 141 if (strcmp(c, fma_tags[i].s) == 0)
142 142 return (1);
143 143
144 144 return (0);
145 145 }
146 146
147 147 const char *
148 148 de_tag(const char *tag)
149 149 {
150 150 int i;
151 151
152 152 for (i = 0; fma_tags[i].t; ++i)
153 153 if (strcmp(tag, fma_tags[i].t) == 0)
154 154 return (fma_tags[i].s);
155 155
156 156 return (tag);
157 157 }
158 158
159 159 const char *
160 160 re_tag(const char *fma_event)
161 161 {
162 162 int i;
163 163
164 164 for (i = 0; fma_tags[i].s; ++i)
165 165 if (strcmp(fma_event, fma_tags[i].s) == 0)
166 166 return (fma_tags[i].t);
167 167
168 168 return (fma_event);
169 169 }
170 170
171 171 int32_t
172 172 string_to_tset(const char *str)
173 173 {
174 174 int i;
175 175
176 176 for (i = 0; smf_st_events[i].s != NULL; ++i) {
177 177 if (strcmp(str, smf_st_events[i].s) == 0)
178 178 return (smf_st_events[i].c);
179 179 }
180 180
181 181 return (0);
182 182 }
183 183
184 184 const char *
185 185 tset_to_string(int32_t t)
186 186 {
187 187 int i;
188 188
189 189 for (i = 0; smf_st_events[i].s != NULL; ++i) {
190 190 if (smf_st_events[i].c == t)
191 191 return (smf_st_events[i].s);
192 192 }
193 193
194 194 return (NULL);
195 195 }
196 196
197 197 void
198 198 safe_printf(const char *fmt, ...)
199 199 {
200 200 va_list va;
201 201
202 202 va_start(va, fmt);
203 203 if (vprintf(fmt, va) < 0)
204 204 uu_die(gettext("Error writing to stdout"));
205 205 va_end(va);
206 206 }
207 207
208 208 static uint32_t
209 209 notify_params_get_version(nvlist_t *nvl)
210 210 {
211 211 uint32_t v;
212 212
213 213 if (nvl == NULL)
214 214 return (0xFFFFFFFFU);
215 215
216 216 if (nvlist_lookup_uint32(nvl, SCF_NOTIFY_NAME_VERSION, &v) != 0)
217 217 return (0xFFFFFFFFU);
218 218 else
219 219 return (v);
220 220 }
221 221
222 222 static void
223 223 nvpair_print(nvpair_t *p)
224 224 {
225 225 char **v;
226 226 uint_t n;
227 227 int i;
228 228
229 229 safe_printf(" %s:", nvpair_name(p));
230 230 (void) nvpair_value_string_array(p, &v, &n);
231 231 for (i = 0; i < n; ++i) {
232 232 safe_printf(" %s", v[i]);
233 233 }
234 234 safe_printf("\n");
235 235 }
236 236
237 237 static void
238 238 params_type_print(nvlist_t *p, const char *name, const char *fmri)
239 239 {
240 240 nvpair_t *tnvp, *nvp;
241 241 nvlist_t *nvl;
242 242 boolean_t *a;
243 243 uint_t n;
244 244 int has_output = 0;
245 245
246 246 /* for each event e print all notification parameters */
247 247 for (tnvp = nvlist_next_nvpair(p, NULL); tnvp != NULL;
248 248 tnvp = nvlist_next_nvpair(p, tnvp)) {
249 249 /* We only want the NVLIST memebers */
250 250 if (nvpair_type(tnvp) != DATA_TYPE_NVLIST)
251 251 continue;
252 252
253 253 if (nvpair_value_nvlist(tnvp, &nvl) != 0)
254 254 uu_die("nvpair_value_nvlist");
255 255
256 256 if (!has_output)
257 257 if (fmri == NULL)
258 258 safe_printf(gettext(" Event: %s\n"), name);
259 259 else
260 260 safe_printf(gettext(
261 261 " Event: %s (source: %s)\n"),
262 262 name, fmri);
263 263
264 264 has_output = 1;
265 265
266 266 safe_printf(gettext(" Notification Type: %s\n"),
267 267 nvpair_name(tnvp));
268 268
269 269 if (nvlist_lookup_boolean_array(nvl, PARAM_ACTIVE, &a, &n) != 0)
270 270 uu_warn(gettext("Missing 'active' property"));
271 271 else
272 272 safe_printf(gettext(" Active: %s\n"),
273 273 *a ? "true" : "false");
274 274
275 275 for (nvp = nvlist_next_nvpair(nvl, NULL); nvp != NULL;
276 276 nvp = nvlist_next_nvpair(nvl, nvp)) {
277 277 if (nvpair_type(nvp) != DATA_TYPE_STRING_ARRAY)
278 278 continue;
279 279 nvpair_print(nvp);
280 280 }
281 281 safe_printf("\n");
282 282 }
283 283 }
284 284
285 285 void
286 286 listnotify_print(nvlist_t *nvl, const char *event)
287 287 {
288 288 char *fmri;
289 289 nvlist_t **params;
290 290 size_t n;
291 291 int32_t tset;
292 292 int i;
293 293
294 294 /*
295 295 * Check the nvl we got is from a version we understand
296 296 */
297 297 if (nvl != NULL && notify_params_get_version(nvl) !=
298 298 SCF_NOTIFY_PARAMS_VERSION)
299 299 uu_die(gettext("libscf(3LIB) mismatch\n"));
300 300
301 301 if (nvl != NULL && nvlist_lookup_nvlist_array(nvl, SCF_NOTIFY_PARAMS,
302 302 ¶ms, &n) != 0)
303 303 /* Sanity check. If we get here nvl is bad! */
304 304 uu_die(gettext("nvlist_lookup_nvlist_array\n"));
305 305
306 306 if (event == NULL) {
307 307 /* this is an SMF state transition nvlist */
308 308 for (i = 0; i < n; ++i) {
309 309 nvlist_t *p = *(params + i);
310 310
311 311 if (nvlist_lookup_string(p,
312 312 SCF_NOTIFY_PARAMS_SOURCE_NAME, &fmri) != 0)
313 313 fmri = NULL;
314 314 if (nvlist_lookup_int32(p, SCF_NOTIFY_NAME_TSET,
315 315 &tset) != 0)
316 316 uu_die("nvlist_lookup_int32");
317 317 params_type_print(p, tset_to_string(tset), fmri);
318 318 }
319 319 } else {
320 320 /* this is FMA event nvlist */
321 321 if (nvl == NULL) { /* preferences not found */
322 322 return;
323 323 }
324 324 for (i = 0; i < n; ++i) {
325 325 nvlist_t *p = *(params + i);
326 326
327 327 if (nvlist_lookup_string(p,
328 328 SCF_NOTIFY_PARAMS_SOURCE_NAME, &fmri) != 0)
329 329 fmri = NULL;
330 330 params_type_print(p, event, fmri);
331 331 }
332 332 }
333 333 }
↓ open down ↓ |
219 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX