|
@@ -82,6 +82,41 @@ struct compat_x25_subscrip_struct {
|
|
|
};
|
|
|
#endif
|
|
|
|
|
|
+
|
|
|
+int x25_parse_address_block(struct sk_buff *skb,
|
|
|
+ struct x25_address *called_addr,
|
|
|
+ struct x25_address *calling_addr)
|
|
|
+{
|
|
|
+ unsigned char len;
|
|
|
+ int needed;
|
|
|
+ int rc;
|
|
|
+
|
|
|
+ if (skb->len < 1) {
|
|
|
+ /* packet has no address block */
|
|
|
+ rc = 0;
|
|
|
+ goto empty;
|
|
|
+ }
|
|
|
+
|
|
|
+ len = *skb->data;
|
|
|
+ needed = 1 + (len >> 4) + (len & 0x0f);
|
|
|
+
|
|
|
+ if (skb->len < needed) {
|
|
|
+ /* packet is too short to hold the addresses it claims
|
|
|
+ to hold */
|
|
|
+ rc = -1;
|
|
|
+ goto empty;
|
|
|
+ }
|
|
|
+
|
|
|
+ return x25_addr_ntoa(skb->data, called_addr, calling_addr);
|
|
|
+
|
|
|
+empty:
|
|
|
+ *called_addr->x25_addr = 0;
|
|
|
+ *calling_addr->x25_addr = 0;
|
|
|
+
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr,
|
|
|
struct x25_address *calling_addr)
|
|
|
{
|
|
@@ -921,16 +956,26 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
|
|
|
/*
|
|
|
* Extract the X.25 addresses and convert them to ASCII strings,
|
|
|
* and remove them.
|
|
|
+ *
|
|
|
+ * Address block is mandatory in call request packets
|
|
|
*/
|
|
|
- addr_len = x25_addr_ntoa(skb->data, &source_addr, &dest_addr);
|
|
|
+ addr_len = x25_parse_address_block(skb, &source_addr, &dest_addr);
|
|
|
+ if (addr_len <= 0)
|
|
|
+ goto out_clear_request;
|
|
|
skb_pull(skb, addr_len);
|
|
|
|
|
|
/*
|
|
|
* Get the length of the facilities, skip past them for the moment
|
|
|
* get the call user data because this is needed to determine
|
|
|
* the correct listener
|
|
|
+ *
|
|
|
+ * Facilities length is mandatory in call request packets
|
|
|
*/
|
|
|
+ if (skb->len < 1)
|
|
|
+ goto out_clear_request;
|
|
|
len = skb->data[0] + 1;
|
|
|
+ if (skb->len < len)
|
|
|
+ goto out_clear_request;
|
|
|
skb_pull(skb,len);
|
|
|
|
|
|
/*
|