Commit 0626af31 authored by Eric Dumazet's avatar Eric Dumazet Committed by Pablo Neira Ayuso

netfilter: take care of timewait sockets

Sami Farin reported crashes in xt_LOG because it assumes skb->sk is a
full blown socket.

Since (41063e9d ipv4: Early TCP socket demux), we can have skb->sk
pointing to a timewait socket.

Same fix is needed in nfnetlink_log.
Diagnosed-by: default avatarFlorian Westphal <fw@strlen.de>
Reported-by: default avatarSami Farin <hvtaifwkbgefbaei@gmail.com>
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 5b716ac7
...@@ -381,6 +381,7 @@ __build_packet_message(struct nfulnl_instance *inst, ...@@ -381,6 +381,7 @@ __build_packet_message(struct nfulnl_instance *inst,
struct nlmsghdr *nlh; struct nlmsghdr *nlh;
struct nfgenmsg *nfmsg; struct nfgenmsg *nfmsg;
sk_buff_data_t old_tail = inst->skb->tail; sk_buff_data_t old_tail = inst->skb->tail;
struct sock *sk;
nlh = nlmsg_put(inst->skb, 0, 0, nlh = nlmsg_put(inst->skb, 0, 0,
NFNL_SUBSYS_ULOG << 8 | NFULNL_MSG_PACKET, NFNL_SUBSYS_ULOG << 8 | NFULNL_MSG_PACKET,
...@@ -499,18 +500,19 @@ __build_packet_message(struct nfulnl_instance *inst, ...@@ -499,18 +500,19 @@ __build_packet_message(struct nfulnl_instance *inst,
} }
/* UID */ /* UID */
if (skb->sk) { sk = skb->sk;
read_lock_bh(&skb->sk->sk_callback_lock); if (sk && sk->sk_state != TCP_TIME_WAIT) {
if (skb->sk->sk_socket && skb->sk->sk_socket->file) { read_lock_bh(&sk->sk_callback_lock);
struct file *file = skb->sk->sk_socket->file; if (sk->sk_socket && sk->sk_socket->file) {
struct file *file = sk->sk_socket->file;
__be32 uid = htonl(file->f_cred->fsuid); __be32 uid = htonl(file->f_cred->fsuid);
__be32 gid = htonl(file->f_cred->fsgid); __be32 gid = htonl(file->f_cred->fsgid);
read_unlock_bh(&skb->sk->sk_callback_lock); read_unlock_bh(&sk->sk_callback_lock);
if (nla_put_be32(inst->skb, NFULA_UID, uid) || if (nla_put_be32(inst->skb, NFULA_UID, uid) ||
nla_put_be32(inst->skb, NFULA_GID, gid)) nla_put_be32(inst->skb, NFULA_GID, gid))
goto nla_put_failure; goto nla_put_failure;
} else } else
read_unlock_bh(&skb->sk->sk_callback_lock); read_unlock_bh(&sk->sk_callback_lock);
} }
/* local sequence number */ /* local sequence number */
......
...@@ -145,6 +145,19 @@ static int dump_tcp_header(struct sbuff *m, const struct sk_buff *skb, ...@@ -145,6 +145,19 @@ static int dump_tcp_header(struct sbuff *m, const struct sk_buff *skb,
return 0; return 0;
} }
static void dump_sk_uid_gid(struct sbuff *m, struct sock *sk)
{
if (!sk || sk->sk_state == TCP_TIME_WAIT)
return;
read_lock_bh(&sk->sk_callback_lock);
if (sk->sk_socket && sk->sk_socket->file)
sb_add(m, "UID=%u GID=%u ",
sk->sk_socket->file->f_cred->fsuid,
sk->sk_socket->file->f_cred->fsgid);
read_unlock_bh(&sk->sk_callback_lock);
}
/* One level of recursion won't kill us */ /* One level of recursion won't kill us */
static void dump_ipv4_packet(struct sbuff *m, static void dump_ipv4_packet(struct sbuff *m,
const struct nf_loginfo *info, const struct nf_loginfo *info,
...@@ -361,14 +374,8 @@ static void dump_ipv4_packet(struct sbuff *m, ...@@ -361,14 +374,8 @@ static void dump_ipv4_packet(struct sbuff *m,
} }
/* Max length: 15 "UID=4294967295 " */ /* Max length: 15 "UID=4294967295 " */
if ((logflags & XT_LOG_UID) && !iphoff && skb->sk) { if ((logflags & XT_LOG_UID) && !iphoff)
read_lock_bh(&skb->sk->sk_callback_lock); dump_sk_uid_gid(m, skb->sk);
if (skb->sk->sk_socket && skb->sk->sk_socket->file)
sb_add(m, "UID=%u GID=%u ",
skb->sk->sk_socket->file->f_cred->fsuid,
skb->sk->sk_socket->file->f_cred->fsgid);
read_unlock_bh(&skb->sk->sk_callback_lock);
}
/* Max length: 16 "MARK=0xFFFFFFFF " */ /* Max length: 16 "MARK=0xFFFFFFFF " */
if (!iphoff && skb->mark) if (!iphoff && skb->mark)
...@@ -717,14 +724,8 @@ static void dump_ipv6_packet(struct sbuff *m, ...@@ -717,14 +724,8 @@ static void dump_ipv6_packet(struct sbuff *m,
} }
/* Max length: 15 "UID=4294967295 " */ /* Max length: 15 "UID=4294967295 " */
if ((logflags & XT_LOG_UID) && recurse && skb->sk) { if ((logflags & XT_LOG_UID) && recurse)
read_lock_bh(&skb->sk->sk_callback_lock); dump_sk_uid_gid(m, skb->sk);
if (skb->sk->sk_socket && skb->sk->sk_socket->file)
sb_add(m, "UID=%u GID=%u ",
skb->sk->sk_socket->file->f_cred->fsuid,
skb->sk->sk_socket->file->f_cred->fsgid);
read_unlock_bh(&skb->sk->sk_callback_lock);
}
/* Max length: 16 "MARK=0xFFFFFFFF " */ /* Max length: 16 "MARK=0xFFFFFFFF " */
if (!recurse && skb->mark) if (!recurse && skb->mark)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment