Text   |  XML   |  ReML   |   Visible Warnings:

Null Test After Dereference  at packet-sctp.c:2394

No properties have been set. | edit properties
Jump to warning location ↓ warning details...
Show Events | Options

fragment_reassembly

(/home/sate/Testcases/c/cve/wireshark-1.2.0/epan/dissectors/packet-sctp.c)expand/collapse
Show more  
 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) {
 2299      /* no message, we can't do anything */
 2300      return NULL;
 2301    }
 2302   
 2303    /* check if fragment is part of an already reassembled message */
 2304    for (message = msg->messages;
 2305         message &&
 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) {
 2312      /* we found the reassembled message this fragment belongs to */
 2313      if (fragment == message->reassembled_in) {
 2314   
 2315        /* this is the last fragment, create data source */
 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        /* display reassembly info */
 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      /* this is not the last fragment,
 2361       * so let the user know the frame where the reassembly is 
 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    /* this fragment has not been reassembled, yet 
 2371     * check now if we can reassemble it 
 2372     * at first look for the first and last tsn of the msg
 2373     */
 2374    for (begin = msg->begins;
 2375         begin && begin->fragment->tsn > fragment->tsn;
 2376         begin = begin->next);
 2377   
 2378    /* in case begin still is null, set it to first (highest) begin 
 2379     * maybe the message tsn restart at 0 in between 
 2380     */
 2381    if (!begin)
 2382      begin = msg->begins;
 2383   
 2384    for (end = msg->ends;
 2385         end && end->fragment->tsn < fragment->tsn;
 2386         end = end->next);
 2387   
 2388    /* in case end still is null, set it to first (lowest) end 
 2389     * maybe the message tsn restart at 0 in between 
 2390     */
 2391    if (!end)
 2392      end = msg->ends;
 2393   
 2394    if (!begin || !end || !msg->fragments ||
 2395        (begin->fragment->tsn > end->fragment->tsn && msg->fragments->tsn)) {
 2396      /* begin and end have not been collected, yet 
 2397       * or there might be a tsn restart but the first fragment hasn't a tsn of 0
 2398       * just mark as fragment
 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    /* we found possible begin and end
 2408     * look for the first fragment and then try to get to the end 
 2409     */
 2410    first_frag = begin->fragment;
 2411   
 2412    /* while looking if all fragments are there 
 2413     * we can calculate the overall length that 
 2414     * we need in case of success
 2415     */
 2416    len = first_frag->len;
 2417   
 2418    /* check if begin is past end
 2419     * this can happen if there has been a tsn restart
 2420     * or we just got the wrong begin and end 
 2421     * so give it a try 
 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      /* check if we reached the last possible tsn
 2429       * if yes, restart and continue 
 2430       */
 2431      if ((last_frag->tsn + 1)) {
 2432        /* there are just fragments missing */
 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      /* we got all fragments until the last possible tsn 
 2440       * and the first is 0 if we got here 
 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      /* we need more fragments. just mark as fragment */
 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    /* ok, this message is complete, we can reassemble it
 2463     * but at first don't forget to add the length of the last fragment 
 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    /* now copy all fragments */
 2476    if (begin->fragment->tsn > end->fragment->tsn) {
 2477      /* a tsn restart has occured */
 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        /* release fragment data */
 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        /* release fragment data */
 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        /* release fragment data */
 2514        g_free(frag_i->data);
 2515        frag_i->data = NULL;
 2516      }
 2517    }
 2518   
 2519    /* save message */
 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    /* remove begin and end from list */
 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    /* create data source */
 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    /* display reassembly info */
 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    /* it's not fragmented anymore */
 2596    pinfo->fragmented = FALSE;
 2597   
 2598    return new_tvb;
 2599  }
Show more  




Change Warning 12352.31891 : Null Test After Dereference

Because they are very similar, this warning shares annotations with warning 12352.31892.

Priority:
State:
Finding:
Owner:
Note: