Print this page
10111 dat_dictionary_create() use after free
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/udapl/libdat/common/dat_dictionary.c
+++ new/usr/src/lib/udapl/libdat/common/dat_dictionary.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, Version 1.0 only
6 6 * (the "License"). You may not use this file except in compliance
7 7 * with the License.
8 8 *
9 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 10 * or http://www.opensolaris.org/os/licensing.
11 11 * See the License for the specific language governing permissions
12 12 * and limitations under the License.
13 13 *
14 14 * When distributing Covered Code, include this CDDL HEADER in each
15 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 16 * If applicable, add the following below this CDDL HEADER, with the
17 17 * fields enclosed by brackets "[]" replaced with your own identifying
18 18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 19 *
20 20 * CDDL HEADER END
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
21 21 */
22 22 /*
23 23 * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
24 24 */
25 25
26 26 /*
27 27 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
28 28 * Use is subject to license terms.
29 29 */
30 30
31 -#pragma ident "%Z%%M% %I% %E% SMI"
31 +/*
32 + * Copyright (c) 2018, Joyent, Inc.
33 + */
32 34
33 35 /*
34 36 *
35 37 * MODULE: dat_dictionary.c
36 38 *
37 39 * PURPOSE: dictionary data structure
38 40 *
39 41 * $Id: dat_dictionary.c,v 1.11 2003/08/05 19:01:48 jlentini Exp $
40 42 */
41 43
42 44
43 45 #include "dat_dictionary.h"
44 46
45 47
46 48 /*
47 49 *
48 50 * Structures
49 51 *
50 52 */
51 53
52 54 typedef struct DAT_DICTIONARY_NODE
53 55 {
54 56 DAT_PROVIDER_INFO key;
55 57 DAT_DICTIONARY_DATA data;
56 58 struct DAT_DICTIONARY_NODE *prev;
57 59 struct DAT_DICTIONARY_NODE *next;
58 60 } DAT_DICTIONARY_NODE;
59 61
60 62
61 63 struct DAT_DICTIONARY
62 64 {
63 65 DAT_DICTIONARY_NODE *head;
64 66 DAT_DICTIONARY_NODE *tail;
65 67 DAT_COUNT size;
66 68 };
67 69
68 70 /*
69 71 *
70 72 * Function Declarations
71 73 *
72 74 */
73 75
74 76 static DAT_RETURN
75 77 dat_dictionary_key_dup(
76 78 const DAT_PROVIDER_INFO *old_key,
77 79 DAT_PROVIDER_INFO *new_key);
78 80
79 81 static DAT_BOOLEAN
80 82 dat_dictionary_key_is_equal(
81 83 const DAT_PROVIDER_INFO *key_a,
82 84 const DAT_PROVIDER_INFO *key_b);
83 85
84 86
85 87 /*
86 88 *
87 89 * External Functions
88 90 *
89 91 */
90 92
91 93
92 94 /*
93 95 * Function: dat_dictionary_create
94 96 */
95 97
96 98 DAT_RETURN
97 99 dat_dictionary_create(
98 100 OUT DAT_DICTIONARY **pp_dictionary)
99 101 {
100 102 DAT_DICTIONARY *p_dictionary;
101 103 DAT_RETURN status;
102 104
103 105 dat_os_assert(NULL != pp_dictionary);
104 106
105 107 status = DAT_SUCCESS;
106 108
107 109 /* create the dictionary */
108 110 p_dictionary = dat_os_alloc(sizeof (DAT_DICTIONARY));
109 111 if (NULL == p_dictionary) {
110 112 status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
111 113 DAT_RESOURCE_MEMORY);
112 114 goto bail;
113 115 }
114 116
115 117 (void) dat_os_memset(p_dictionary, '\0', sizeof (DAT_DICTIONARY));
116 118
117 119 /* create the head node */
118 120 p_dictionary->head = dat_os_alloc(sizeof (DAT_DICTIONARY_NODE));
119 121 if (NULL == p_dictionary->head) {
120 122 status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
121 123 DAT_RESOURCE_MEMORY);
122 124 goto bail;
123 125 }
124 126
125 127 (void) dat_os_memset(p_dictionary->head, '\0',
126 128 sizeof (DAT_DICTIONARY_NODE));
127 129
128 130 /* create the tail node */
129 131 p_dictionary->tail = dat_os_alloc(sizeof (DAT_DICTIONARY_NODE));
130 132 if (NULL == p_dictionary->tail) {
131 133 status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
132 134 DAT_RESOURCE_MEMORY);
133 135 goto bail;
134 136 }
135 137
136 138 (void) dat_os_memset(p_dictionary->tail, '\0',
↓ open down ↓ |
95 lines elided |
↑ open up ↑ |
137 139 sizeof (DAT_DICTIONARY_NODE));
138 140
139 141 p_dictionary->head->next = p_dictionary->tail;
140 142 p_dictionary->tail->prev = p_dictionary->head;
141 143
142 144 *pp_dictionary = p_dictionary;
143 145
144 146 bail:
145 147 if (DAT_SUCCESS != status) {
146 148 if (NULL != p_dictionary) {
147 - dat_os_free(p_dictionary, sizeof (DAT_DICTIONARY));
148 -
149 149 if (NULL != p_dictionary->head) {
150 150 dat_os_free(p_dictionary->head,
151 151 sizeof (DAT_DICTIONARY_NODE));
152 152 }
153 153
154 154 if (NULL != p_dictionary->tail) {
155 155 dat_os_free(p_dictionary->tail,
156 156 sizeof (DAT_DICTIONARY_NODE));
157 157 }
158 +
159 + dat_os_free(p_dictionary, sizeof (DAT_DICTIONARY));
158 160 }
161 +
159 162 }
160 163
161 164 return (status);
162 165 }
163 166
164 167
165 168 /*
166 169 * Function: dat_dictionary_destroy
167 170 */
168 171
169 172 DAT_RETURN
170 173 dat_dictionary_destroy(
171 174 IN DAT_DICTIONARY *p_dictionary)
172 175 {
173 176 DAT_DICTIONARY_NODE *cur_node;
174 177
175 178 dat_os_assert(NULL != p_dictionary);
176 179
177 180 while (NULL != p_dictionary->head) {
178 181 cur_node = p_dictionary->head;
179 182 p_dictionary->head = cur_node->next;
180 183
181 184 dat_os_free(cur_node, sizeof (DAT_DICTIONARY_NODE));
182 185 }
183 186
184 187 dat_os_free(p_dictionary, sizeof (DAT_DICTIONARY));
185 188
186 189 return (DAT_SUCCESS);
187 190 }
188 191
189 192
190 193 /*
191 194 * Function: dat_dictionary_size
192 195 */
193 196
194 197 DAT_RETURN
195 198 dat_dictionary_size(
196 199 IN DAT_DICTIONARY *p_dictionary,
197 200 OUT DAT_COUNT *p_size)
198 201 {
199 202 dat_os_assert(NULL != p_dictionary);
200 203 dat_os_assert(NULL != p_size);
201 204
202 205 *p_size = p_dictionary->size;
203 206
204 207 return (DAT_SUCCESS);
205 208 }
206 209
207 210
208 211 /*
209 212 * Function: dat_dictionary_entry_create
210 213 */
211 214
212 215 DAT_RETURN
213 216 dat_dictionary_entry_create(
214 217 OUT DAT_DICTIONARY_ENTRY *p_entry)
215 218 {
216 219 DAT_DICTIONARY_NODE *node;
217 220 DAT_RETURN dat_status;
218 221
219 222 dat_os_assert(NULL != p_entry);
220 223
221 224 dat_status = DAT_SUCCESS;
222 225
223 226 node = dat_os_alloc(sizeof (DAT_DICTIONARY_NODE));
224 227 if (NULL == node) {
225 228 dat_status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
226 229 DAT_RESOURCE_MEMORY);
227 230 goto bail;
228 231 }
229 232
230 233 *p_entry = node;
231 234
232 235 bail:
233 236 return (dat_status);
234 237 }
235 238
236 239
237 240 /*
238 241 * Function: dat_dictionary_entry_destroy
239 242 */
240 243
241 244 DAT_RETURN
242 245 dat_dictionary_entry_destroy(
243 246 OUT DAT_DICTIONARY_ENTRY entry)
244 247 {
245 248 dat_os_free(entry, sizeof (DAT_DICTIONARY_NODE));
246 249 return (DAT_SUCCESS);
247 250 }
248 251
249 252
250 253 /*
251 254 * Function: dat_dictionary_insert
252 255 */
253 256
254 257 DAT_RETURN
255 258 dat_dictionary_insert(
256 259 IN DAT_DICTIONARY *p_dictionary,
257 260 IN DAT_DICTIONARY_ENTRY entry,
258 261 IN const DAT_PROVIDER_INFO *key,
259 262 IN DAT_DICTIONARY_DATA data)
260 263 {
261 264 DAT_RETURN dat_status;
262 265 DAT_DICTIONARY_NODE *cur_node, *prev_node, *next_node;
263 266
264 267 dat_os_assert(NULL != p_dictionary);
265 268 dat_os_assert(NULL != entry);
266 269
267 270 cur_node = entry;
268 271
269 272 if (DAT_SUCCESS == dat_dictionary_search(p_dictionary, key, NULL)) {
270 273 dat_status = DAT_ERROR(DAT_PROVIDER_ALREADY_REGISTERED, 0);
271 274 goto bail;
272 275 }
273 276
274 277 dat_status = dat_dictionary_key_dup(key, &cur_node->key);
275 278 if (DAT_SUCCESS != dat_status) {
276 279 goto bail;
277 280 }
278 281
279 282 /* insert node at end of list to preserve registration order */
280 283 prev_node = p_dictionary->tail->prev;
281 284 next_node = p_dictionary->tail;
282 285
283 286 cur_node->data = data;
284 287 cur_node->next = next_node;
285 288 cur_node->prev = prev_node;
286 289
287 290 prev_node->next = cur_node;
288 291 next_node->prev = cur_node;
289 292
290 293 p_dictionary->size++;
291 294
292 295 bail:
293 296 return (dat_status);
294 297 }
295 298
296 299
297 300 /*
298 301 * Function: dat_dictionary_search
299 302 */
300 303
301 304 DAT_RETURN
302 305 dat_dictionary_search(
303 306 IN DAT_DICTIONARY *p_dictionary,
304 307 IN const DAT_PROVIDER_INFO *key,
305 308 OUT DAT_DICTIONARY_DATA *p_data)
306 309 {
307 310 DAT_DICTIONARY_NODE *cur_node;
308 311 DAT_RETURN status;
309 312
310 313 dat_os_assert(NULL != p_dictionary);
311 314
312 315 status = DAT_ERROR(DAT_NAME_NOT_FOUND, 0);
313 316
314 317 for (cur_node = p_dictionary->head->next;
315 318 p_dictionary->tail != cur_node;
316 319 cur_node = cur_node->next) {
317 320 if (DAT_TRUE == dat_dictionary_key_is_equal(&cur_node->key,
318 321 key)) {
319 322 if (NULL != p_data) {
320 323 *p_data = cur_node->data;
321 324 }
322 325
323 326 status = DAT_SUCCESS;
324 327 goto bail;
325 328 }
326 329 }
327 330
328 331 bail:
329 332 return (status);
330 333 }
331 334
332 335
333 336 /*
334 337 * Function: dat_dictionary_enumerate
335 338 */
336 339
337 340 DAT_RETURN
338 341 dat_dictionary_enumerate(
339 342 IN DAT_DICTIONARY *p_dictionary,
340 343 IN DAT_DICTIONARY_DATA array[],
341 344 IN DAT_COUNT array_size)
342 345 {
343 346 DAT_DICTIONARY_NODE *cur_node;
344 347 DAT_COUNT i;
345 348 DAT_RETURN status;
346 349
347 350 dat_os_assert(NULL != p_dictionary);
348 351 dat_os_assert(NULL != array);
349 352
350 353 status = DAT_SUCCESS;
351 354
352 355 if (array_size < p_dictionary->size) {
353 356 status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, 0);
354 357 goto bail;
355 358 }
356 359
357 360 for (cur_node = p_dictionary->head->next, i = 0;
358 361 p_dictionary->tail != cur_node;
359 362 cur_node = cur_node->next, i++) {
360 363 array[i] = cur_node->data;
361 364 }
362 365
363 366 bail:
364 367 return (status);
365 368 }
366 369
367 370
368 371 /*
369 372 * Function: dat_dictionary_remove
370 373 */
371 374
372 375 DAT_RETURN
373 376 dat_dictionary_remove(
374 377 IN DAT_DICTIONARY *p_dictionary,
375 378 IN DAT_DICTIONARY_ENTRY *p_entry,
376 379 IN const DAT_PROVIDER_INFO *key,
377 380 OUT DAT_DICTIONARY_DATA *p_data)
378 381 {
379 382 DAT_DICTIONARY_NODE *cur_node, *prev_node, *next_node;
380 383 DAT_RETURN status;
381 384
382 385 dat_os_assert(NULL != p_dictionary);
383 386 dat_os_assert(NULL != p_entry);
384 387
385 388 status = DAT_ERROR(DAT_NAME_NOT_FOUND, 0);
386 389
387 390 for (cur_node = p_dictionary->head->next;
388 391 p_dictionary->tail != cur_node;
389 392 cur_node = cur_node->next) {
390 393 if (DAT_TRUE == dat_dictionary_key_is_equal(&cur_node->key,
391 394 key)) {
392 395 if (NULL != p_data) {
393 396 *p_data = cur_node->data;
394 397 }
395 398
396 399 prev_node = cur_node->prev;
397 400 next_node = cur_node->next;
398 401
399 402 prev_node->next = next_node;
400 403 next_node->prev = prev_node;
401 404
402 405 *p_entry = cur_node;
403 406
404 407 p_dictionary->size--;
405 408
406 409 status = DAT_SUCCESS;
407 410 goto bail;
408 411 }
409 412 }
410 413
411 414 bail:
412 415 return (status);
413 416 }
414 417
415 418
416 419 /*
417 420 *
418 421 * Internal Function Definitions
419 422 *
420 423 */
421 424
422 425
423 426 /*
424 427 * Function: dat_dictionary_key_create
425 428 */
426 429
427 430 DAT_RETURN
428 431 dat_dictionary_key_dup(
429 432 const DAT_PROVIDER_INFO *old_key,
430 433 DAT_PROVIDER_INFO *new_key)
431 434 {
432 435 dat_os_assert(NULL != old_key);
433 436 dat_os_assert(NULL != new_key);
434 437
435 438 (void) dat_os_strncpy(new_key->ia_name, old_key->ia_name,
436 439 DAT_NAME_MAX_LENGTH);
437 440 new_key->dapl_version_major = old_key->dapl_version_major;
438 441 new_key->dapl_version_minor = old_key->dapl_version_minor;
439 442 new_key->is_thread_safe = old_key->is_thread_safe;
440 443
441 444 return (DAT_SUCCESS);
442 445 }
443 446
444 447
445 448 /*
446 449 * Function: dat_dictionary_key_is_equal
447 450 */
448 451
449 452 DAT_BOOLEAN
450 453 dat_dictionary_key_is_equal(
451 454 const DAT_PROVIDER_INFO *key_a,
452 455 const DAT_PROVIDER_INFO *key_b)
453 456 {
454 457 if ((dat_os_strlen(key_a->ia_name) == dat_os_strlen(key_b->ia_name)) &&
455 458 (!dat_os_strncmp(key_a->ia_name, key_b->ia_name,
456 459 dat_os_strlen(key_a->ia_name))) &&
457 460 (key_a->dapl_version_major == key_b->dapl_version_major) &&
458 461 (key_a->dapl_version_minor == key_b->dapl_version_minor) &&
459 462 (key_a->is_thread_safe == key_b->is_thread_safe)) {
460 463 return (DAT_TRUE);
461 464 } else {
462 465 return (DAT_FALSE);
463 466 }
464 467 }
↓ open down ↓ |
296 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX