aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2006-09-20 15:09:51 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-09-22 18:20:14 -0400
commita1073406a124c1d3b33a0f06bfb8078a9ddd1985 (patch)
treef00172adc188074a998d39df64f258c1048d6f73 /net
parentcf9f81523ef3e95d9f222c896d266e4562999150 (diff)
[NETFILTER]: PPTP conntrack: consolidate header size checks
Also make sure not to pass undersized messages to the NAT helper. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/netfilter/ip_conntrack_helper_pptp.c65
1 files changed, 22 insertions, 43 deletions
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_pptp.c b/net/ipv4/netfilter/ip_conntrack_helper_pptp.c
index 57eac6e3871a..3b5464fa4217 100644
--- a/net/ipv4/netfilter/ip_conntrack_helper_pptp.c
+++ b/net/ipv4/netfilter/ip_conntrack_helper_pptp.c
@@ -291,6 +291,22 @@ out_unexpect_orig:
291 goto out_put_both; 291 goto out_put_both;
292} 292}
293 293
294static const unsigned int pptp_msg_size[] = {
295 [PPTP_START_SESSION_REQUEST] = sizeof(struct PptpStartSessionRequest),
296 [PPTP_START_SESSION_REPLY] = sizeof(struct PptpStartSessionReply),
297 [PPTP_STOP_SESSION_REQUEST] = sizeof(struct PptpStopSessionRequest),
298 [PPTP_STOP_SESSION_REPLY] = sizeof(struct PptpStopSessionReply),
299 [PPTP_OUT_CALL_REQUEST] = sizeof(struct PptpOutCallRequest),
300 [PPTP_OUT_CALL_REPLY] = sizeof(struct PptpOutCallReply),
301 [PPTP_IN_CALL_REQUEST] = sizeof(struct PptpInCallRequest),
302 [PPTP_IN_CALL_REPLY] = sizeof(struct PptpInCallReply),
303 [PPTP_IN_CALL_CONNECT] = sizeof(struct PptpInCallConnected),
304 [PPTP_CALL_CLEAR_REQUEST] = sizeof(struct PptpClearCallRequest),
305 [PPTP_CALL_DISCONNECT_NOTIFY] = sizeof(struct PptpCallDisconnectNotify),
306 [PPTP_WAN_ERROR_NOTIFY] = sizeof(struct PptpWanErrorNotify),
307 [PPTP_SET_LINK_INFO] = sizeof(struct PptpSetLinkInfo),
308};
309
294static inline int 310static inline int
295pptp_inbound_pkt(struct sk_buff **pskb, 311pptp_inbound_pkt(struct sk_buff **pskb,
296 struct tcphdr *tcph, 312 struct tcphdr *tcph,
@@ -326,13 +342,11 @@ pptp_inbound_pkt(struct sk_buff **pskb,
326 msg = ntohs(ctlh->messageType); 342 msg = ntohs(ctlh->messageType);
327 DEBUGP("inbound control message %s\n", pptp_msg_name[msg]); 343 DEBUGP("inbound control message %s\n", pptp_msg_name[msg]);
328 344
345 if (msg > 0 && msg <= PPTP_MSG_MAX && reqlen < pptp_msg_size[msg])
346 return NF_ACCEPT;
347
329 switch (msg) { 348 switch (msg) {
330 case PPTP_START_SESSION_REPLY: 349 case PPTP_START_SESSION_REPLY:
331 if (reqlen < sizeof(_pptpReq.srep)) {
332 DEBUGP("%s: short packet\n", pptp_msg_name[msg]);
333 break;
334 }
335
336 /* server confirms new control session */ 350 /* server confirms new control session */
337 if (info->sstate < PPTP_SESSION_REQUESTED) { 351 if (info->sstate < PPTP_SESSION_REQUESTED) {
338 DEBUGP("%s without START_SESS_REQUEST\n", 352 DEBUGP("%s without START_SESS_REQUEST\n",
@@ -346,11 +360,6 @@ pptp_inbound_pkt(struct sk_buff **pskb,
346 break; 360 break;
347 361
348 case PPTP_STOP_SESSION_REPLY: 362 case PPTP_STOP_SESSION_REPLY:
349 if (reqlen < sizeof(_pptpReq.strep)) {
350 DEBUGP("%s: short packet\n", pptp_msg_name[msg]);
351 break;
352 }
353
354 /* server confirms end of control session */ 363 /* server confirms end of control session */
355 if (info->sstate > PPTP_SESSION_STOPREQ) { 364 if (info->sstate > PPTP_SESSION_STOPREQ) {
356 DEBUGP("%s without STOP_SESS_REQUEST\n", 365 DEBUGP("%s without STOP_SESS_REQUEST\n",
@@ -364,11 +373,6 @@ pptp_inbound_pkt(struct sk_buff **pskb,
364 break; 373 break;
365 374
366 case PPTP_OUT_CALL_REPLY: 375 case PPTP_OUT_CALL_REPLY:
367 if (reqlen < sizeof(_pptpReq.ocack)) {
368 DEBUGP("%s: short packet\n", pptp_msg_name[msg]);
369 break;
370 }
371
372 /* server accepted call, we now expect GRE frames */ 376 /* server accepted call, we now expect GRE frames */
373 if (info->sstate != PPTP_SESSION_CONFIRMED) { 377 if (info->sstate != PPTP_SESSION_CONFIRMED) {
374 DEBUGP("%s but no session\n", pptp_msg_name[msg]); 378 DEBUGP("%s but no session\n", pptp_msg_name[msg]);
@@ -404,11 +408,6 @@ pptp_inbound_pkt(struct sk_buff **pskb,
404 break; 408 break;
405 409
406 case PPTP_IN_CALL_REQUEST: 410 case PPTP_IN_CALL_REQUEST:
407 if (reqlen < sizeof(_pptpReq.icack)) {
408 DEBUGP("%s: short packet\n", pptp_msg_name[msg]);
409 break;
410 }
411
412 /* server tells us about incoming call request */ 411 /* server tells us about incoming call request */
413 if (info->sstate != PPTP_SESSION_CONFIRMED) { 412 if (info->sstate != PPTP_SESSION_CONFIRMED) {
414 DEBUGP("%s but no session\n", pptp_msg_name[msg]); 413 DEBUGP("%s but no session\n", pptp_msg_name[msg]);
@@ -421,11 +420,6 @@ pptp_inbound_pkt(struct sk_buff **pskb,
421 break; 420 break;
422 421
423 case PPTP_IN_CALL_CONNECT: 422 case PPTP_IN_CALL_CONNECT:
424 if (reqlen < sizeof(_pptpReq.iccon)) {
425 DEBUGP("%s: short packet\n", pptp_msg_name[msg]);
426 break;
427 }
428
429 /* server tells us about incoming call established */ 423 /* server tells us about incoming call established */
430 if (info->sstate != PPTP_SESSION_CONFIRMED) { 424 if (info->sstate != PPTP_SESSION_CONFIRMED) {
431 DEBUGP("%s but no session\n", pptp_msg_name[msg]); 425 DEBUGP("%s but no session\n", pptp_msg_name[msg]);
@@ -455,11 +449,6 @@ pptp_inbound_pkt(struct sk_buff **pskb,
455 break; 449 break;
456 450
457 case PPTP_CALL_DISCONNECT_NOTIFY: 451 case PPTP_CALL_DISCONNECT_NOTIFY:
458 if (reqlen < sizeof(_pptpReq.disc)) {
459 DEBUGP("%s: short packet\n", pptp_msg_name[msg]);
460 break;
461 }
462
463 /* server confirms disconnect */ 452 /* server confirms disconnect */
464 cid = pptpReq->disc.callID; 453 cid = pptpReq->disc.callID;
465 DEBUGP("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid)); 454 DEBUGP("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid));
@@ -470,8 +459,6 @@ pptp_inbound_pkt(struct sk_buff **pskb,
470 break; 459 break;
471 460
472 case PPTP_WAN_ERROR_NOTIFY: 461 case PPTP_WAN_ERROR_NOTIFY:
473 break;
474
475 case PPTP_ECHO_REQUEST: 462 case PPTP_ECHO_REQUEST:
476 case PPTP_ECHO_REPLY: 463 case PPTP_ECHO_REPLY:
477 /* I don't have to explain these ;) */ 464 /* I don't have to explain these ;) */
@@ -522,6 +509,9 @@ pptp_outbound_pkt(struct sk_buff **pskb,
522 msg = ntohs(ctlh->messageType); 509 msg = ntohs(ctlh->messageType);
523 DEBUGP("outbound control message %s\n", pptp_msg_name[msg]); 510 DEBUGP("outbound control message %s\n", pptp_msg_name[msg]);
524 511
512 if (msg > 0 && msg <= PPTP_MSG_MAX && reqlen < pptp_msg_size[msg])
513 return NF_ACCEPT;
514
525 switch (msg) { 515 switch (msg) {
526 case PPTP_START_SESSION_REQUEST: 516 case PPTP_START_SESSION_REQUEST:
527 /* client requests for new control session */ 517 /* client requests for new control session */
@@ -537,11 +527,6 @@ pptp_outbound_pkt(struct sk_buff **pskb,
537 break; 527 break;
538 528
539 case PPTP_OUT_CALL_REQUEST: 529 case PPTP_OUT_CALL_REQUEST:
540 if (reqlen < sizeof(_pptpReq.ocreq)) {
541 DEBUGP("%s: short packet\n", pptp_msg_name[msg]);
542 break;
543 }
544
545 /* client initiating connection to server */ 530 /* client initiating connection to server */
546 if (info->sstate != PPTP_SESSION_CONFIRMED) { 531 if (info->sstate != PPTP_SESSION_CONFIRMED) {
547 DEBUGP("%s but no session\n", 532 DEBUGP("%s but no session\n",
@@ -555,11 +540,6 @@ pptp_outbound_pkt(struct sk_buff **pskb,
555 info->pns_call_id = cid; 540 info->pns_call_id = cid;
556 break; 541 break;
557 case PPTP_IN_CALL_REPLY: 542 case PPTP_IN_CALL_REPLY:
558 if (reqlen < sizeof(_pptpReq.icack)) {
559 DEBUGP("%s: short packet\n", pptp_msg_name[msg]);
560 break;
561 }
562
563 /* client answers incoming call */ 543 /* client answers incoming call */
564 if (info->cstate != PPTP_CALL_IN_REQ 544 if (info->cstate != PPTP_CALL_IN_REQ
565 && info->cstate != PPTP_CALL_IN_REP) { 545 && info->cstate != PPTP_CALL_IN_REP) {
@@ -595,7 +575,6 @@ pptp_outbound_pkt(struct sk_buff **pskb,
595 info->cstate = PPTP_CALL_CLEAR_REQ; 575 info->cstate = PPTP_CALL_CLEAR_REQ;
596 break; 576 break;
597 case PPTP_SET_LINK_INFO: 577 case PPTP_SET_LINK_INFO:
598 break;
599 case PPTP_ECHO_REQUEST: 578 case PPTP_ECHO_REQUEST:
600 case PPTP_ECHO_REPLY: 579 case PPTP_ECHO_REPLY:
601 /* I don't have to explain these ;) */ 580 /* I don't have to explain these ;) */