aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2012-09-04 03:49:03 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2012-09-06 08:28:18 -0400
commit0626af3139572610b56376580d11eb65d45d9dd7 (patch)
treee1c4664b0afd65788e1508402a5ab60772c2dad0 /net
parent5b716ac728bcc01b1f2a7ed6e437196602237c27 (diff)
netfilter: take care of timewait sockets
Sami Farin reported crashes in xt_LOG because it assumes skb->sk is a full blown socket. Since (41063e9 ipv4: Early TCP socket demux), we can have skb->sk pointing to a timewait socket. Same fix is needed in nfnetlink_log. Diagnosed-by: Florian Westphal <fw@strlen.de> Reported-by: Sami Farin <hvtaifwkbgefbaei@gmail.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/nfnetlink_log.c14
-rw-r--r--net/netfilter/xt_LOG.c33
2 files changed, 25 insertions, 22 deletions
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 14e2f3903142..5cfb5bedb2b8 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -381,6 +381,7 @@ __build_packet_message(struct nfulnl_instance *inst,
381 struct nlmsghdr *nlh; 381 struct nlmsghdr *nlh;
382 struct nfgenmsg *nfmsg; 382 struct nfgenmsg *nfmsg;
383 sk_buff_data_t old_tail = inst->skb->tail; 383 sk_buff_data_t old_tail = inst->skb->tail;
384 struct sock *sk;
384 385
385 nlh = nlmsg_put(inst->skb, 0, 0, 386 nlh = nlmsg_put(inst->skb, 0, 0,
386 NFNL_SUBSYS_ULOG << 8 | NFULNL_MSG_PACKET, 387 NFNL_SUBSYS_ULOG << 8 | NFULNL_MSG_PACKET,
@@ -499,18 +500,19 @@ __build_packet_message(struct nfulnl_instance *inst,
499 } 500 }
500 501
501 /* UID */ 502 /* UID */
502 if (skb->sk) { 503 sk = skb->sk;
503 read_lock_bh(&skb->sk->sk_callback_lock); 504 if (sk && sk->sk_state != TCP_TIME_WAIT) {
504 if (skb->sk->sk_socket && skb->sk->sk_socket->file) { 505 read_lock_bh(&sk->sk_callback_lock);
505 struct file *file = skb->sk->sk_socket->file; 506 if (sk->sk_socket && sk->sk_socket->file) {
507 struct file *file = sk->sk_socket->file;
506 __be32 uid = htonl(file->f_cred->fsuid); 508 __be32 uid = htonl(file->f_cred->fsuid);
507 __be32 gid = htonl(file->f_cred->fsgid); 509 __be32 gid = htonl(file->f_cred->fsgid);
508 read_unlock_bh(&skb->sk->sk_callback_lock); 510 read_unlock_bh(&sk->sk_callback_lock);
509 if (nla_put_be32(inst->skb, NFULA_UID, uid) || 511 if (nla_put_be32(inst->skb, NFULA_UID, uid) ||
510 nla_put_be32(inst->skb, NFULA_GID, gid)) 512 nla_put_be32(inst->skb, NFULA_GID, gid))
511 goto nla_put_failure; 513 goto nla_put_failure;
512 } else 514 } else
513 read_unlock_bh(&skb->sk->sk_callback_lock); 515 read_unlock_bh(&sk->sk_callback_lock);
514 } 516 }
515 517
516 /* local sequence number */ 518 /* local sequence number */
diff --git a/net/netfilter/xt_LOG.c b/net/netfilter/xt_LOG.c
index ff5f75fddb15..2a4f9693e799 100644
--- a/net/netfilter/xt_LOG.c
+++ b/net/netfilter/xt_LOG.c
@@ -145,6 +145,19 @@ static int dump_tcp_header(struct sbuff *m, const struct sk_buff *skb,
145 return 0; 145 return 0;
146} 146}
147 147
148static void dump_sk_uid_gid(struct sbuff *m, struct sock *sk)
149{
150 if (!sk || sk->sk_state == TCP_TIME_WAIT)
151 return;
152
153 read_lock_bh(&sk->sk_callback_lock);
154 if (sk->sk_socket && sk->sk_socket->file)
155 sb_add(m, "UID=%u GID=%u ",
156 sk->sk_socket->file->f_cred->fsuid,
157 sk->sk_socket->file->f_cred->fsgid);
158 read_unlock_bh(&sk->sk_callback_lock);
159}
160
148/* One level of recursion won't kill us */ 161/* One level of recursion won't kill us */
149static void dump_ipv4_packet(struct sbuff *m, 162static void dump_ipv4_packet(struct sbuff *m,
150 const struct nf_loginfo *info, 163 const struct nf_loginfo *info,
@@ -361,14 +374,8 @@ static void dump_ipv4_packet(struct sbuff *m,
361 } 374 }
362 375
363 /* Max length: 15 "UID=4294967295 " */ 376 /* Max length: 15 "UID=4294967295 " */
364 if ((logflags & XT_LOG_UID) && !iphoff && skb->sk) { 377 if ((logflags & XT_LOG_UID) && !iphoff)
365 read_lock_bh(&skb->sk->sk_callback_lock); 378 dump_sk_uid_gid(m, skb->sk);
366 if (skb->sk->sk_socket && skb->sk->sk_socket->file)
367 sb_add(m, "UID=%u GID=%u ",
368 skb->sk->sk_socket->file->f_cred->fsuid,
369 skb->sk->sk_socket->file->f_cred->fsgid);
370 read_unlock_bh(&skb->sk->sk_callback_lock);
371 }
372 379
373 /* Max length: 16 "MARK=0xFFFFFFFF " */ 380 /* Max length: 16 "MARK=0xFFFFFFFF " */
374 if (!iphoff && skb->mark) 381 if (!iphoff && skb->mark)
@@ -717,14 +724,8 @@ static void dump_ipv6_packet(struct sbuff *m,
717 } 724 }
718 725
719 /* Max length: 15 "UID=4294967295 " */ 726 /* Max length: 15 "UID=4294967295 " */
720 if ((logflags & XT_LOG_UID) && recurse && skb->sk) { 727 if ((logflags & XT_LOG_UID) && recurse)
721 read_lock_bh(&skb->sk->sk_callback_lock); 728 dump_sk_uid_gid(m, skb->sk);
722 if (skb->sk->sk_socket && skb->sk->sk_socket->file)
723 sb_add(m, "UID=%u GID=%u ",
724 skb->sk->sk_socket->file->f_cred->fsuid,
725 skb->sk->sk_socket->file->f_cred->fsgid);
726 read_unlock_bh(&skb->sk->sk_callback_lock);
727 }
728 729
729 /* Max length: 16 "MARK=0xFFFFFFFF " */ 730 /* Max length: 16 "MARK=0xFFFFFFFF " */
730 if (!recurse && skb->mark) 731 if (!recurse && skb->mark)