diff options
author | Eric Dumazet <edumazet@google.com> | 2012-09-04 03:49:03 -0400 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2012-09-06 08:28:18 -0400 |
commit | 0626af3139572610b56376580d11eb65d45d9dd7 (patch) | |
tree | e1c4664b0afd65788e1508402a5ab60772c2dad0 /net | |
parent | 5b716ac728bcc01b1f2a7ed6e437196602237c27 (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.c | 14 | ||||
-rw-r--r-- | net/netfilter/xt_LOG.c | 33 |
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 | ||
148 | static 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 */ |
149 | static void dump_ipv4_packet(struct sbuff *m, | 162 | static 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) |