(/home/sate/Testcases/c/cve/wireshark-1.2.0/epan/dissectors/packet-ber.c) |
| |
| 2507 | | | dissect_ber_choice(asn1_ctx_t *actx, proto_tree *parent_tree, tvbuff_t *tvb, int offset, const ber_choice_t *choice, gint hf_id, gint ett_id, gint *branch_taken) |
| 2508 | | | { |
| 2509 | | | gint8 class; |
| 2510 | | | gboolean pc, ind, imp_tag = FALSE; |
| 2511 | | | gint32 tag; |
| 2512 | | | guint32 len; |
| 2513 | | | const ber_choice_t *ch; |
| 2514 | | | proto_tree *tree=parent_tree; |
| 2515 | | | proto_item *item=NULL; |
| 2516 | | | int end_offset, start_offset, count; |
| 2517 | | | int hoffset = offset; |
| 2518 | | | *hfinfo; |
| 2519 | | | gint length, length_remaining; |
| 2520 | | | tvbuff_t *next_tvb; |
| 2521 | | | gboolean first_pass; |
| 2522 | | | |
| 2523 | | | #ifdef DEBUG_BER_CHOICE |
| 2524 | | | { |
| 2525 | | | const char *name; |
| 2526 | | | *hfinfo; |
| 2527 | | | if(hf_id>=0){ |
| 2528 | | | hfinfo = proto_registrar_get_nth(hf_id); |
| 2529 | | | name=hfinfo->name; |
| 2530 | | | } else { |
| 2531 | | | name="unnamed"; |
| 2532 | | | } |
| 2533 | | | if(tvb_length_remaining(tvb,offset)>3){ |
| 2534 | | | printf("CHOICE dissect_ber_choice(%s) entered offset:%d len:%d %02x:%02x:%02x\n",name,offset,tvb_length_remaining(tvb,offset),tvb_get_guint8(tvb,offset),tvb_get_guint8(tvb,offset+1),tvb_get_guint8(tvb,offset+2)); |
| 2535 | | | }else{ |
| 2536 | | | printf("CHOICE dissect_ber_choice(%s) entered len:%d\n",name,tvb_length_remaining(tvb,offset)); |
| 2537 | | | } |
| 2538 | | | } |
| 2539 | | | #endif |
| 2540 | | | start_offset=offset; |
| 2541 | | | |
| 2542 | | | if(tvb_length_remaining(tvb,offset) == 0) { |
Event 1:
Skipping " if". tvb_length_remaining(...) == 0 evaluates to false.
hide
|
|
| 2543 | | | item = proto_tree_add_text(parent_tree, tvb, offset, 0, "BER Error: Empty choice was found"); |
| 2544 | | | proto_item_set_expert_flags(item, PI_MALFORMED, PI_WARN); |
| 2545 | | | expert_add_info_format(actx->pinfo, item, PI_MALFORMED, PI_WARN, "BER Error: Empty choice was found"); |
| 2546 | | | return offset; |
| 2547 | | | } |
| 2548 | | | |
| 2549 | | | |
| 2550 | | | offset=get_ber_identifier(tvb, offset, &class, &pc, &tag); |
| 2551 | | | offset=get_ber_length(tvb, offset, &len, &ind); |
| 2552 | | | end_offset = offset + len ; |
| 2553 | | | |
| 2554 | | | |
| 2555 | | | |
| 2556 | | | |
| 2557 | | | if(hf_id >= 0){ |
Event 2:
Skipping " if". hf_id >= 0 evaluates to false.
hide
|
|
| 2558 | | | hfinfo=proto_registrar_get_nth(hf_id); |
| 2559 | | | switch(hfinfo->type) { |
| 2560 | | | case FT_UINT8: |
| 2561 | | | case FT_UINT16: |
| 2562 | | | case FT_UINT24: |
| 2563 | | | case FT_UINT32: |
| 2564 | | | break; |
| 2565 | | | default: |
| 2566 | | | proto_tree_add_text(tree, tvb, offset, len,"dissect_ber_choice(): Was passed a HF field that was not integer type : %s",hfinfo->abbrev); |
| 2567 | | | fprintf(stderr,"dissect_ber_choice(): frame:%u offset:%d Was passed a HF field that was not integer type : %s\n",actx->pinfo->fd->num,offset,hfinfo->abbrev); |
| 2568 | | | return end_offset; |
| 2569 | | | } |
| 2570 | | | } |
| 2571 | | | |
| 2572 | | | |
| 2573 | | | |
| 2574 | | | |
| 2575 | | | |
| 2576 | | | ch = choice; |
| 2577 | | | if(branch_taken){ |
Event 3:
Taking true branch. branch_taken evaluates to true.
hide
|
|
| 2578 | | | *branch_taken=-1; |
| 2579 | | | } |
| 2580 | | | first_pass = TRUE; |
Event 4:
!0 evaluates to true.
hide
|
|
| 2581 | | | while(ch->func || first_pass){ |
| 2582 | | | if(branch_taken){ |
Event 7:
Taking true branch. branch_taken evaluates to true.
hide
|
|
| 2583 | | | (*branch_taken)++; |
| 2584 | | | } |
| 2585 | | | |
| 2586 | | | if(!ch->func) { |
Event 9:
Taking true branch. ch->func evaluates to false.
hide
|
|
| 2587 | | | first_pass = FALSE; |
| 2588 | | | ch = choice; |
| 2589 | | | if(branch_taken){ |
Null Test After Dereference
This code tests the nullness of branch_taken, which has already been dereferenced. - If branch_taken were null, there would have been a prior null pointer dereference at packet-ber.c:2583, 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 8. Show: All events | Only primary events |
|
| 2590 | | | *branch_taken=-1; |
| 2591 | | | } |
| 2592 | | | } |
| 2593 | | | |
| 2594 | | | choice_try_again: |
| 2595 | | | #ifdef DEBUG_BER_CHOICE |
| 2596 | | | printf("CHOICE testing potential subdissector class[%p]:%d:(expected)%d tag:%d:(expected)%d flags:%d\n",ch,class,ch->class,tag,ch->tag,ch->flags); |
| 2597 | | | #endif |
| 2598 | | | if( (first_pass && (((ch->class==class)&&(ch->tag==tag)) |
| 2599 | | | || ((ch->class==class)&&(ch->tag==-1)&&(ch->flags&BER_FLAGS_NOOWNTAG)))) || |
| 2600 | | | (!first_pass && (((ch->class == BER_CLASS_ANY) && (ch->tag == -1)))) |
| 2601 | | | ){ |
| 2602 | | | if(!(ch->flags & BER_FLAGS_NOOWNTAG)){ |
| 2603 | | | |
| 2604 | | | hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, start_offset, NULL, NULL, NULL); |
| 2605 | | | hoffset = dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); |
| 2606 | | | start_offset=hoffset; |
| 2607 | | | if (ind) |
| 2608 | | | { |
| 2609 | | | length = len-2; |
| 2610 | | | } |
| 2611 | | | else |
| 2612 | | | { |
| 2613 | | | length = len; |
| 2614 | | | } |
| 2615 | | | } |
| 2616 | | | else |
| 2617 | | | length = end_offset- hoffset; |
| 2618 | | | |
| 2619 | | | if(hf_id >= 0){ |
| 2620 | | | if(parent_tree){ |
| 2621 | | | item = proto_tree_add_uint(parent_tree, hf_id, tvb, hoffset, end_offset - hoffset, ch->value); |
| 2622 | | | tree = proto_item_add_subtree(item, ett_id); |
| 2623 | | | } |
| 2624 | | | } |
| 2625 | | | |
| 2626 | | | length_remaining=tvb_length_remaining(tvb, hoffset); |
| 2627 | | | if(length_remaining>length) |
| 2628 | | | length_remaining=length; |
| 2629 | | | |
| 2630 | | | #ifdef REMOVED |
| 2631 | | | |
| 2632 | | | |
| 2633 | | | |
| 2634 | | | |
| 2635 | | | |
| 2636 | | | |
| 2637 | | | |
| 2638 | | | |
| 2639 | | | if(first_pass) |
| 2640 | | | next_tvb=tvb_new_subset(tvb, hoffset, length_remaining, length); |
| 2641 | | | else |
| 2642 | | | next_tvb = tvb; |
| 2643 | | | #endif |
| 2644 | | | next_tvb=tvb_new_subset(tvb, hoffset, length_remaining, length); |
| 2645 | | | |
| 2646 | | | |
| 2647 | | | #ifdef DEBUG_BER_CHOICE |
| 2648 | | | { |
| 2649 | | | const char *name; |
| 2650 | | | *hfinfo; |
| 2651 | | | if(hf_id>=0){ |
| 2652 | | | hfinfo = proto_registrar_get_nth(hf_id); |
| 2653 | | | name=hfinfo->name; |
| 2654 | | | } else { |
| 2655 | | | name="unnamed"; |
| 2656 | | | } |
| 2657 | | | if(tvb_length_remaining(next_tvb,0)>3){ |
| 2658 | | | printf("CHOICE dissect_ber_choice(%s) calling subdissector start_offset:%d offset:%d len:%d %02x:%02x:%02x\n",name,start_offset,offset,tvb_length_remaining(next_tvb,0),tvb_get_guint8(next_tvb,0),tvb_get_guint8(next_tvb,1),tvb_get_guint8(next_tvb,2)); |
| 2659 | | | }else{ |
| 2660 | | | printf("CHOICE dissect_ber_choice(%s) calling subdissector len:%d\n",name,tvb_length(next_tvb)); |
| 2661 | | | } |
| 2662 | | | } |
| 2663 | | | #endif |
| 2664 | | | if (next_tvb == NULL) { |
| 2665 | | | |
| 2666 | | | THROW(ReportedBoundsError);
x /home/sate/Testcases/c/cve/wireshark-1.2.0/epan/exceptions.h |
| |
223 | #define THROW(x) \ |
224 | except_throw(XCEPT_GROUP_WIRESHARK, (x), NULL) |
| |
|
| 2667 | | | } |
| 2668 | | | imp_tag = FALSE; |
| 2669 | | | if ((ch->flags & BER_FLAGS_IMPLTAG)) |
| 2670 | | | imp_tag = TRUE; |
| 2671 | | | count=ch->func(imp_tag, next_tvb, 0, actx, tree, *ch->p_id); |
| 2672 | | | #ifdef DEBUG_BER_CHOICE |
| 2673 | | | { |
| 2674 | | | const char *name; |
| 2675 | | | *hfinfo; |
| 2676 | | | if(hf_id>=0){ |
| 2677 | | | hfinfo = proto_registrar_get_nth(hf_id); |
| 2678 | | | name=hfinfo->name; |
| 2679 | | | } else { |
| 2680 | | | name="unnamed"; |
| 2681 | | | } |
| 2682 | | | printf("CHOICE dissect_ber_choice(%s) subdissector ate %d bytes\n",name,count); |
| 2683 | | | } |
| 2684 | | | #endif |
| 2685 | | | if((count==0)&&(((ch->class==class)&&(ch->tag==-1)&&(ch->flags&BER_FLAGS_NOOWNTAG)) || !first_pass)){ |
| 2686 | | | |
| 2687 | | | ch++; |
| 2688 | | | #ifdef DEBUG_BER_CHOICE |
| 2689 | | | { |
| 2690 | | | const char *name; |
| 2691 | | | *hfinfo; |
| 2692 | | | if(hf_id>=0){ |
| 2693 | | | hfinfo = proto_registrar_get_nth(hf_id); |
| 2694 | | | name=hfinfo->name; |
| 2695 | | | } else { |
| 2696 | | | name="unnamed"; |
| 2697 | | | } |
| 2698 | | | printf("CHOICE dissect_ber_choice(%s) trying again\n",name); |
| 2699 | | | } |
| 2700 | | | #endif |
| 2701 | | | goto choice_try_again; |
| 2702 | | | } |
| 2703 | | | if(!(ch->flags & BER_FLAGS_NOOWNTAG)){ |
| 2704 | | | if(ind) |
| 2705 | | | { |
| 2706 | | | |
| 2707 | | | |
| 2708 | | | if(show_internal_ber_fields){ |
| 2709 | | | proto_tree_add_text(tree, tvb, start_offset, count+2, "CHOICE EOC"); |
| 2710 | | | } |
| 2711 | | | } |
| 2712 | | | } |
| 2713 | | | return end_offset; |
| 2714 | | | } |
| 2715 | | | ch++; |
| 2716 | | | } |
| 2717 | | | if(branch_taken){ |
| 2718 | | | |
| 2719 | | | |
| 2720 | | | *branch_taken=-1; |
| 2721 | | | } |
| 2722 | | | |
| 2723 | | | #ifdef REMOVED |
| 2724 | | | |
| 2725 | | | |
| 2726 | | | |
| 2727 | | | |
| 2728 | | | |
| 2729 | | | |
| 2730 | | | item = proto_tree_add_text(tree, tvb, offset, len, "BER Error: This choice field was not found."); |
| 2731 | | | proto_item_set_expert_flags(item, PI_MALFORMED, PI_WARN); |
| 2732 | | | expert_add_info_format(actx->pinfo, item, PI_MALFORMED, PI_WARN, "BER Error: This choice field was not found"); |
| 2733 | | | return end_offset; |
| 2734 | | | #endif |
| 2735 | | | |
| 2736 | | | return start_offset; |
| 2737 | | | } |
| |