(/home/sate/Testcases/c/cve/wireshark-1.2.0/epan/dissectors/packet-ber.c) |
| |
| 2740 | | | dissect_ber_old_choice(asn1_ctx_t *actx, proto_tree *parent_tree, tvbuff_t *tvb, int offset, const ber_old_choice_t *choice, gint hf_id, gint ett_id, gint *branch_taken) |
| 2741 | | | { |
| 2742 | | | gint8 class; |
| 2743 | | | gboolean pc, ind; |
| 2744 | | | gint32 tag; |
| 2745 | | | guint32 len; |
| 2746 | | | const ber_old_choice_t *ch; |
| 2747 | | | proto_tree *tree=parent_tree; |
| 2748 | | | proto_item *item=NULL; |
| 2749 | | | int end_offset, start_offset, count; |
| 2750 | | | int hoffset = offset; |
| 2751 | | | *hfinfo; |
| 2752 | | | gint length, length_remaining; |
| 2753 | | | tvbuff_t *next_tvb; |
| 2754 | | | gboolean first_pass; |
| 2755 | | | |
| 2756 | | | #ifdef DEBUG_BER_CHOICE |
| 2757 | | | { |
| 2758 | | | const char *name; |
| 2759 | | | *hfinfo; |
| 2760 | | | if(hf_id>=0){ |
| 2761 | | | hfinfo = proto_registrar_get_nth(hf_id); |
| 2762 | | | name=hfinfo->name; |
| 2763 | | | } else { |
| 2764 | | | name="unnamed"; |
| 2765 | | | } |
| 2766 | | | if(tvb_length_remaining(tvb,offset)>3){ |
| 2767 | | | printf("CHOICE dissect_ber_old_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)); |
| 2768 | | | }else{ |
| 2769 | | | printf("CHOICE dissect_ber_old_choice(%s) entered len:%d\n",name,tvb_length_remaining(tvb,offset)); |
| 2770 | | | } |
| 2771 | | | } |
| 2772 | | | #endif |
| 2773 | | | start_offset=offset; |
| 2774 | | | |
| 2775 | | | if(tvb_length_remaining(tvb,offset) == 0) { |
Event 1:
Skipping " if". tvb_length_remaining(...) == 0 evaluates to false.
hide
|
|
| 2776 | | | item = proto_tree_add_text(parent_tree, tvb, offset, 0, "BER Error: Empty choice was found"); |
| 2777 | | | proto_item_set_expert_flags(item, PI_MALFORMED, PI_WARN); |
| 2778 | | | expert_add_info_format(actx->pinfo, item, PI_MALFORMED, PI_WARN, "BER Error: Empty choice was found"); |
| 2779 | | | return offset; |
| 2780 | | | } |
| 2781 | | | |
| 2782 | | | |
| 2783 | | | offset=get_ber_identifier(tvb, offset, &class, &pc, &tag); |
| 2784 | | | offset=get_ber_length(tvb, offset, &len, &ind); |
| 2785 | | | end_offset = offset + len ; |
| 2786 | | | |
| 2787 | | | |
| 2788 | | | |
| 2789 | | | |
| 2790 | | | if(hf_id >= 0){ |
Event 2:
Skipping " if". hf_id >= 0 evaluates to false.
hide
|
|
| 2791 | | | hfinfo=proto_registrar_get_nth(hf_id); |
| 2792 | | | switch(hfinfo->type) { |
| 2793 | | | case FT_UINT8: |
| 2794 | | | case FT_UINT16: |
| 2795 | | | case FT_UINT24: |
| 2796 | | | case FT_UINT32: |
| 2797 | | | break; |
| 2798 | | | default: |
| 2799 | | | proto_tree_add_text(tree, tvb, offset, len,"dissect_ber_old_choice(): Was passed a HF field that was not integer type : %s",hfinfo->abbrev); |
| 2800 | | | fprintf(stderr,"dissect_ber_old_choice(): frame:%u offset:%d Was passed a HF field that was not integer type : %s\n",actx->pinfo->fd->num,offset,hfinfo->abbrev); |
| 2801 | | | return end_offset; |
| 2802 | | | } |
| 2803 | | | } |
| 2804 | | | |
| 2805 | | | |
| 2806 | | | |
| 2807 | | | |
| 2808 | | | |
| 2809 | | | ch = choice; |
| 2810 | | | if(branch_taken){ |
Event 3:
Taking true branch. branch_taken evaluates to true.
hide
|
|
| 2811 | | | *branch_taken=-1; |
| 2812 | | | } |
| 2813 | | | first_pass = TRUE; |
Event 4:
!0 evaluates to true.
hide
|
|
| 2814 | | | while(ch->func || first_pass){ |
| 2815 | | | if(branch_taken){ |
Event 6:
Taking true branch. branch_taken evaluates to true.
hide
|
|
| 2816 | | | (*branch_taken)++; |
| 2817 | | | } |
| 2818 | | | |
| 2819 | | | if(!ch->func) { |
Event 8:
Taking true branch. ch->func evaluates to false.
hide
|
|
| 2820 | | | first_pass = FALSE; |
| 2821 | | | ch = choice; |
| 2822 | | | 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:2816, 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 7. Show: All events | Only primary events |
|
| 2823 | | | *branch_taken=-1; |
| 2824 | | | } |
| 2825 | | | } |
| 2826 | | | |
| 2827 | | | choice_try_again: |
| 2828 | | | #ifdef DEBUG_BER_CHOICE |
| 2829 | | | 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); |
| 2830 | | | #endif |
| 2831 | | | if( (first_pass && (((ch->class==class)&&(ch->tag==tag)) |
| 2832 | | | || ((ch->class==class)&&(ch->tag==-1)&&(ch->flags&BER_FLAGS_NOOWNTAG)))) || |
| 2833 | | | (!first_pass && (((ch->class == BER_CLASS_ANY) && (ch->tag == -1)))) |
| 2834 | | | ){ |
| 2835 | | | if(!(ch->flags & BER_FLAGS_NOOWNTAG)){ |
| 2836 | | | |
| 2837 | | | hoffset = dissect_ber_identifier(actx->pinfo, tree, tvb, start_offset, NULL, NULL, NULL); |
| 2838 | | | hoffset = dissect_ber_length(actx->pinfo, tree, tvb, hoffset, NULL, NULL); |
| 2839 | | | start_offset=hoffset; |
| 2840 | | | if (ind) |
| 2841 | | | { |
| 2842 | | | length = len-2; |
| 2843 | | | } |
| 2844 | | | else |
| 2845 | | | { |
| 2846 | | | length = len; |
| 2847 | | | } |
| 2848 | | | } |
| 2849 | | | else |
| 2850 | | | length = end_offset- hoffset; |
| 2851 | | | |
| 2852 | | | if(hf_id >= 0){ |
| 2853 | | | if(parent_tree){ |
| 2854 | | | item = proto_tree_add_uint(parent_tree, hf_id, tvb, hoffset, end_offset - hoffset, ch->value); |
| 2855 | | | tree = proto_item_add_subtree(item, ett_id); |
| 2856 | | | } |
| 2857 | | | } |
| 2858 | | | |
| 2859 | | | length_remaining=tvb_length_remaining(tvb, hoffset); |
| 2860 | | | if(length_remaining>length) |
| 2861 | | | length_remaining=length; |
| 2862 | | | |
| 2863 | | | #ifdef REMOVED |
| 2864 | | | |
| 2865 | | | |
| 2866 | | | |
| 2867 | | | |
| 2868 | | | |
| 2869 | | | |
| 2870 | | | |
| 2871 | | | |
| 2872 | | | if(first_pass) |
| 2873 | | | next_tvb=tvb_new_subset(tvb, hoffset, length_remaining, length); |
| 2874 | | | else |
| 2875 | | | next_tvb = tvb; |
| 2876 | | | #endif |
| 2877 | | | next_tvb=tvb_new_subset(tvb, hoffset, length_remaining, length); |
| 2878 | | | |
| 2879 | | | |
| 2880 | | | #ifdef DEBUG_BER_CHOICE |
| 2881 | | | { |
| 2882 | | | const char *name; |
| 2883 | | | *hfinfo; |
| 2884 | | | if(hf_id>=0){ |
| 2885 | | | hfinfo = proto_registrar_get_nth(hf_id); |
| 2886 | | | name=hfinfo->name; |
| 2887 | | | } else { |
| 2888 | | | name="unnamed"; |
| 2889 | | | } |
| 2890 | | | if(tvb_length_remaining(next_tvb,0)>3){ |
| 2891 | | | printf("CHOICE dissect_ber_old_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)); |
| 2892 | | | }else{ |
| 2893 | | | printf("CHOICE dissect_ber_old_choice(%s) calling subdissector len:%d\n",name,tvb_length(next_tvb)); |
| 2894 | | | } |
| 2895 | | | } |
| 2896 | | | #endif |
| 2897 | | | if (next_tvb == NULL) { |
| 2898 | | | |
| 2899 | | | 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) |
| |
|
| 2900 | | | } |
| 2901 | | | count=ch->func(tree, next_tvb, 0, actx); |
| 2902 | | | #ifdef DEBUG_BER_CHOICE |
| 2903 | | | { |
| 2904 | | | const char *name; |
| 2905 | | | *hfinfo; |
| 2906 | | | if(hf_id>=0){ |
| 2907 | | | hfinfo = proto_registrar_get_nth(hf_id); |
| 2908 | | | name=hfinfo->name; |
| 2909 | | | } else { |
| 2910 | | | name="unnamed"; |
| 2911 | | | } |
| 2912 | | | printf("CHOICE dissect_ber_old_choice(%s) subdissector ate %d bytes\n",name,count); |
| 2913 | | | } |
| 2914 | | | #endif |
| 2915 | | | if((count==0)&&(((ch->class==class)&&(ch->tag==-1)&&(ch->flags&BER_FLAGS_NOOWNTAG)) || !first_pass)){ |
| 2916 | | | |
| 2917 | | | ch++; |
| 2918 | | | #ifdef DEBUG_BER_CHOICE |
| 2919 | | | { |
| 2920 | | | const char *name; |
| 2921 | | | *hfinfo; |
| 2922 | | | if(hf_id>=0){ |
| 2923 | | | hfinfo = proto_registrar_get_nth(hf_id); |
| 2924 | | | name=hfinfo->name; |
| 2925 | | | } else { |
| 2926 | | | name="unnamed"; |
| 2927 | | | } |
| 2928 | | | printf("CHOICE dissect_ber_old_choice(%s) trying again\n",name); |
| 2929 | | | } |
| 2930 | | | #endif |
| 2931 | | | goto choice_try_again; |
| 2932 | | | } |
| 2933 | | | if(!(ch->flags & BER_FLAGS_NOOWNTAG)){ |
| 2934 | | | if(ind) |
| 2935 | | | { |
| 2936 | | | |
| 2937 | | | |
| 2938 | | | if(show_internal_ber_fields){ |
| 2939 | | | proto_tree_add_text(tree, tvb, start_offset, count+2, "CHOICE EOC"); |
| 2940 | | | } |
| 2941 | | | } |
| 2942 | | | } |
| 2943 | | | return end_offset; |
| 2944 | | | } |
| 2945 | | | ch++; |
| 2946 | | | } |
| 2947 | | | if(branch_taken){ |
| 2948 | | | |
| 2949 | | | |
| 2950 | | | *branch_taken=-1; |
| 2951 | | | } |
| 2952 | | | |
| 2953 | | | #ifdef REMOVED |
| 2954 | | | |
| 2955 | | | |
| 2956 | | | |
| 2957 | | | |
| 2958 | | | |
| 2959 | | | |
| 2960 | | | cause = proto_tree_add_text(tree, tvb, offset, len, "BER Error: This choice field was not found."); |
| 2961 | | | proto_item_set_expert_flags(cause, PI_MALFORMED, PI_WARN); |
| 2962 | | | expert_add_info_format(actx->pinfo, cause, PI_MALFORMED, PI_WARN, "BER Error: This choice field was not found"); |
| 2963 | | | return end_offset; |
| 2964 | | | #endif |
| 2965 | | | |
| 2966 | | | return start_offset; |
| 2967 | | | } |
| |