(/home/sate/Testcases/c/cve/wireshark-1.2.0/plugins/irda/packet-irda.c) |
| |
| 675 | | | static void dissect_iap_result(tvbuff_t* tvb, packet_info* pinfo, proto_tree* root) |
| 676 | | | { |
| 677 | | | unsigned offset = 0; |
| 678 | | | unsigned len = tvb_length(tvb); |
| 679 | | | unsigned n = 0; |
| 680 | | | unsigned list_len; |
| 681 | | | guint8 op; |
| 682 | | | guint8 retcode; |
| 683 | | | guint8 type; |
| 684 | | | guint16 attr_len; |
| 685 | | | char buf[300]; |
| 686 | | | guint8 src; |
| 687 | | | address srcaddr; |
| 688 | | | address destaddr; |
| 689 | | | conversation_t* conv; |
| 690 | | | iap_conversation_t* cur_iap_conv; |
| 691 | | | iap_conversation_t* iap_conv = NULL; |
| 692 | | | guint32 num; |
| 693 | | | |
| 694 | | | |
| 695 | | | if (tvb_length(tvb) == 0) |
Event 1:
Skipping " if". tvb_length(tvb) == 0 evaluates to false.
hide
|
|
| 696 | | | return; |
| 697 | | | |
| 698 | | | |
| 699 | | | if (check_col(pinfo->cinfo, COL_PROTOCOL)) |
Event 2:
Skipping " if". check_col(...) evaluates to false.
hide
|
|
| 700 | | | col_set_str(pinfo->cinfo, COL_PROTOCOL, "IAP"); |
| 701 | | | |
| 702 | | | op = tvb_get_guint8(tvb, offset) & IAP_OP; |
| 703 | | | retcode = tvb_get_guint8(tvb, offset + 1); |
| 704 | | | |
| 705 | | | src = pinfo->circuit_id ^ CMD_FRAME; |
| 706 | | | srcaddr.type = AT_NONE; |
| 707 | | | srcaddr.len = 1; |
| 708 | | | srcaddr.data = (guint8*)&src; |
| 709 | | | |
| 710 | | | destaddr.type = AT_NONE; |
| 711 | | | destaddr.len = 1; |
| 712 | | | destaddr.data = (guint8*)&pinfo->circuit_id; |
| 713 | | | |
| 714 | | | |
| 715 | | | conv = find_conversation(pinfo->fd->num, &srcaddr, &destaddr, PT_NONE, pinfo->srcport, pinfo->destport, 0); |
| 716 | | | if (conv) |
Event 3:
Taking true branch. conv evaluates to true.
hide
|
|
| 717 | | | { |
| 718 | | | num = pinfo->fd->num; |
| 719 | | | |
| 720 | | | iap_conv = (iap_conversation_t*)conversation_get_proto_data(conv, proto_iap); |
| 721 | | | while (iap_conv && (iap_conv->iap_query_frame >= num)) |
| 722 | | | iap_conv = iap_conv->pnext; |
| 723 | | | |
| 724 | | | if (iap_conv) |
Event 5:
Taking true branch. iap_conv evaluates to true.
hide
|
|
| 725 | | | { |
| 726 | | | cur_iap_conv = iap_conv->pnext; |
| 727 | | | while (cur_iap_conv) |
Event 7:
Leaving loop. cur_iap_conv evaluates to false.
hide
|
|
| 728 | | | { |
| 729 | | | if ((cur_iap_conv->iap_query_frame < num) && |
| 730 | | | (cur_iap_conv->iap_query_frame > iap_conv->iap_query_frame)) |
| 731 | | | { |
| 732 | | | iap_conv = cur_iap_conv; |
| 733 | | | } |
| 734 | | | |
| 735 | | | cur_iap_conv = cur_iap_conv->pnext; |
| 736 | | | } |
| 737 | | | } |
| 738 | | | } |
| 739 | | | |
| 740 | | | if (check_col(pinfo->cinfo, COL_INFO)) |
Event 8:
Skipping " if". check_col(...) evaluates to false.
hide
|
|
| 741 | | | { |
| 742 | | | col_add_str(pinfo->cinfo, COL_INFO, "Result: "); |
| 743 | | | col_append_str(pinfo->cinfo, COL_INFO, val_to_str(retcode, iap_return_vals, "0x%02X")); |
| 744 | | | |
| 745 | | | switch (op) |
| 746 | | | { |
| 747 | | | case GET_VALUE_BY_CLASS: |
| 748 | | | if (retcode == 0) |
| 749 | | | { |
| 750 | | | guint8 *string; |
| 751 | | | switch (tvb_get_guint8(tvb, offset + 6)) |
| 752 | | | { |
| 753 | | | case IAS_MISSING: |
| 754 | | | g_snprintf(buf, 300, ", Missing"); |
| 755 | | | break; |
| 756 | | | |
| 757 | | | case IAS_INTEGER: |
| 758 | | | g_snprintf(buf, 300, ", Integer: %d", tvb_get_ntohl(tvb, offset + 7)); |
| 759 | | | break; |
| 760 | | | |
| 761 | | | case IAS_OCT_SEQ: |
| 762 | | | g_snprintf(buf, 300, ", %d Octets", tvb_get_ntohs(tvb, offset + 7)); |
| 763 | | | break; |
| 764 | | | |
| 765 | | | case IAS_STRING: |
| 766 | | | n = tvb_get_guint8(tvb, offset + 8); |
| 767 | | | string = tvb_get_ephemeral_string(tvb, offset + 9, n); |
| 768 | | | g_snprintf(buf, 300, ", \"%s\"", string); |
| 769 | | | break; |
| 770 | | | } |
| 771 | | | col_append_str(pinfo->cinfo, COL_INFO, buf); |
| 772 | | | if (tvb_get_ntohs(tvb, offset + 2) > 1) |
| 773 | | | col_append_str(pinfo->cinfo, COL_INFO, ", ..."); |
| 774 | | | } |
| 775 | | | break; |
| 776 | | | } |
| 777 | | | } |
| 778 | | | |
| 779 | | | if (root) |
Event 9:
Taking true branch. root evaluates to true.
hide
|
|
| 780 | | | { |
| 781 | | | |
| 782 | | | proto_item* ti = proto_tree_add_item(root, proto_iap, tvb, 0, -1, FALSE); |
| 783 | | | proto_tree* tree = proto_item_add_subtree(ti, ett_iap); |
| 784 | | | |
| 785 | | | proto_tree* ctl_tree; |
| 786 | | | proto_tree* entry_tree; |
| 787 | | | |
| 788 | | | |
| 789 | | | ti = proto_tree_add_item(tree, hf_iap_ctl, tvb, offset, 1, FALSE); |
| 790 | | | ctl_tree = proto_item_add_subtree(ti, ett_iap_ctl); |
| 791 | | | proto_tree_add_item(ctl_tree, hf_iap_ctl_lst, tvb, offset, 1, FALSE); |
| 792 | | | proto_tree_add_item(ctl_tree, hf_iap_ctl_ack, tvb, offset, 1, FALSE); |
| 793 | | | proto_tree_add_item(ctl_tree, hf_iap_ctl_opcode, tvb, offset, 1, FALSE); |
| 794 | | | offset++; |
| 795 | | | |
| 796 | | | proto_tree_add_item(tree, hf_iap_return, tvb, offset, 1, FALSE); |
| 797 | | | offset++; |
| 798 | | | |
| 799 | | | switch (op) |
Event 10:
op evaluates to 4.
hide
|
|
| 800 | | | { |
| 801 | | | case GET_VALUE_BY_CLASS: |
| 802 | | | if (retcode == 0) |
Event 11:
Taking true branch. retcode == 0 evaluates to true.
hide
|
|
| 803 | | | { |
| 804 | | | list_len = tvb_get_ntohs(tvb, offset); |
| 805 | | | |
| 806 | | | proto_tree_add_item(tree, hf_iap_list_len, tvb, offset, 2, FALSE); |
| 807 | | | offset += 2; |
| 808 | | | |
| 809 | | | while ((offset < len) && (n < list_len)) |
| 810 | | | { |
| 811 | | | type = tvb_get_guint8(tvb, offset + 2); |
| 812 | | | switch (type) |
Event 13:
type evaluates to 1.
hide
|
|
| 813 | | | { |
| 814 | | | case IAS_INTEGER: |
| 815 | | | attr_len = 4; |
| 816 | | | break; |
| 817 | | | |
| 818 | | | case IAS_OCT_SEQ: |
| 819 | | | attr_len = tvb_get_ntohs(tvb, offset + 2 + 1) + 2; |
| 820 | | | break; |
| 821 | | | |
| 822 | | | case IAS_STRING: |
| 823 | | | attr_len = tvb_get_guint8(tvb, offset + 2 + 1 + 1) + 2; |
| 824 | | | break; |
| 825 | | | |
| 826 | | | default: |
| 827 | | | attr_len = 0; |
| 828 | | | } |
| 829 | | | |
| 830 | | | ti = proto_tree_add_item(tree, hf_iap_list_entry, tvb, offset, 2 + 1 + attr_len, FALSE); |
| 831 | | | proto_item_append_text(ti, "%d", n + 1); |
| 832 | | | entry_tree = proto_item_add_subtree(ti, ett_iap_entry[n]); |
| 833 | | | |
| 834 | | | proto_tree_add_item(entry_tree, hf_iap_obj_id, tvb, offset, 2, FALSE); |
| 835 | | | offset += 2; |
| 836 | | | |
| 837 | | | proto_tree_add_item(entry_tree, hf_iap_attr_type, tvb, offset, 1, FALSE); |
| 838 | | | offset++; |
| 839 | | | |
| 840 | | | switch (type) |
Event 14:
type evaluates to 1.
hide
|
|
| 841 | | | { |
| 842 | | | case IAS_INTEGER: |
| 843 | | | if (!iap_conv || !iap_conv->pattr_dissector || |
Null Test After Dereference
This code tests the nullness of iap_conv, which has already been dereferenced. - If iap_conv were null, there would have been a prior null pointer dereference at packet-irda.c:726, 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 6. Show: All events | Only primary events |
|
| 844 | | | !iap_conv->pattr_dissector->value_dissector(tvb, offset, pinfo, entry_tree, |
| 845 | | | n, type)) |
| 846 | | | proto_tree_add_item(entry_tree, hf_iap_int, tvb, offset, 4, FALSE); |
| 847 | | | break; |
| 848 | | | |
| 849 | | | case IAS_OCT_SEQ: |
| 850 | | | proto_tree_add_item(entry_tree, hf_iap_seq_len, tvb, offset, 2, FALSE); |
| 851 | | | if (!iap_conv || !iap_conv->pattr_dissector || |
| 852 | | | !iap_conv->pattr_dissector->value_dissector(tvb, offset, pinfo, entry_tree, |
| 853 | | | n, type)) |
| 854 | | | proto_tree_add_item(entry_tree, hf_iap_oct_seq, tvb, offset + 2, |
| 855 | | | attr_len - 2, FALSE); |
| 856 | | | break; |
| 857 | | | |
| 858 | | | case IAS_STRING: |
| 859 | | | proto_tree_add_item(entry_tree, hf_iap_char_set, tvb, offset, 1, FALSE); |
| 860 | | | if (!iap_conv || !iap_conv->pattr_dissector || |
| 861 | | | !iap_conv->pattr_dissector->value_dissector(tvb, offset, pinfo, entry_tree, |
| 862 | | | n, type)) |
| 863 | | | proto_tree_add_item(entry_tree, hf_iap_string, tvb, offset + 1, 1, FALSE); |
| 864 | | | break; |
| 865 | | | } |
| 866 | | | offset += attr_len; |
| 867 | | | |
| 868 | | | n++; |
| 869 | | | } |
| 870 | | | } |
| 871 | | | break; |
| 872 | | | } |
| 873 | | | } |
| 874 | | | else |
| 875 | | | { |
| 876 | | | offset += 2; |
| 877 | | | switch (op) |
| 878 | | | { |
| 879 | | | case GET_VALUE_BY_CLASS: |
| 880 | | | if (retcode == 0) |
| 881 | | | { |
| 882 | | | offset += 2; |
| 883 | | | |
| 884 | | | while (offset < len) |
| 885 | | | { |
| 886 | | | offset += 2; |
| 887 | | | type = tvb_get_guint8(tvb, offset); |
| 888 | | | offset++; |
| 889 | | | |
| 890 | | | switch (type) |
| 891 | | | { |
| 892 | | | case IAS_INTEGER: |
| 893 | | | attr_len = 4; |
| 894 | | | if (iap_conv && iap_conv->pattr_dissector) |
| 895 | | | iap_conv->pattr_dissector->value_dissector(tvb, offset, pinfo, 0, |
| 896 | | | n, type); |
| 897 | | | break; |
| 898 | | | |
| 899 | | | case IAS_OCT_SEQ: |
| 900 | | | attr_len = tvb_get_ntohs(tvb, offset) + 2; |
| 901 | | | if (iap_conv && iap_conv->pattr_dissector) |
| 902 | | | iap_conv->pattr_dissector->value_dissector(tvb, offset, pinfo, 0, |
| 903 | | | n, type); |
| 904 | | | break; |
| 905 | | | |
| 906 | | | case IAS_STRING: |
| 907 | | | attr_len = tvb_get_guint8(tvb, offset + 1) + 2; |
| 908 | | | if (iap_conv && iap_conv->pattr_dissector) |
| 909 | | | iap_conv->pattr_dissector->value_dissector(tvb, offset, pinfo, 0, |
| 910 | | | n, type); |
| 911 | | | |
| 912 | | | default: |
| 913 | | | attr_len = 0; |
| 914 | | | } |
| 915 | | | offset += attr_len; |
| 916 | | | |
| 917 | | | n++; |
| 918 | | | } |
| 919 | | | } |
| 920 | | | break; |
| 921 | | | } |
| 922 | | | } |
| 923 | | | |
| 924 | | | |
| 925 | | | tvb = tvb_new_subset(tvb, offset, -1, -1); |
| 926 | | | call_dissector(data_handle, tvb, pinfo, root); |
| 927 | | | } |
| |