diff options
Diffstat (limited to 'net/x25/af_x25.c')
-rw-r--r-- | net/x25/af_x25.c | 31 |
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); |