diff options
Diffstat (limited to 'net/x25/x25_in.c')
| -rw-r--r-- | net/x25/x25_in.c | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/net/x25/x25_in.c b/net/x25/x25_in.c index 0b073b51b183..a49cd4ec551a 100644 --- a/net/x25/x25_in.c +++ b/net/x25/x25_in.c | |||
| @@ -107,6 +107,8 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp | |||
| 107 | /* | 107 | /* |
| 108 | * Parse the data in the frame. | 108 | * Parse the data in the frame. |
| 109 | */ | 109 | */ |
| 110 | if (!pskb_may_pull(skb, X25_STD_MIN_LEN)) | ||
| 111 | goto out_clear; | ||
| 110 | skb_pull(skb, X25_STD_MIN_LEN); | 112 | skb_pull(skb, X25_STD_MIN_LEN); |
| 111 | 113 | ||
| 112 | len = x25_parse_address_block(skb, &source_addr, | 114 | len = x25_parse_address_block(skb, &source_addr, |
| @@ -127,9 +129,11 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp | |||
| 127 | * Copy any Call User Data. | 129 | * Copy any Call User Data. |
| 128 | */ | 130 | */ |
| 129 | if (skb->len > 0) { | 131 | if (skb->len > 0) { |
| 130 | skb_copy_from_linear_data(skb, | 132 | if (skb->len > X25_MAX_CUD_LEN) |
| 131 | x25->calluserdata.cuddata, | 133 | goto out_clear; |
| 132 | skb->len); | 134 | |
| 135 | skb_copy_bits(skb, 0, x25->calluserdata.cuddata, | ||
| 136 | skb->len); | ||
| 133 | x25->calluserdata.cudlength = skb->len; | 137 | x25->calluserdata.cudlength = skb->len; |
| 134 | } | 138 | } |
| 135 | if (!sock_flag(sk, SOCK_DEAD)) | 139 | if (!sock_flag(sk, SOCK_DEAD)) |
| @@ -137,6 +141,9 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp | |||
| 137 | break; | 141 | break; |
| 138 | } | 142 | } |
| 139 | case X25_CLEAR_REQUEST: | 143 | case X25_CLEAR_REQUEST: |
| 144 | if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2)) | ||
| 145 | goto out_clear; | ||
| 146 | |||
| 140 | x25_write_internal(sk, X25_CLEAR_CONFIRMATION); | 147 | x25_write_internal(sk, X25_CLEAR_CONFIRMATION); |
| 141 | x25_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]); | 148 | x25_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]); |
| 142 | break; | 149 | break; |
| @@ -164,6 +171,9 @@ static int x25_state2_machine(struct sock *sk, struct sk_buff *skb, int frametyp | |||
| 164 | switch (frametype) { | 171 | switch (frametype) { |
| 165 | 172 | ||
| 166 | case X25_CLEAR_REQUEST: | 173 | case X25_CLEAR_REQUEST: |
| 174 | if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2)) | ||
| 175 | goto out_clear; | ||
| 176 | |||
| 167 | x25_write_internal(sk, X25_CLEAR_CONFIRMATION); | 177 | x25_write_internal(sk, X25_CLEAR_CONFIRMATION); |
| 168 | x25_disconnect(sk, 0, skb->data[3], skb->data[4]); | 178 | x25_disconnect(sk, 0, skb->data[3], skb->data[4]); |
| 169 | break; | 179 | break; |
| @@ -177,6 +187,11 @@ static int x25_state2_machine(struct sock *sk, struct sk_buff *skb, int frametyp | |||
| 177 | } | 187 | } |
| 178 | 188 | ||
| 179 | return 0; | 189 | return 0; |
| 190 | |||
| 191 | out_clear: | ||
| 192 | x25_write_internal(sk, X25_CLEAR_REQUEST); | ||
| 193 | x25_start_t23timer(sk); | ||
| 194 | return 0; | ||
| 180 | } | 195 | } |
| 181 | 196 | ||
| 182 | /* | 197 | /* |
| @@ -206,6 +221,9 @@ static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametyp | |||
| 206 | break; | 221 | break; |
| 207 | 222 | ||
| 208 | case X25_CLEAR_REQUEST: | 223 | case X25_CLEAR_REQUEST: |
| 224 | if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2)) | ||
| 225 | goto out_clear; | ||
| 226 | |||
| 209 | x25_write_internal(sk, X25_CLEAR_CONFIRMATION); | 227 | x25_write_internal(sk, X25_CLEAR_CONFIRMATION); |
| 210 | x25_disconnect(sk, 0, skb->data[3], skb->data[4]); | 228 | x25_disconnect(sk, 0, skb->data[3], skb->data[4]); |
| 211 | break; | 229 | break; |
| @@ -304,6 +322,12 @@ static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametyp | |||
| 304 | } | 322 | } |
| 305 | 323 | ||
| 306 | return queued; | 324 | return queued; |
| 325 | |||
| 326 | out_clear: | ||
| 327 | x25_write_internal(sk, X25_CLEAR_REQUEST); | ||
| 328 | x25->state = X25_STATE_2; | ||
| 329 | x25_start_t23timer(sk); | ||
| 330 | return 0; | ||
| 307 | } | 331 | } |
| 308 | 332 | ||
| 309 | /* | 333 | /* |
| @@ -313,13 +337,13 @@ static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametyp | |||
| 313 | */ | 337 | */ |
| 314 | static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametype) | 338 | static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametype) |
| 315 | { | 339 | { |
| 340 | struct x25_sock *x25 = x25_sk(sk); | ||
| 341 | |||
| 316 | switch (frametype) { | 342 | switch (frametype) { |
| 317 | 343 | ||
| 318 | case X25_RESET_REQUEST: | 344 | case X25_RESET_REQUEST: |
| 319 | x25_write_internal(sk, X25_RESET_CONFIRMATION); | 345 | x25_write_internal(sk, X25_RESET_CONFIRMATION); |
| 320 | case X25_RESET_CONFIRMATION: { | 346 | case X25_RESET_CONFIRMATION: { |
| 321 | struct x25_sock *x25 = x25_sk(sk); | ||
| 322 | |||
| 323 | x25_stop_timer(sk); | 347 | x25_stop_timer(sk); |
| 324 | x25->condition = 0x00; | 348 | x25->condition = 0x00; |
| 325 | x25->va = 0; | 349 | x25->va = 0; |
| @@ -331,6 +355,9 @@ static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametyp | |||
| 331 | break; | 355 | break; |
| 332 | } | 356 | } |
| 333 | case X25_CLEAR_REQUEST: | 357 | case X25_CLEAR_REQUEST: |
| 358 | if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2)) | ||
| 359 | goto out_clear; | ||
| 360 | |||
| 334 | x25_write_internal(sk, X25_CLEAR_CONFIRMATION); | 361 | x25_write_internal(sk, X25_CLEAR_CONFIRMATION); |
| 335 | x25_disconnect(sk, 0, skb->data[3], skb->data[4]); | 362 | x25_disconnect(sk, 0, skb->data[3], skb->data[4]); |
| 336 | break; | 363 | break; |
| @@ -340,6 +367,12 @@ static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametyp | |||
| 340 | } | 367 | } |
| 341 | 368 | ||
| 342 | return 0; | 369 | return 0; |
| 370 | |||
| 371 | out_clear: | ||
| 372 | x25_write_internal(sk, X25_CLEAR_REQUEST); | ||
| 373 | x25->state = X25_STATE_2; | ||
| 374 | x25_start_t23timer(sk); | ||
| 375 | return 0; | ||
| 343 | } | 376 | } |
| 344 | 377 | ||
| 345 | /* Higher level upcall for a LAPB frame */ | 378 | /* Higher level upcall for a LAPB frame */ |
