diff options
Diffstat (limited to 'net/x25/af_x25.c')
| -rw-r--r-- | net/x25/af_x25.c | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 9796f3ed1edb..fe26c01ef3e6 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c | |||
| @@ -82,6 +82,41 @@ struct compat_x25_subscrip_struct { | |||
| 82 | }; | 82 | }; |
| 83 | #endif | 83 | #endif |
| 84 | 84 | ||
| 85 | |||
| 86 | int x25_parse_address_block(struct sk_buff *skb, | ||
| 87 | struct x25_address *called_addr, | ||
| 88 | struct x25_address *calling_addr) | ||
| 89 | { | ||
| 90 | unsigned char len; | ||
| 91 | int needed; | ||
| 92 | int rc; | ||
| 93 | |||
| 94 | if (skb->len < 1) { | ||
| 95 | /* packet has no address block */ | ||
| 96 | rc = 0; | ||
| 97 | goto empty; | ||
| 98 | } | ||
| 99 | |||
| 100 | len = *skb->data; | ||
| 101 | needed = 1 + (len >> 4) + (len & 0x0f); | ||
| 102 | |||
| 103 | if (skb->len < needed) { | ||
| 104 | /* packet is too short to hold the addresses it claims | ||
| 105 | to hold */ | ||
| 106 | rc = -1; | ||
| 107 | goto empty; | ||
| 108 | } | ||
| 109 | |||
| 110 | return x25_addr_ntoa(skb->data, called_addr, calling_addr); | ||
| 111 | |||
| 112 | empty: | ||
| 113 | *called_addr->x25_addr = 0; | ||
| 114 | *calling_addr->x25_addr = 0; | ||
| 115 | |||
| 116 | return rc; | ||
| 117 | } | ||
| 118 | |||
| 119 | |||
| 85 | int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr, | 120 | int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr, |
| 86 | struct x25_address *calling_addr) | 121 | struct x25_address *calling_addr) |
| 87 | { | 122 | { |
| @@ -921,16 +956,26 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, | |||
| 921 | /* | 956 | /* |
| 922 | * Extract the X.25 addresses and convert them to ASCII strings, | 957 | * Extract the X.25 addresses and convert them to ASCII strings, |
| 923 | * and remove them. | 958 | * and remove them. |
| 959 | * | ||
| 960 | * Address block is mandatory in call request packets | ||
| 924 | */ | 961 | */ |
| 925 | addr_len = x25_addr_ntoa(skb->data, &source_addr, &dest_addr); | 962 | addr_len = x25_parse_address_block(skb, &source_addr, &dest_addr); |
| 963 | if (addr_len <= 0) | ||
| 964 | goto out_clear_request; | ||
| 926 | skb_pull(skb, addr_len); | 965 | skb_pull(skb, addr_len); |
| 927 | 966 | ||
| 928 | /* | 967 | /* |
| 929 | * Get the length of the facilities, skip past them for the moment | 968 | * Get the length of the facilities, skip past them for the moment |
| 930 | * get the call user data because this is needed to determine | 969 | * get the call user data because this is needed to determine |
| 931 | * the correct listener | 970 | * the correct listener |
| 971 | * | ||
| 972 | * Facilities length is mandatory in call request packets | ||
| 932 | */ | 973 | */ |
| 974 | if (skb->len < 1) | ||
| 975 | goto out_clear_request; | ||
| 933 | len = skb->data[0] + 1; | 976 | len = skb->data[0] + 1; |
| 977 | if (skb->len < len) | ||
| 978 | goto out_clear_request; | ||
| 934 | skb_pull(skb,len); | 979 | skb_pull(skb,len); |
| 935 | 980 | ||
| 936 | /* | 981 | /* |
