aboutsummaryrefslogtreecommitdiffstats
path: root/net/x25/af_x25.c
diff options
context:
space:
mode:
authorJohn Hughes <john@calva.com>2010-04-08 00:29:25 -0400
committerDavid S. Miller <davem@davemloft.net>2010-04-08 00:29:25 -0400
commitf5eb917b861828da18dc28854308068c66d1449a (patch)
treeaa45d1a809abbe426b55dc89b8167e5a6609d418 /net/x25/af_x25.c
parentfd218cf9557b9bf7061365a8fe7020a56d3f767c (diff)
x25: Patch to fix bug 15678 - x25 accesses fields beyond end of packet.
Here is a patch to stop X.25 examining fields beyond the end of the packet. For example, when a simple CALL ACCEPTED was received: 10 10 0f x25_parse_facilities was attempting to decode the FACILITIES field, but this packet contains no facilities field. Signed-off-by: John Hughes <john@calva.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/x25/af_x25.c')
-rw-r--r--net/x25/af_x25.c47
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
86int 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
112empty:
113 *called_addr->x25_addr = 0;
114 *calling_addr->x25_addr = 0;
115
116 return rc;
117}
118
119
85int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr, 120int 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 /*