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.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index a4bd1720e39b..aa567b09ea9a 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -91,7 +91,7 @@ int x25_parse_address_block(struct sk_buff *skb,
91 int needed; 91 int needed;
92 int rc; 92 int rc;
93 93
94 if (skb->len < 1) { 94 if (!pskb_may_pull(skb, 1)) {
95 /* packet has no address block */ 95 /* packet has no address block */
96 rc = 0; 96 rc = 0;
97 goto empty; 97 goto empty;
@@ -100,7 +100,7 @@ int x25_parse_address_block(struct sk_buff *skb,
100 len = *skb->data; 100 len = *skb->data;
101 needed = 1 + (len >> 4) + (len & 0x0f); 101 needed = 1 + (len >> 4) + (len & 0x0f);
102 102
103 if (skb->len < needed) { 103 if (!pskb_may_pull(skb, needed)) {
104 /* packet is too short to hold the addresses it claims 104 /* packet is too short to hold the addresses it claims
105 to hold */ 105 to hold */
106 rc = -1; 106 rc = -1;
@@ -951,10 +951,10 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
951 * 951 *
952 * Facilities length is mandatory in call request packets 952 * Facilities length is mandatory in call request packets
953 */ 953 */
954 if (skb->len < 1) 954 if (!pskb_may_pull(skb, 1))
955 goto out_clear_request; 955 goto out_clear_request;
956 len = skb->data[0] + 1; 956 len = skb->data[0] + 1;
957 if (skb->len < len) 957 if (!pskb_may_pull(skb, len))
958 goto out_clear_request; 958 goto out_clear_request;
959 skb_pull(skb,len); 959 skb_pull(skb,len);
960 960
@@ -965,6 +965,13 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
965 goto out_clear_request; 965 goto out_clear_request;
966 966
967 /* 967 /*
968 * Get all the call user data so it can be used in
969 * x25_find_listener and skb_copy_from_linear_data up ahead.
970 */
971 if (!pskb_may_pull(skb, skb->len))
972 goto out_clear_request;
973
974 /*
968 * Find a listener for the particular address/cud pair. 975 * Find a listener for the particular address/cud pair.
969 */ 976 */
970 sk = x25_find_listener(&source_addr,skb); 977 sk = x25_find_listener(&source_addr,skb);
@@ -1172,6 +1179,9 @@ static int x25_sendmsg(struct kiocb *iocb, struct socket *sock,
1172 * byte of the user data is the logical value of the Q Bit. 1179 * byte of the user data is the logical value of the Q Bit.
1173 */ 1180 */
1174 if (test_bit(X25_Q_BIT_FLAG, &x25->flags)) { 1181 if (test_bit(X25_Q_BIT_FLAG, &x25->flags)) {
1182 if (!pskb_may_pull(skb, 1))
1183 goto out_kfree_skb;
1184
1175 qbit = skb->data[0]; 1185 qbit = skb->data[0];
1176 skb_pull(skb, 1); 1186 skb_pull(skb, 1);
1177 } 1187 }
@@ -1250,7 +1260,9 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
1250 struct x25_sock *x25 = x25_sk(sk); 1260 struct x25_sock *x25 = x25_sk(sk);
1251 struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)msg->msg_name; 1261 struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)msg->msg_name;
1252 size_t copied; 1262 size_t copied;
1253 int qbit; 1263 int qbit, header_len = x25->neighbour->extended ?
1264 X25_EXT_MIN_LEN : X25_STD_MIN_LEN;
1265
1254 struct sk_buff *skb; 1266 struct sk_buff *skb;
1255 unsigned char *asmptr; 1267 unsigned char *asmptr;
1256 int rc = -ENOTCONN; 1268 int rc = -ENOTCONN;
@@ -1271,6 +1283,9 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
1271 1283
1272 skb = skb_dequeue(&x25->interrupt_in_queue); 1284 skb = skb_dequeue(&x25->interrupt_in_queue);
1273 1285
1286 if (!pskb_may_pull(skb, X25_STD_MIN_LEN))
1287 goto out_free_dgram;
1288
1274 skb_pull(skb, X25_STD_MIN_LEN); 1289 skb_pull(skb, X25_STD_MIN_LEN);
1275 1290
1276 /* 1291 /*
@@ -1291,10 +1306,12 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
1291 if (!skb) 1306 if (!skb)
1292 goto out; 1307 goto out;
1293 1308
1309 if (!pskb_may_pull(skb, header_len))
1310 goto out_free_dgram;
1311
1294 qbit = (skb->data[0] & X25_Q_BIT) == X25_Q_BIT; 1312 qbit = (skb->data[0] & X25_Q_BIT) == X25_Q_BIT;
1295 1313
1296 skb_pull(skb, x25->neighbour->extended ? 1314 skb_pull(skb, header_len);
1297 X25_EXT_MIN_LEN : X25_STD_MIN_LEN);
1298 1315
1299 if (test_bit(X25_Q_BIT_FLAG, &x25->flags)) { 1316 if (test_bit(X25_Q_BIT_FLAG, &x25->flags)) {
1300 asmptr = skb_push(skb, 1); 1317 asmptr = skb_push(skb, 1);