aboutsummaryrefslogtreecommitdiffstats
path: root/net/x25/af_x25.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/x25/af_x25.c')
-rw-r--r--net/x25/af_x25.c68
1 files changed, 63 insertions, 5 deletions
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 9796f3ed1edb..cbddd0cb83f1 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -47,6 +47,7 @@
47#include <linux/netdevice.h> 47#include <linux/netdevice.h>
48#include <linux/if_arp.h> 48#include <linux/if_arp.h>
49#include <linux/skbuff.h> 49#include <linux/skbuff.h>
50#include <linux/slab.h>
50#include <net/sock.h> 51#include <net/sock.h>
51#include <net/tcp_states.h> 52#include <net/tcp_states.h>
52#include <asm/uaccess.h> 53#include <asm/uaccess.h>
@@ -82,6 +83,41 @@ struct compat_x25_subscrip_struct {
82}; 83};
83#endif 84#endif
84 85
86
87int x25_parse_address_block(struct sk_buff *skb,
88 struct x25_address *called_addr,
89 struct x25_address *calling_addr)
90{
91 unsigned char len;
92 int needed;
93 int rc;
94
95 if (skb->len < 1) {
96 /* packet has no address block */
97 rc = 0;
98 goto empty;
99 }
100
101 len = *skb->data;
102 needed = 1 + (len >> 4) + (len & 0x0f);
103
104 if (skb->len < needed) {
105 /* packet is too short to hold the addresses it claims
106 to hold */
107 rc = -1;
108 goto empty;
109 }
110
111 return x25_addr_ntoa(skb->data, called_addr, calling_addr);
112
113empty:
114 *called_addr->x25_addr = 0;
115 *calling_addr->x25_addr = 0;
116
117 return rc;
118}
119
120
85int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr, 121int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr,
86 struct x25_address *calling_addr) 122 struct x25_address *calling_addr)
87{ 123{
@@ -553,7 +589,8 @@ static int x25_create(struct net *net, struct socket *sock, int protocol,
553 x25->facilities.winsize_out = X25_DEFAULT_WINDOW_SIZE; 589 x25->facilities.winsize_out = X25_DEFAULT_WINDOW_SIZE;
554 x25->facilities.pacsize_in = X25_DEFAULT_PACKET_SIZE; 590 x25->facilities.pacsize_in = X25_DEFAULT_PACKET_SIZE;
555 x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE; 591 x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE;
556 x25->facilities.throughput = X25_DEFAULT_THROUGHPUT; 592 x25->facilities.throughput = 0; /* by default don't negotiate
593 throughput */
557 x25->facilities.reverse = X25_DEFAULT_REVERSE; 594 x25->facilities.reverse = X25_DEFAULT_REVERSE;
558 x25->dte_facilities.calling_len = 0; 595 x25->dte_facilities.calling_len = 0;
559 x25->dte_facilities.called_len = 0; 596 x25->dte_facilities.called_len = 0;
@@ -921,16 +958,26 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
921 /* 958 /*
922 * Extract the X.25 addresses and convert them to ASCII strings, 959 * Extract the X.25 addresses and convert them to ASCII strings,
923 * and remove them. 960 * and remove them.
961 *
962 * Address block is mandatory in call request packets
924 */ 963 */
925 addr_len = x25_addr_ntoa(skb->data, &source_addr, &dest_addr); 964 addr_len = x25_parse_address_block(skb, &source_addr, &dest_addr);
965 if (addr_len <= 0)
966 goto out_clear_request;
926 skb_pull(skb, addr_len); 967 skb_pull(skb, addr_len);
927 968
928 /* 969 /*
929 * Get the length of the facilities, skip past them for the moment 970 * Get the length of the facilities, skip past them for the moment
930 * get the call user data because this is needed to determine 971 * get the call user data because this is needed to determine
931 * the correct listener 972 * the correct listener
973 *
974 * Facilities length is mandatory in call request packets
932 */ 975 */
976 if (skb->len < 1)
977 goto out_clear_request;
933 len = skb->data[0] + 1; 978 len = skb->data[0] + 1;
979 if (skb->len < len)
980 goto out_clear_request;
934 skb_pull(skb,len); 981 skb_pull(skb,len);
935 982
936 /* 983 /*
@@ -1414,9 +1461,20 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1414 if (facilities.winsize_in < 1 || 1461 if (facilities.winsize_in < 1 ||
1415 facilities.winsize_in > 127) 1462 facilities.winsize_in > 127)
1416 break; 1463 break;
1417 if (facilities.throughput < 0x03 || 1464 if (facilities.throughput) {
1418 facilities.throughput > 0xDD) 1465 int out = facilities.throughput & 0xf0;
1419 break; 1466 int in = facilities.throughput & 0x0f;
1467 if (!out)
1468 facilities.throughput |=
1469 X25_DEFAULT_THROUGHPUT << 4;
1470 else if (out < 0x30 || out > 0xD0)
1471 break;
1472 if (!in)
1473 facilities.throughput |=
1474 X25_DEFAULT_THROUGHPUT;
1475 else if (in < 0x03 || in > 0x0D)
1476 break;
1477 }
1420 if (facilities.reverse && 1478 if (facilities.reverse &&
1421 (facilities.reverse & 0x81) != 0x81) 1479 (facilities.reverse & 0x81) != 0x81)
1422 break; 1480 break;