Skip to content

Commit b73c8bf

Browse files
committed
Merge branch 'skb_to_full_sk'
Eric Dumazet says: ==================== net: add skb_to_full_sk() helper Many contexts need to reach listener socket from skb attached to a request socket. This patch series add skb_to_full_sk() to clearly express this need and use it where appropriate. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents fb9a10d + 3aed822 commit b73c8bf

File tree

8 files changed

+149
-87
lines changed

8 files changed

+149
-87
lines changed

include/net/inet_sock.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,18 @@ struct inet_sock {
210210
#define IP_CMSG_ORIGDSTADDR BIT(6)
211211
#define IP_CMSG_CHECKSUM BIT(7)
212212

213+
/* SYNACK messages might be attached to request sockets.
214+
* Some places want to reach the listener in this case.
215+
*/
216+
static inline struct sock *skb_to_full_sk(const struct sk_buff *skb)
217+
{
218+
struct sock *sk = skb->sk;
219+
220+
if (sk && sk->sk_state == TCP_NEW_SYN_RECV)
221+
sk = inet_reqsk(sk)->rsk_listener;
222+
return sk;
223+
}
224+
213225
static inline struct inet_sock *inet_sk(const struct sock *sk)
214226
{
215227
return (struct inet_sock *)sk;

net/netfilter/nft_meta.c

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ void nft_meta_get_eval(const struct nft_expr *expr,
3131
const struct nft_meta *priv = nft_expr_priv(expr);
3232
const struct sk_buff *skb = pkt->skb;
3333
const struct net_device *in = pkt->in, *out = pkt->out;
34+
struct sock *sk;
3435
u32 *dest = &regs->data[priv->dreg];
3536

3637
switch (priv->key) {
@@ -86,33 +87,35 @@ void nft_meta_get_eval(const struct nft_expr *expr,
8687
*(u16 *)dest = out->type;
8788
break;
8889
case NFT_META_SKUID:
89-
if (skb->sk == NULL || !sk_fullsock(skb->sk))
90+
sk = skb_to_full_sk(skb);
91+
if (!sk || !sk_fullsock(sk))
9092
goto err;
9193

92-
read_lock_bh(&skb->sk->sk_callback_lock);
93-
if (skb->sk->sk_socket == NULL ||
94-
skb->sk->sk_socket->file == NULL) {
95-
read_unlock_bh(&skb->sk->sk_callback_lock);
94+
read_lock_bh(&sk->sk_callback_lock);
95+
if (sk->sk_socket == NULL ||
96+
sk->sk_socket->file == NULL) {
97+
read_unlock_bh(&sk->sk_callback_lock);
9698
goto err;
9799
}
98100

99101
*dest = from_kuid_munged(&init_user_ns,
100-
skb->sk->sk_socket->file->f_cred->fsuid);
101-
read_unlock_bh(&skb->sk->sk_callback_lock);
102+
sk->sk_socket->file->f_cred->fsuid);
103+
read_unlock_bh(&sk->sk_callback_lock);
102104
break;
103105
case NFT_META_SKGID:
104-
if (skb->sk == NULL || !sk_fullsock(skb->sk))
106+
sk = skb_to_full_sk(skb);
107+
if (!sk || !sk_fullsock(sk))
105108
goto err;
106109

107-
read_lock_bh(&skb->sk->sk_callback_lock);
108-
if (skb->sk->sk_socket == NULL ||
109-
skb->sk->sk_socket->file == NULL) {
110-
read_unlock_bh(&skb->sk->sk_callback_lock);
110+
read_lock_bh(&sk->sk_callback_lock);
111+
if (sk->sk_socket == NULL ||
112+
sk->sk_socket->file == NULL) {
113+
read_unlock_bh(&sk->sk_callback_lock);
111114
goto err;
112115
}
113116
*dest = from_kgid_munged(&init_user_ns,
114-
skb->sk->sk_socket->file->f_cred->fsgid);
115-
read_unlock_bh(&skb->sk->sk_callback_lock);
117+
sk->sk_socket->file->f_cred->fsgid);
118+
read_unlock_bh(&sk->sk_callback_lock);
116119
break;
117120
#ifdef CONFIG_IP_ROUTE_CLASSID
118121
case NFT_META_RTCLASSID: {
@@ -168,9 +171,10 @@ void nft_meta_get_eval(const struct nft_expr *expr,
168171
break;
169172
#ifdef CONFIG_CGROUP_NET_CLASSID
170173
case NFT_META_CGROUP:
171-
if (skb->sk == NULL || !sk_fullsock(skb->sk))
174+
sk = skb_to_full_sk(skb);
175+
if (!sk || !sk_fullsock(sk))
172176
goto err;
173-
*dest = skb->sk->sk_classid;
177+
*dest = sk->sk_classid;
174178
break;
175179
#endif
176180
default:

net/netfilter/xt_owner.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/skbuff.h>
1515
#include <linux/file.h>
1616
#include <net/sock.h>
17+
#include <net/inet_sock.h>
1718
#include <linux/netfilter/x_tables.h>
1819
#include <linux/netfilter/xt_owner.h>
1920

@@ -33,8 +34,9 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
3334
{
3435
const struct xt_owner_match_info *info = par->matchinfo;
3536
const struct file *filp;
37+
struct sock *sk = skb_to_full_sk(skb);
3638

37-
if (skb->sk == NULL || skb->sk->sk_socket == NULL)
39+
if (sk == NULL || sk->sk_socket == NULL)
3840
return (info->match ^ info->invert) == 0;
3941
else if (info->match & info->invert & XT_OWNER_SOCKET)
4042
/*
@@ -43,7 +45,7 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
4345
*/
4446
return false;
4547

46-
filp = skb->sk->sk_socket->file;
48+
filp = sk->sk_socket->file;
4749
if (filp == NULL)
4850
return ((info->match ^ info->invert) &
4951
(XT_OWNER_UID | XT_OWNER_GID)) == 0;

net/sched/cls_flow.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/if_vlan.h>
2323
#include <linux/slab.h>
2424
#include <linux/module.h>
25+
#include <net/inet_sock.h>
2526

2627
#include <net/pkt_cls.h>
2728
#include <net/ip.h>
@@ -197,17 +198,23 @@ static u32 flow_get_rtclassid(const struct sk_buff *skb)
197198

198199
static u32 flow_get_skuid(const struct sk_buff *skb)
199200
{
200-
if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) {
201-
kuid_t skuid = skb->sk->sk_socket->file->f_cred->fsuid;
201+
struct sock *sk = skb_to_full_sk(skb);
202+
203+
if (sk && sk->sk_socket && sk->sk_socket->file) {
204+
kuid_t skuid = sk->sk_socket->file->f_cred->fsuid;
205+
202206
return from_kuid(&init_user_ns, skuid);
203207
}
204208
return 0;
205209
}
206210

207211
static u32 flow_get_skgid(const struct sk_buff *skb)
208212
{
209-
if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) {
210-
kgid_t skgid = skb->sk->sk_socket->file->f_cred->fsgid;
213+
struct sock *sk = skb_to_full_sk(skb);
214+
215+
if (sk && sk->sk_socket && sk->sk_socket->file) {
216+
kgid_t skgid = sk->sk_socket->file->f_cred->fsgid;
217+
211218
return from_kgid(&init_user_ns, skgid);
212219
}
213220
return 0;

0 commit comments

Comments
 (0)