(/home/sate/Testcases/c/cve/wireshark-1.2.0/epan/dissectors/packet-sctp.c) |
| |
| 2282 | | | static tvbuff_t* |
| 2283 | | | fragment_reassembly(tvbuff_t *tvb, sctp_fragment* fragment, |
| 2284 | | | packet_info *pinfo, proto_tree *tree, guint16 stream_id, |
| 2285 | | | guint16 stream_seq_num) |
| 2286 | | | { |
| 2287 | | | sctp_frag_msg *msg; |
| 2288 | | | sctp_complete_msg *message, *last_message; |
| 2289 | | | sctp_fragment *frag_i, *last_frag, *first_frag; |
| 2290 | | | sctp_frag_be *begin, *end, *beginend; |
| 2291 | | | guint32 len, offset = 0; |
| 2292 | | | tvbuff_t* new_tvb = NULL; |
| 2293 | | | proto_item *item; |
| 2294 | | | proto_tree *ptree; |
| 2295 | | | |
| 2296 | | | msg = find_message(stream_id, stream_seq_num); |
| 2297 | | | |
| 2298 | | | if (!msg) { |
Event 1:
Skipping " if". msg evaluates to true.
hide
|
|
| 2299 | | | |
| 2300 | | | return NULL; |
| 2301 | | | } |
| 2302 | | | |
| 2303 | | | |
| 2304 | | | for (message = msg->messages; |
| 2305 | | | message && |
Event 2:
Leaving loop. message evaluates to false.
hide
|
|
| 2306 | | | !(message->begin <= fragment->tsn && message->end >= fragment->tsn) && |
| 2307 | | | !(message->begin > message->end && |
| 2308 | | | (message->begin <= fragment->tsn || message->end >= fragment->tsn)); |
| 2309 | | | message = message->next); |
| 2310 | | | |
| 2311 | | | if (message) { |
Event 3:
Skipping " if". message evaluates to false.
hide
|
|
| 2312 | | | |
| 2313 | | | if (fragment == message->reassembled_in) { |
| 2314 | | | |
| 2315 | | | |
| 2316 | | | new_tvb = tvb_new_child_real_data(tvb, message->data, message->len, message->len); |
| 2317 | | | add_new_data_source(pinfo, new_tvb, "Reassembled SCTP Message"); |
| 2318 | | | |
| 2319 | | | |
| 2320 | | | item = proto_tree_add_item(tree, hf_sctp_fragments, tvb, 0, -1, FALSE); |
| 2321 | | | ptree = proto_item_add_subtree(item, ett_sctp_fragments); |
| 2322 | | | proto_item_append_text(item, " (%u bytes, %u fragments): ", |
| 2323 | | | message->len, message->end - message->begin + 1); |
| 2324 | | | |
| 2325 | | | if (message->begin > message->end) { |
| 2326 | | | for (frag_i = find_fragment(message->begin, stream_id, stream_seq_num); |
| 2327 | | | frag_i; |
| 2328 | | | frag_i = frag_i->next) { |
| 2329 | | | |
| 2330 | | | proto_tree_add_uint_format(ptree, hf_sctp_fragment, new_tvb, offset, frag_i->len, |
| 2331 | | | frag_i->frame_num, "Frame: %u, payload: %u-%u (%u bytes)", |
| 2332 | | | frag_i->frame_num, offset, offset + frag_i->len - 1, frag_i->len); |
| 2333 | | | offset += frag_i->len; |
| 2334 | | | } |
| 2335 | | | |
| 2336 | | | for (frag_i = msg->fragments; |
| 2337 | | | frag_i && frag_i->tsn <= message->end; |
| 2338 | | | frag_i = frag_i->next) { |
| 2339 | | | |
| 2340 | | | proto_tree_add_uint_format(ptree, hf_sctp_fragment, new_tvb, offset, frag_i->len, |
| 2341 | | | frag_i->frame_num, "Frame: %u, payload: %u-%u (%u bytes)", |
| 2342 | | | frag_i->frame_num, offset, offset + frag_i->len - 1, frag_i->len); |
| 2343 | | | offset += frag_i->len; |
| 2344 | | | } |
| 2345 | | | } else { |
| 2346 | | | for (frag_i = find_fragment(message->begin, stream_id, stream_seq_num); |
| 2347 | | | frag_i && frag_i->tsn <= message->end; |
| 2348 | | | frag_i = frag_i->next) { |
| 2349 | | | |
| 2350 | | | proto_tree_add_uint_format(ptree, hf_sctp_fragment, new_tvb, offset, frag_i->len, |
| 2351 | | | frag_i->frame_num, "Frame: %u, payload: %u-%u (%u bytes)", |
| 2352 | | | frag_i->frame_num, offset, offset + frag_i->len - 1, frag_i->len); |
| 2353 | | | offset += frag_i->len; |
| 2354 | | | } |
| 2355 | | | } |
| 2356 | | | |
| 2357 | | | return new_tvb; |
| 2358 | | | } |
| 2359 | | | |
| 2360 | | | |
| 2361 | | | |
| 2362 | | | |
| 2363 | | | if (check_col(pinfo->cinfo, COL_INFO)) |
| 2364 | | | col_append_str(pinfo->cinfo, COL_INFO, " (Message Fragment) "); |
| 2365 | | | |
| 2366 | | | proto_tree_add_uint(tree, hf_sctp_reassembled_in, tvb, 0, 0, message->reassembled_in->frame_num); |
| 2367 | | | return NULL; |
| 2368 | | | } |
| 2369 | | | |
| 2370 | | | |
| 2371 | | | |
| 2372 | | | |
| 2373 | | | |
| 2374 | | | for (begin = msg->begins; |
| 2375 | | | begin && begin->fragment->tsn > fragment->tsn; |
| 2376 | | | begin = begin->next); |
| 2377 | | | |
| 2378 | | | |
| 2379 | | | |
| 2380 | | | |
| 2381 | | | if (!begin) |
Event 6:
Skipping " if". begin evaluates to true.
hide
|
|
| 2382 | | | begin = msg->begins; |
| 2383 | | | |
| 2384 | | | for (end = msg->ends; |
| 2385 | | | end && end->fragment->tsn < fragment->tsn; |
| 2386 | | | end = end->next); |
| 2387 | | | |
| 2388 | | | |
| 2389 | | | |
| 2390 | | | |
| 2391 | | | if (!end) |
Event 8:
Skipping " if". end evaluates to true.
hide
|
|
| 2392 | | | end = msg->ends; |
| 2393 | | | |
| 2394 | | | if (!begin || !end || !msg->fragments || |
Null Test After Dereference
This code tests the nullness of begin, which has already been dereferenced. - If begin were null, there would have been a prior null pointer dereference at packet-sctp.c:2375, and potentially at other locations as well.
- Either this test is redundant, or the earlier dereference(s) should be guarded by a similar test.
The issue can occur if the highlighted code executes. See related event 5. Show: All events | Only primary events |
|
| 2395 | | | (begin->fragment->tsn > end->fragment->tsn && msg->fragments->tsn)) { |
| 2396 | | | |
| 2397 | | | |
| 2398 | | | |
| 2399 | | | |
| 2400 | | | |
| 2401 | | | if (check_col(pinfo->cinfo, COL_INFO)) |
| 2402 | | | col_append_str(pinfo->cinfo, COL_INFO, " (Message Fragment) "); |
| 2403 | | | |
| 2404 | | | return NULL; |
| 2405 | | | } |
| 2406 | | | |
| 2407 | | | |
| 2408 | | | |
| 2409 | | | |
| 2410 | | | first_frag = begin->fragment; |
| 2411 | | | |
| 2412 | | | |
| 2413 | | | |
| 2414 | | | |
| 2415 | | | |
| 2416 | | | len = first_frag->len; |
| 2417 | | | |
| 2418 | | | |
| 2419 | | | |
| 2420 | | | |
| 2421 | | | |
| 2422 | | | |
| 2423 | | | if (begin->fragment->tsn > end->fragment->tsn) { |
| 2424 | | | for (last_frag = first_frag, frag_i = first_frag->next; |
| 2425 | | | frag_i && frag_i->tsn == (last_frag->tsn + 1); |
| 2426 | | | last_frag = frag_i, frag_i = frag_i->next) len += frag_i->len; |
| 2427 | | | |
| 2428 | | | |
| 2429 | | | |
| 2430 | | | |
| 2431 | | | if ((last_frag->tsn + 1)) { |
| 2432 | | | |
| 2433 | | | if (check_col(pinfo->cinfo, COL_INFO)) |
| 2434 | | | col_append_str(pinfo->cinfo, COL_INFO, " (Message Fragment) "); |
| 2435 | | | |
| 2436 | | | return NULL; |
| 2437 | | | } |
| 2438 | | | |
| 2439 | | | |
| 2440 | | | |
| 2441 | | | |
| 2442 | | | |
| 2443 | | | len += msg->fragments->len; |
| 2444 | | | for (last_frag = msg->fragments, frag_i = last_frag->next; |
| 2445 | | | frag_i && frag_i->tsn < end->fragment->tsn && frag_i->tsn == (last_frag->tsn + 1); |
| 2446 | | | last_frag = frag_i, frag_i = frag_i->next) len += frag_i->len; |
| 2447 | | | |
| 2448 | | | } else { |
| 2449 | | | for (last_frag = first_frag, frag_i = first_frag->next; |
| 2450 | | | frag_i && frag_i->tsn < end->fragment->tsn && frag_i->tsn == (last_frag->tsn + 1); |
| 2451 | | | last_frag = frag_i, frag_i = frag_i->next) len += frag_i->len; |
| 2452 | | | } |
| 2453 | | | |
| 2454 | | | if (!frag_i || frag_i != end->fragment || frag_i->tsn != (last_frag->tsn + 1)) { |
| 2455 | | | |
| 2456 | | | if (check_col(pinfo->cinfo, COL_INFO)) |
| 2457 | | | col_append_str(pinfo->cinfo, COL_INFO, " (Message Fragment) "); |
| 2458 | | | |
| 2459 | | | return NULL; |
| 2460 | | | } |
| 2461 | | | |
| 2462 | | | |
| 2463 | | | |
| 2464 | | | |
| 2465 | | | len += frag_i->len; |
| 2466 | | | |
| 2467 | | | message = se_alloc (sizeof (sctp_complete_msg)); |
| 2468 | | | message->begin = begin->fragment->tsn; |
| 2469 | | | message->end = end->fragment->tsn; |
| 2470 | | | message->reassembled_in = fragment; |
| 2471 | | | message->len = len; |
| 2472 | | | message->data = se_alloc(len); |
| 2473 | | | message->next = NULL; |
| 2474 | | | |
| 2475 | | | |
| 2476 | | | if (begin->fragment->tsn > end->fragment->tsn) { |
| 2477 | | | |
| 2478 | | | for (frag_i = first_frag; |
| 2479 | | | frag_i; |
| 2480 | | | frag_i = frag_i->next) { |
| 2481 | | | |
| 2482 | | | if (frag_i->len && frag_i->data) |
| 2483 | | | memcpy(message->data + offset, frag_i->data, frag_i->len); |
| 2484 | | | offset += frag_i->len; |
| 2485 | | | |
| 2486 | | | |
| 2487 | | | g_free(frag_i->data); |
| 2488 | | | frag_i->data = NULL; |
| 2489 | | | } |
| 2490 | | | |
| 2491 | | | for (frag_i = msg->fragments; |
| 2492 | | | frag_i && frag_i->tsn <= end->fragment->tsn; |
| 2493 | | | frag_i = frag_i->next) { |
| 2494 | | | |
| 2495 | | | if (frag_i->len && frag_i->data) |
| 2496 | | | memcpy(message->data + offset, frag_i->data, frag_i->len); |
| 2497 | | | offset += frag_i->len; |
| 2498 | | | |
| 2499 | | | |
| 2500 | | | g_free(frag_i->data); |
| 2501 | | | frag_i->data = NULL; |
| 2502 | | | } |
| 2503 | | | |
| 2504 | | | } else { |
| 2505 | | | for (frag_i = first_frag; |
| 2506 | | | frag_i && frag_i->tsn <= end->fragment->tsn; |
| 2507 | | | frag_i = frag_i->next) { |
| 2508 | | | |
| 2509 | | | if (frag_i->len && frag_i->data) |
| 2510 | | | memcpy(message->data + offset, frag_i->data, frag_i->len); |
| 2511 | | | offset += frag_i->len; |
| 2512 | | | |
| 2513 | | | |
| 2514 | | | g_free(frag_i->data); |
| 2515 | | | frag_i->data = NULL; |
| 2516 | | | } |
| 2517 | | | } |
| 2518 | | | |
| 2519 | | | |
| 2520 | | | if (!msg->messages) { |
| 2521 | | | msg->messages = message; |
| 2522 | | | } else { |
| 2523 | | | for (last_message = msg->messages; |
| 2524 | | | last_message->next; |
| 2525 | | | last_message = last_message->next); |
| 2526 | | | |
| 2527 | | | last_message->next = message; |
| 2528 | | | } |
| 2529 | | | |
| 2530 | | | |
| 2531 | | | if (msg->begins == begin) { |
| 2532 | | | msg->begins = begin->next; |
| 2533 | | | } else { |
| 2534 | | | for (beginend = msg->begins; |
| 2535 | | | beginend && beginend->next != begin; |
| 2536 | | | beginend = beginend->next); |
| 2537 | | | if (beginend && beginend->next == begin) |
| 2538 | | | beginend->next = begin->next; |
| 2539 | | | } |
| 2540 | | | g_free(begin); |
| 2541 | | | |
| 2542 | | | if (msg->ends == end) { |
| 2543 | | | msg->ends = end->next; |
| 2544 | | | } else { |
| 2545 | | | for (beginend = msg->ends; |
| 2546 | | | beginend && beginend->next != end; |
| 2547 | | | beginend = beginend->next); |
| 2548 | | | if (beginend && beginend->next == end) |
| 2549 | | | beginend->next = end->next; |
| 2550 | | | } |
| 2551 | | | g_free(end); |
| 2552 | | | |
| 2553 | | | |
| 2554 | | | new_tvb = tvb_new_child_real_data(tvb, message->data, len, len); |
| 2555 | | | add_new_data_source(pinfo, new_tvb, "Reassembled SCTP Message"); |
| 2556 | | | |
| 2557 | | | |
| 2558 | | | item = proto_tree_add_item(tree, hf_sctp_fragments, tvb, 0, -1, FALSE); |
| 2559 | | | ptree = proto_item_add_subtree(item, ett_sctp_fragments); |
| 2560 | | | proto_item_append_text(item, " (%u bytes, %u fragments): ", |
| 2561 | | | message->len, message->end - message->begin + 1); |
| 2562 | | | |
| 2563 | | | if (message->begin > message->end) { |
| 2564 | | | for (frag_i = find_fragment(message->begin, stream_id, stream_seq_num); |
| 2565 | | | frag_i; |
| 2566 | | | frag_i = frag_i->next) { |
| 2567 | | | |
| 2568 | | | proto_tree_add_uint_format(ptree, hf_sctp_fragment, new_tvb, offset, frag_i->len, |
| 2569 | | | frag_i->frame_num, "Frame: %u, payload: %u-%u (%u bytes)", |
| 2570 | | | frag_i->frame_num, offset, offset + frag_i->len - 1, frag_i->len); |
| 2571 | | | offset += frag_i->len; |
| 2572 | | | } |
| 2573 | | | |
| 2574 | | | for (frag_i = msg->fragments; |
| 2575 | | | frag_i && frag_i->tsn <= message->end; |
| 2576 | | | frag_i = frag_i->next) { |
| 2577 | | | |
| 2578 | | | proto_tree_add_uint_format(ptree, hf_sctp_fragment, new_tvb, offset, frag_i->len, |
| 2579 | | | frag_i->frame_num, "Frame: %u, payload: %u-%u (%u bytes)", |
| 2580 | | | frag_i->frame_num, offset, offset + frag_i->len - 1, frag_i->len); |
| 2581 | | | offset += frag_i->len; |
| 2582 | | | } |
| 2583 | | | } else { |
| 2584 | | | for (frag_i = find_fragment(message->begin, stream_id, stream_seq_num); |
| 2585 | | | frag_i && frag_i->tsn <= message->end; |
| 2586 | | | frag_i = frag_i->next) { |
| 2587 | | | |
| 2588 | | | proto_tree_add_uint_format(ptree, hf_sctp_fragment, new_tvb, offset, frag_i->len, |
| 2589 | | | frag_i->frame_num, "Frame: %u, payload: %u-%u (%u bytes)", |
| 2590 | | | frag_i->frame_num, offset, offset + frag_i->len - 1, frag_i->len); |
| 2591 | | | offset += frag_i->len; |
| 2592 | | | } |
| 2593 | | | } |
| 2594 | | | |
| 2595 | | | |
| 2596 | | | pinfo->fragmented = FALSE; |
| 2597 | | | |
| 2598 | | | return new_tvb; |
| 2599 | | | } |
| |