diff options
| author | Lorenzo Colitti <lorenzo@google.com> | 2016-11-04 02:23:41 +0900 |
|---|---|---|
| committer | Mister Oyster <oysterized@gmail.com> | 2017-05-23 13:25:26 +0200 |
| commit | 3f247e26f4579632cea6868834463d3382c2de58 (patch) | |
| tree | e870d4ed8be28ebc6ef89ac1ba4dd8066f33e7f9 /include/net | |
| parent | 9f5fbeef8825a771077032c79258073722b53d8e (diff) | |
net: core: Add a UID field to struct sock.
Protocol sockets (struct sock) don't have UIDs, but most of the
time, they map 1:1 to userspace sockets (struct socket) which do.
Various operations such as the iptables xt_owner match need
access to the "UID of a socket", and do so by following the
backpointer to the struct socket. This involves taking
sk_callback_lock and doesn't work when there is no socket
because userspace has already called close().
Simplify this by adding a sk_uid field to struct sock whose value
matches the UID of the corresponding struct socket. The semantics
are as follows:
1. Whenever sk_socket is non-null: sk_uid is the same as the UID
in sk_socket, i.e., matches the return value of sock_i_uid.
Specifically, the UID is set when userspace calls socket(),
fchown(), or accept().
2. When sk_socket is NULL, sk_uid is defined as follows:
- For a socket that no longer has a sk_socket because
userspace has called close(): the previous UID.
- For a cloned socket (e.g., an incoming connection that is
established but on which userspace has not yet called
accept): the UID of the socket it was cloned from.
- For a socket that has never had an sk_socket: UID 0 inside
the user namespace corresponding to the network namespace
the socket belongs to.
Kernel sockets created by sock_create_kern are a special case
of #1 and sk_uid is the user that created them. For kernel
sockets created at network namespace creation time, such as the
per-processor ICMP and TCP sockets, this is the user that created
the network namespace.
[Backport of net-next 86741ec25462e4c8cdce6df2f41ead05568c7d5e]
Bug: 16355602
Change-Id: Idbc3e9a0cec91c4c6e01916b967b6237645ebe59
Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net')
| -rw-r--r-- | include/net/sock.h | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/include/net/sock.h b/include/net/sock.h index ae1509860..1fa662430 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -394,6 +394,7 @@ struct sock { void *sk_security; #endif __u32 sk_mark; + kuid_t sk_uid; u32 sk_classid; struct cg_proto *sk_cgrp; void (*sk_state_change)(struct sock *sk); @@ -1733,6 +1734,7 @@ static inline void sock_graft(struct sock *sk, struct socket *parent) sk->sk_wq = parent->wq; parent->sk = sk; sk_set_socket(sk, parent); + sk->sk_uid = SOCK_INODE(parent)->i_uid; security_sock_graft(sk, parent); write_unlock_bh(&sk->sk_callback_lock); } @@ -1740,6 +1742,11 @@ static inline void sock_graft(struct sock *sk, struct socket *parent) extern kuid_t sock_i_uid(struct sock *sk); extern unsigned long sock_i_ino(struct sock *sk); +static inline kuid_t sock_net_uid(const struct net *net, const struct sock *sk) +{ + return sk ? sk->sk_uid : make_kuid(net->user_ns, 0); +} + static inline struct dst_entry * __sk_dst_get(struct sock *sk) { |
