Skip to content

Commit 091b87b

Browse files
edumazetgregkh
authored andcommitted
net: annotate races around sk->sk_uid
[ Upstream commit e84a492 ] sk->sk_uid can be read while another thread changes its value in sockfs_setattr(). Add sk_uid(const struct sock *sk) helper to factorize the needed READ_ONCE() annotations, and add corresponding WRITE_ONCE() where needed. Fixes: 86741ec ("net: core: Add a UID field to struct sock.") Signed-off-by: Eric Dumazet <[email protected]> Cc: Lorenzo Colitti <[email protected]> Reviewed-by: Maciej Żenczykowski <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent d9b91c2 commit 091b87b

20 files changed

+42
-28
lines changed

include/net/route.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ static inline void inet_sk_init_flowi4(const struct inet_sock *inet,
153153
ip_sock_rt_tos(sk), ip_sock_rt_scope(sk),
154154
sk->sk_protocol, inet_sk_flowi_flags(sk), daddr,
155155
inet->inet_saddr, inet->inet_dport,
156-
inet->inet_sport, sk->sk_uid);
156+
inet->inet_sport, sk_uid(sk));
157157
security_sk_classify_flow(sk, flowi4_to_flowi_common(fl4));
158158
}
159159

@@ -331,7 +331,7 @@ static inline void ip_route_connect_init(struct flowi4 *fl4, __be32 dst,
331331

332332
flowi4_init_output(fl4, oif, READ_ONCE(sk->sk_mark), ip_sock_rt_tos(sk),
333333
ip_sock_rt_scope(sk), protocol, flow_flags, dst,
334-
src, dport, sport, sk->sk_uid);
334+
src, dport, sport, sk_uid(sk));
335335
}
336336

337337
static inline struct rtable *ip_route_connect(struct flowi4 *fl4, __be32 dst,

include/net/sock.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2076,6 +2076,7 @@ static inline void sock_orphan(struct sock *sk)
20762076
sock_set_flag(sk, SOCK_DEAD);
20772077
sk_set_socket(sk, NULL);
20782078
sk->sk_wq = NULL;
2079+
/* Note: sk_uid is unchanged. */
20792080
write_unlock_bh(&sk->sk_callback_lock);
20802081
}
20812082

@@ -2086,18 +2087,25 @@ static inline void sock_graft(struct sock *sk, struct socket *parent)
20862087
rcu_assign_pointer(sk->sk_wq, &parent->wq);
20872088
parent->sk = sk;
20882089
sk_set_socket(sk, parent);
2089-
sk->sk_uid = SOCK_INODE(parent)->i_uid;
2090+
WRITE_ONCE(sk->sk_uid, SOCK_INODE(parent)->i_uid);
20902091
security_sock_graft(sk, parent);
20912092
write_unlock_bh(&sk->sk_callback_lock);
20922093
}
20932094

20942095
kuid_t sock_i_uid(struct sock *sk);
2096+
2097+
static inline kuid_t sk_uid(const struct sock *sk)
2098+
{
2099+
/* Paired with WRITE_ONCE() in sockfs_setattr() */
2100+
return READ_ONCE(sk->sk_uid);
2101+
}
2102+
20952103
unsigned long __sock_i_ino(struct sock *sk);
20962104
unsigned long sock_i_ino(struct sock *sk);
20972105

20982106
static inline kuid_t sock_net_uid(const struct net *net, const struct sock *sk)
20992107
{
2100-
return sk ? sk->sk_uid : make_kuid(net->user_ns, 0);
2108+
return sk ? sk_uid(sk) : make_kuid(net->user_ns, 0);
21012109
}
21022110

21032111
static inline u32 net_tx_rndhash(void)

net/ipv4/inet_connection_sock.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -812,7 +812,7 @@ struct dst_entry *inet_csk_route_req(const struct sock *sk,
812812
sk->sk_protocol, inet_sk_flowi_flags(sk),
813813
(opt && opt->opt.srr) ? opt->opt.faddr : ireq->ir_rmt_addr,
814814
ireq->ir_loc_addr, ireq->ir_rmt_port,
815-
htons(ireq->ir_num), sk->sk_uid);
815+
htons(ireq->ir_num), sk_uid(sk));
816816
security_req_classify_flow(req, flowi4_to_flowi_common(fl4));
817817
rt = ip_route_output_flow(net, fl4, sk);
818818
if (IS_ERR(rt))
@@ -849,7 +849,7 @@ struct dst_entry *inet_csk_route_child_sock(const struct sock *sk,
849849
sk->sk_protocol, inet_sk_flowi_flags(sk),
850850
(opt && opt->opt.srr) ? opt->opt.faddr : ireq->ir_rmt_addr,
851851
ireq->ir_loc_addr, ireq->ir_rmt_port,
852-
htons(ireq->ir_num), sk->sk_uid);
852+
htons(ireq->ir_num), sk_uid(sk));
853853
security_req_classify_flow(req, flowi4_to_flowi_common(fl4));
854854
rt = ip_route_output_flow(net, fl4, sk);
855855
if (IS_ERR(rt))

net/ipv4/ping.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -781,7 +781,7 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
781781
flowi4_init_output(&fl4, ipc.oif, ipc.sockc.mark,
782782
ipc.tos & INET_DSCP_MASK, scope,
783783
sk->sk_protocol, inet_sk_flowi_flags(sk), faddr,
784-
saddr, 0, 0, sk->sk_uid);
784+
saddr, 0, 0, sk_uid(sk));
785785

786786
fl4.fl4_icmp_type = user_icmph.type;
787787
fl4.fl4_icmp_code = user_icmph.code;

net/ipv4/raw.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
610610
hdrincl ? ipc.protocol : sk->sk_protocol,
611611
inet_sk_flowi_flags(sk) |
612612
(hdrincl ? FLOWI_FLAG_KNOWN_NH : 0),
613-
daddr, saddr, 0, 0, sk->sk_uid);
613+
daddr, saddr, 0, 0, sk_uid(sk));
614614

615615
fl4.fl4_icmp_type = 0;
616616
fl4.fl4_icmp_code = 0;

net/ipv4/route.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,8 @@ static void build_sk_flow_key(struct flowi4 *fl4, const struct sock *sk)
556556
inet_test_bit(HDRINCL, sk) ?
557557
IPPROTO_RAW : sk->sk_protocol,
558558
inet_sk_flowi_flags(sk),
559-
daddr, inet->inet_saddr, 0, 0, sk->sk_uid);
559+
daddr, inet->inet_saddr, 0, 0,
560+
sk_uid(sk));
560561
rcu_read_unlock();
561562
}
562563

net/ipv4/syncookies.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
454454
ip_sock_rt_tos(sk), ip_sock_rt_scope(sk),
455455
IPPROTO_TCP, inet_sk_flowi_flags(sk),
456456
opt->srr ? opt->faddr : ireq->ir_rmt_addr,
457-
ireq->ir_loc_addr, th->source, th->dest, sk->sk_uid);
457+
ireq->ir_loc_addr, th->source, th->dest,
458+
sk_uid(sk));
458459
security_req_classify_flow(req, flowi4_to_flowi_common(&fl4));
459460
rt = ip_route_output_key(net, &fl4);
460461
if (IS_ERR(rt)) {

net/ipv4/udp.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1445,7 +1445,8 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
14451445
flowi4_init_output(fl4, ipc.oif, ipc.sockc.mark,
14461446
ipc.tos & INET_DSCP_MASK, scope,
14471447
sk->sk_protocol, flow_flags, faddr, saddr,
1448-
dport, inet->inet_sport, sk->sk_uid);
1448+
dport, inet->inet_sport,
1449+
sk_uid(sk));
14491450

14501451
security_sk_classify_flow(sk, flowi4_to_flowi_common(fl4));
14511452
rt = ip_route_output_flow(net, fl4, sk);

net/ipv6/af_inet6.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -842,7 +842,7 @@ int inet6_sk_rebuild_header(struct sock *sk)
842842
fl6.flowi6_mark = sk->sk_mark;
843843
fl6.fl6_dport = inet->inet_dport;
844844
fl6.fl6_sport = inet->inet_sport;
845-
fl6.flowi6_uid = sk->sk_uid;
845+
fl6.flowi6_uid = sk_uid(sk);
846846
security_sk_classify_flow(sk, flowi6_to_flowi_common(&fl6));
847847

848848
rcu_read_lock();

net/ipv6/datagram.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ static void ip6_datagram_flow_key_init(struct flowi6 *fl6,
5353
fl6->fl6_dport = inet->inet_dport;
5454
fl6->fl6_sport = inet->inet_sport;
5555
fl6->flowlabel = ip6_make_flowinfo(np->tclass, np->flow_label);
56-
fl6->flowi6_uid = sk->sk_uid;
56+
fl6->flowi6_uid = sk_uid(sk);
5757

5858
if (!oif)
5959
oif = np->sticky_pktinfo.ipi6_ifindex;

0 commit comments

Comments
 (0)