Skip to content

Commit f564650

Browse files
fleitnerdavem330
authored andcommitted
netfilter: check if the socket netns is correct.
Netfilter assumes that if the socket is present in the skb, then it can be used because that reference is cleaned up while the skb is crossing netns. We want to change that to preserve the socket reference in a future patch, so this is a preparation updating netfilter to check if the socket netns matches before use it. Signed-off-by: Flavio Leitner <[email protected]> Acked-by: Florian Westphal <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 003504a commit f564650

File tree

12 files changed

+44
-21
lines changed

12 files changed

+44
-21
lines changed

include/net/netfilter/nf_log.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ int nf_log_dump_udp_header(struct nf_log_buf *m, const struct sk_buff *skb,
106106
int nf_log_dump_tcp_header(struct nf_log_buf *m, const struct sk_buff *skb,
107107
u8 proto, int fragment, unsigned int offset,
108108
unsigned int logflags);
109-
void nf_log_dump_sk_uid_gid(struct nf_log_buf *m, struct sock *sk);
109+
void nf_log_dump_sk_uid_gid(struct net *net, struct nf_log_buf *m,
110+
struct sock *sk);
110111
void nf_log_dump_packet_common(struct nf_log_buf *m, u_int8_t pf,
111112
unsigned int hooknum, const struct sk_buff *skb,
112113
const struct net_device *in,

net/ipv4/netfilter/nf_log_ipv4.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ static const struct nf_loginfo default_loginfo = {
3535
};
3636

3737
/* One level of recursion won't kill us */
38-
static void dump_ipv4_packet(struct nf_log_buf *m,
38+
static void dump_ipv4_packet(struct net *net, struct nf_log_buf *m,
3939
const struct nf_loginfo *info,
4040
const struct sk_buff *skb, unsigned int iphoff)
4141
{
@@ -183,7 +183,7 @@ static void dump_ipv4_packet(struct nf_log_buf *m,
183183
/* Max length: 3+maxlen */
184184
if (!iphoff) { /* Only recurse once. */
185185
nf_log_buf_add(m, "[");
186-
dump_ipv4_packet(m, info, skb,
186+
dump_ipv4_packet(net, m, info, skb,
187187
iphoff + ih->ihl*4+sizeof(_icmph));
188188
nf_log_buf_add(m, "] ");
189189
}
@@ -251,7 +251,7 @@ static void dump_ipv4_packet(struct nf_log_buf *m,
251251

252252
/* Max length: 15 "UID=4294967295 " */
253253
if ((logflags & NF_LOG_UID) && !iphoff)
254-
nf_log_dump_sk_uid_gid(m, skb->sk);
254+
nf_log_dump_sk_uid_gid(net, m, skb->sk);
255255

256256
/* Max length: 16 "MARK=0xFFFFFFFF " */
257257
if (!iphoff && skb->mark)
@@ -333,7 +333,7 @@ static void nf_log_ip_packet(struct net *net, u_int8_t pf,
333333
if (in != NULL)
334334
dump_ipv4_mac_header(m, loginfo, skb);
335335

336-
dump_ipv4_packet(m, loginfo, skb, 0);
336+
dump_ipv4_packet(net, m, loginfo, skb, 0);
337337

338338
nf_log_buf_close(m);
339339
}

net/ipv6/netfilter/nf_log_ipv6.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ static const struct nf_loginfo default_loginfo = {
3636
};
3737

3838
/* One level of recursion won't kill us */
39-
static void dump_ipv6_packet(struct nf_log_buf *m,
39+
static void dump_ipv6_packet(struct net *net, struct nf_log_buf *m,
4040
const struct nf_loginfo *info,
4141
const struct sk_buff *skb, unsigned int ip6hoff,
4242
int recurse)
@@ -258,7 +258,7 @@ static void dump_ipv6_packet(struct nf_log_buf *m,
258258
/* Max length: 3+maxlen */
259259
if (recurse) {
260260
nf_log_buf_add(m, "[");
261-
dump_ipv6_packet(m, info, skb,
261+
dump_ipv6_packet(net, m, info, skb,
262262
ptr + sizeof(_icmp6h), 0);
263263
nf_log_buf_add(m, "] ");
264264
}
@@ -278,7 +278,7 @@ static void dump_ipv6_packet(struct nf_log_buf *m,
278278

279279
/* Max length: 15 "UID=4294967295 " */
280280
if ((logflags & NF_LOG_UID) && recurse)
281-
nf_log_dump_sk_uid_gid(m, skb->sk);
281+
nf_log_dump_sk_uid_gid(net, m, skb->sk);
282282

283283
/* Max length: 16 "MARK=0xFFFFFFFF " */
284284
if (recurse && skb->mark)
@@ -365,7 +365,7 @@ static void nf_log_ip6_packet(struct net *net, u_int8_t pf,
365365
if (in != NULL)
366366
dump_ipv6_mac_header(m, loginfo, skb);
367367

368-
dump_ipv6_packet(m, loginfo, skb, skb_network_offset(skb), 1);
368+
dump_ipv6_packet(net, m, loginfo, skb, skb_network_offset(skb), 1);
369369

370370
nf_log_buf_close(m);
371371
}

net/netfilter/nf_conntrack_broadcast.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb,
3232
__be32 mask = 0;
3333

3434
/* we're only interested in locally generated packets */
35-
if (skb->sk == NULL)
35+
if (skb->sk == NULL || !net_eq(nf_ct_net(ct), sock_net(skb->sk)))
3636
goto out;
3737
if (rt == NULL || !(rt->rt_flags & RTCF_BROADCAST))
3838
goto out;

net/netfilter/nf_log_common.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,10 @@ int nf_log_dump_tcp_header(struct nf_log_buf *m, const struct sk_buff *skb,
132132
}
133133
EXPORT_SYMBOL_GPL(nf_log_dump_tcp_header);
134134

135-
void nf_log_dump_sk_uid_gid(struct nf_log_buf *m, struct sock *sk)
135+
void nf_log_dump_sk_uid_gid(struct net *net, struct nf_log_buf *m,
136+
struct sock *sk)
136137
{
137-
if (!sk || !sk_fullsock(sk))
138+
if (!sk || !sk_fullsock(sk) || !net_eq(net, sock_net(sk)))
138139
return;
139140

140141
read_lock_bh(&sk->sk_callback_lock);

net/netfilter/nf_nat_core.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ int nf_xfrm_me_harder(struct net *net, struct sk_buff *skb, unsigned int family)
108108
struct flowi fl;
109109
unsigned int hh_len;
110110
struct dst_entry *dst;
111+
struct sock *sk = skb->sk;
111112
int err;
112113

113114
err = xfrm_decode_session(skb, &fl, family);
@@ -119,7 +120,10 @@ int nf_xfrm_me_harder(struct net *net, struct sk_buff *skb, unsigned int family)
119120
dst = ((struct xfrm_dst *)dst)->route;
120121
dst_hold(dst);
121122

122-
dst = xfrm_lookup(net, dst, &fl, skb->sk, 0);
123+
if (sk && !net_eq(net, sock_net(sk)))
124+
sk = NULL;
125+
126+
dst = xfrm_lookup(net, dst, &fl, sk, 0);
123127
if (IS_ERR(dst))
124128
return PTR_ERR(dst);
125129

net/netfilter/nft_meta.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ static void nft_meta_get_eval(const struct nft_expr *expr,
107107
break;
108108
case NFT_META_SKUID:
109109
sk = skb_to_full_sk(skb);
110-
if (!sk || !sk_fullsock(sk))
110+
if (!sk || !sk_fullsock(sk) ||
111+
!net_eq(nft_net(pkt), sock_net(sk)))
111112
goto err;
112113

113114
read_lock_bh(&sk->sk_callback_lock);
@@ -123,7 +124,8 @@ static void nft_meta_get_eval(const struct nft_expr *expr,
123124
break;
124125
case NFT_META_SKGID:
125126
sk = skb_to_full_sk(skb);
126-
if (!sk || !sk_fullsock(sk))
127+
if (!sk || !sk_fullsock(sk) ||
128+
!net_eq(nft_net(pkt), sock_net(sk)))
127129
goto err;
128130

129131
read_lock_bh(&sk->sk_callback_lock);
@@ -214,7 +216,8 @@ static void nft_meta_get_eval(const struct nft_expr *expr,
214216
#ifdef CONFIG_CGROUP_NET_CLASSID
215217
case NFT_META_CGROUP:
216218
sk = skb_to_full_sk(skb);
217-
if (!sk || !sk_fullsock(sk))
219+
if (!sk || !sk_fullsock(sk) ||
220+
!net_eq(nft_net(pkt), sock_net(sk)))
218221
goto err;
219222
*dest = sock_cgroup_classid(&sk->sk_cgrp_data);
220223
break;

net/netfilter/nft_socket.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ static void nft_socket_eval(const struct nft_expr *expr,
2323
struct sock *sk = skb->sk;
2424
u32 *dest = &regs->data[priv->dreg];
2525

26+
if (sk && !net_eq(nft_net(pkt), sock_net(sk)))
27+
sk = NULL;
28+
2629
if (!sk)
2730
switch(nft_pf(pkt)) {
2831
case NFPROTO_IPV4:
@@ -39,7 +42,7 @@ static void nft_socket_eval(const struct nft_expr *expr,
3942
return;
4043
}
4144

42-
if(!sk) {
45+
if (!sk) {
4346
nft_reg_store8(dest, 0);
4447
return;
4548
}

net/netfilter/xt_cgroup.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@ static bool
7272
cgroup_mt_v0(const struct sk_buff *skb, struct xt_action_param *par)
7373
{
7474
const struct xt_cgroup_info_v0 *info = par->matchinfo;
75+
struct sock *sk = skb->sk;
7576

76-
if (skb->sk == NULL || !sk_fullsock(skb->sk))
77+
if (!sk || !sk_fullsock(sk) || !net_eq(xt_net(par), sock_net(sk)))
7778
return false;
7879

7980
return (info->id == sock_cgroup_classid(&skb->sk->sk_cgrp_data)) ^
@@ -85,8 +86,9 @@ static bool cgroup_mt_v1(const struct sk_buff *skb, struct xt_action_param *par)
8586
const struct xt_cgroup_info_v1 *info = par->matchinfo;
8687
struct sock_cgroup_data *skcd = &skb->sk->sk_cgrp_data;
8788
struct cgroup *ancestor = info->priv;
89+
struct sock *sk = skb->sk;
8890

89-
if (!skb->sk || !sk_fullsock(skb->sk))
91+
if (!sk || !sk_fullsock(sk) || !net_eq(xt_net(par), sock_net(sk)))
9092
return false;
9193

9294
if (ancestor)

net/netfilter/xt_owner.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
6767
struct sock *sk = skb_to_full_sk(skb);
6868
struct net *net = xt_net(par);
6969

70-
if (sk == NULL || sk->sk_socket == NULL)
70+
if (!sk || !sk->sk_socket || !net_eq(net, sock_net(sk)))
7171
return (info->match ^ info->invert) == 0;
7272
else if (info->match & info->invert & XT_OWNER_SOCKET)
7373
/*

net/netfilter/xt_recent.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,8 @@ recent_mt(const struct sk_buff *skb, struct xt_action_param *par)
265265
}
266266

267267
/* use TTL as seen before forwarding */
268-
if (xt_out(par) != NULL && skb->sk == NULL)
268+
if (xt_out(par) != NULL &&
269+
(!skb->sk || !net_eq(net, sock_net(skb->sk))))
269270
ttl++;
270271

271272
spin_lock_bh(&recent_lock);

net/netfilter/xt_socket.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,12 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par,
5656
struct sk_buff *pskb = (struct sk_buff *)skb;
5757
struct sock *sk = skb->sk;
5858

59+
if (!net_eq(xt_net(par), sock_net(sk)))
60+
sk = NULL;
61+
5962
if (!sk)
6063
sk = nf_sk_lookup_slow_v4(xt_net(par), skb, xt_in(par));
64+
6165
if (sk) {
6266
bool wildcard;
6367
bool transparent = true;
@@ -113,8 +117,12 @@ socket_mt6_v1_v2_v3(const struct sk_buff *skb, struct xt_action_param *par)
113117
struct sk_buff *pskb = (struct sk_buff *)skb;
114118
struct sock *sk = skb->sk;
115119

120+
if (!net_eq(xt_net(par), sock_net(sk)))
121+
sk = NULL;
122+
116123
if (!sk)
117124
sk = nf_sk_lookup_slow_v6(xt_net(par), skb, xt_in(par));
125+
118126
if (sk) {
119127
bool wildcard;
120128
bool transparent = true;

0 commit comments

Comments
 (0)