diff options
-rw-r--r-- | net/ipv4/fib_frontend.c | 8 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_proto_tcp.c | 29 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_recent.c | 1 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_proto_tcp.c | 29 |
4 files changed, 47 insertions, 20 deletions
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 882f88f6d13b..19b1b984d687 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -544,12 +544,16 @@ static void nl_fib_input(struct sock *sk, int len) | |||
544 | struct sk_buff *skb = NULL; | 544 | struct sk_buff *skb = NULL; |
545 | struct nlmsghdr *nlh = NULL; | 545 | struct nlmsghdr *nlh = NULL; |
546 | struct fib_result_nl *frn; | 546 | struct fib_result_nl *frn; |
547 | int err; | ||
548 | u32 pid; | 547 | u32 pid; |
549 | struct fib_table *tb; | 548 | struct fib_table *tb; |
550 | 549 | ||
551 | skb = skb_recv_datagram(sk, 0, 0, &err); | 550 | skb = skb_dequeue(&sk->sk_receive_queue); |
552 | nlh = (struct nlmsghdr *)skb->data; | 551 | nlh = (struct nlmsghdr *)skb->data; |
552 | if (skb->len < NLMSG_SPACE(0) || skb->len < nlh->nlmsg_len || | ||
553 | nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*frn))) { | ||
554 | kfree_skb(skb); | ||
555 | return; | ||
556 | } | ||
553 | 557 | ||
554 | frn = (struct fib_result_nl *) NLMSG_DATA(nlh); | 558 | frn = (struct fib_result_nl *) NLMSG_DATA(nlh); |
555 | tb = fib_get_table(frn->tb_id_in); | 559 | tb = fib_get_table(frn->tb_id_in); |
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c index 625981676776..aeb7353d4777 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c | |||
@@ -272,9 +272,9 @@ static const enum tcp_conntrack tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = { | |||
272 | * sCL -> sCL | 272 | * sCL -> sCL |
273 | */ | 273 | */ |
274 | /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */ | 274 | /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */ |
275 | /*ack*/ { sIV, sIV, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV }, | 275 | /*ack*/ { sIV, sIG, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV }, |
276 | /* | 276 | /* |
277 | * sSS -> sIV Might be a half-open connection. | 277 | * sSS -> sIG Might be a half-open connection. |
278 | * sSR -> sSR Might answer late resent SYN. | 278 | * sSR -> sSR Might answer late resent SYN. |
279 | * sES -> sES :-) | 279 | * sES -> sES :-) |
280 | * sFW -> sCW Normal close request answered by ACK. | 280 | * sFW -> sCW Normal close request answered by ACK. |
@@ -917,8 +917,12 @@ static int tcp_packet(struct ip_conntrack *conntrack, | |||
917 | 917 | ||
918 | switch (new_state) { | 918 | switch (new_state) { |
919 | case TCP_CONNTRACK_IGNORE: | 919 | case TCP_CONNTRACK_IGNORE: |
920 | /* Either SYN in ORIGINAL | 920 | /* Ignored packets: |
921 | * or SYN/ACK in REPLY. */ | 921 | * |
922 | * a) SYN in ORIGINAL | ||
923 | * b) SYN/ACK in REPLY | ||
924 | * c) ACK in reply direction after initial SYN in original. | ||
925 | */ | ||
922 | if (index == TCP_SYNACK_SET | 926 | if (index == TCP_SYNACK_SET |
923 | && conntrack->proto.tcp.last_index == TCP_SYN_SET | 927 | && conntrack->proto.tcp.last_index == TCP_SYN_SET |
924 | && conntrack->proto.tcp.last_dir != dir | 928 | && conntrack->proto.tcp.last_dir != dir |
@@ -985,13 +989,20 @@ static int tcp_packet(struct ip_conntrack *conntrack, | |||
985 | } | 989 | } |
986 | case TCP_CONNTRACK_CLOSE: | 990 | case TCP_CONNTRACK_CLOSE: |
987 | if (index == TCP_RST_SET | 991 | if (index == TCP_RST_SET |
988 | && test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status) | 992 | && ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status) |
989 | && conntrack->proto.tcp.last_index == TCP_SYN_SET | 993 | && conntrack->proto.tcp.last_index == TCP_SYN_SET) |
994 | || (!test_bit(IPS_ASSURED_BIT, &conntrack->status) | ||
995 | && conntrack->proto.tcp.last_index == TCP_ACK_SET)) | ||
990 | && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) { | 996 | && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) { |
991 | /* RST sent to invalid SYN we had let trough | 997 | /* RST sent to invalid SYN or ACK we had let trough |
992 | * SYN was in window then, tear down connection. | 998 | * at a) and c) above: |
999 | * | ||
1000 | * a) SYN was in window then | ||
1001 | * c) we hold a half-open connection. | ||
1002 | * | ||
1003 | * Delete our connection entry. | ||
993 | * We skip window checking, because packet might ACK | 1004 | * We skip window checking, because packet might ACK |
994 | * segments we ignored in the SYN. */ | 1005 | * segments we ignored. */ |
995 | goto in_window; | 1006 | goto in_window; |
996 | } | 1007 | } |
997 | /* Just fall trough */ | 1008 | /* Just fall trough */ |
diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c index 2d44b07688af..261cbb4d4c49 100644 --- a/net/ipv4/netfilter/ipt_recent.c +++ b/net/ipv4/netfilter/ipt_recent.c | |||
@@ -532,6 +532,7 @@ match(const struct sk_buff *skb, | |||
532 | } | 532 | } |
533 | if(info->seconds && info->hit_count) { | 533 | if(info->seconds && info->hit_count) { |
534 | for(pkt_count = 0, hits_found = 0; pkt_count < ip_pkt_list_tot; pkt_count++) { | 534 | for(pkt_count = 0, hits_found = 0; pkt_count < ip_pkt_list_tot; pkt_count++) { |
535 | if(r_list[location].last_pkts[pkt_count] == 0) break; | ||
535 | if(time_before_eq(now,r_list[location].last_pkts[pkt_count]+info->seconds*HZ)) hits_found++; | 536 | if(time_before_eq(now,r_list[location].last_pkts[pkt_count]+info->seconds*HZ)) hits_found++; |
536 | } | 537 | } |
537 | if(hits_found >= info->hit_count) ans = !info->invert; else ans = info->invert; | 538 | if(hits_found >= info->hit_count) ans = !info->invert; else ans = info->invert; |
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index 5a6fcf349bdf..6035633d8225 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c | |||
@@ -280,9 +280,9 @@ static enum tcp_conntrack tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = { | |||
280 | * sCL -> sCL | 280 | * sCL -> sCL |
281 | */ | 281 | */ |
282 | /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */ | 282 | /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */ |
283 | /*ack*/ { sIV, sIV, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV }, | 283 | /*ack*/ { sIV, sIG, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV }, |
284 | /* | 284 | /* |
285 | * sSS -> sIV Might be a half-open connection. | 285 | * sSS -> sIG Might be a half-open connection. |
286 | * sSR -> sSR Might answer late resent SYN. | 286 | * sSR -> sSR Might answer late resent SYN. |
287 | * sES -> sES :-) | 287 | * sES -> sES :-) |
288 | * sFW -> sCW Normal close request answered by ACK. | 288 | * sFW -> sCW Normal close request answered by ACK. |
@@ -912,8 +912,12 @@ static int tcp_packet(struct nf_conn *conntrack, | |||
912 | 912 | ||
913 | switch (new_state) { | 913 | switch (new_state) { |
914 | case TCP_CONNTRACK_IGNORE: | 914 | case TCP_CONNTRACK_IGNORE: |
915 | /* Either SYN in ORIGINAL | 915 | /* Ignored packets: |
916 | * or SYN/ACK in REPLY. */ | 916 | * |
917 | * a) SYN in ORIGINAL | ||
918 | * b) SYN/ACK in REPLY | ||
919 | * c) ACK in reply direction after initial SYN in original. | ||
920 | */ | ||
917 | if (index == TCP_SYNACK_SET | 921 | if (index == TCP_SYNACK_SET |
918 | && conntrack->proto.tcp.last_index == TCP_SYN_SET | 922 | && conntrack->proto.tcp.last_index == TCP_SYN_SET |
919 | && conntrack->proto.tcp.last_dir != dir | 923 | && conntrack->proto.tcp.last_dir != dir |
@@ -979,13 +983,20 @@ static int tcp_packet(struct nf_conn *conntrack, | |||
979 | } | 983 | } |
980 | case TCP_CONNTRACK_CLOSE: | 984 | case TCP_CONNTRACK_CLOSE: |
981 | if (index == TCP_RST_SET | 985 | if (index == TCP_RST_SET |
982 | && test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status) | 986 | && ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status) |
983 | && conntrack->proto.tcp.last_index == TCP_SYN_SET | 987 | && conntrack->proto.tcp.last_index == TCP_SYN_SET) |
988 | || (!test_bit(IPS_ASSURED_BIT, &conntrack->status) | ||
989 | && conntrack->proto.tcp.last_index == TCP_ACK_SET)) | ||
984 | && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) { | 990 | && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) { |
985 | /* RST sent to invalid SYN we had let trough | 991 | /* RST sent to invalid SYN or ACK we had let trough |
986 | * SYN was in window then, tear down connection. | 992 | * at a) and c) above: |
993 | * | ||
994 | * a) SYN was in window then | ||
995 | * c) we hold a half-open connection. | ||
996 | * | ||
997 | * Delete our connection entry. | ||
987 | * We skip window checking, because packet might ACK | 998 | * We skip window checking, because packet might ACK |
988 | * segments we ignored in the SYN. */ | 999 | * segments we ignored. */ |
989 | goto in_window; | 1000 | goto in_window; |
990 | } | 1001 | } |
991 | /* Just fall trough */ | 1002 | /* Just fall trough */ |