Message ID | 1477588841-140767-2-git-send-email-lorenzo@google.com |
---|---|
State | Changes Requested, archived |
Delegated to: | David Miller |
Headers | show |
On Fri, 2016-10-28 at 02:20 +0900, Lorenzo Colitti wrote: > diff --git a/net/core/sock.c b/net/core/sock.c > index d8e4532e..831e4e8 100644 > --- a/net/core/sock.c > +++ b/net/core/sock.c > @@ -1570,6 +1570,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) > */ > sk_refcnt_debug_inc(newsk); > sk_set_socket(newsk, NULL); > + newsk->sk_uid = sk->sk_uid; Not sure why this is needed ? sk_clone_lock() already copies sk to newsk, using sock_copy(newsk, sk); > newsk->sk_wq = NULL; > > if (newsk->sk_prot->sockets_allocated) > @@ -2460,8 +2461,11 @@ void sock_init_data(struct socket *sock, struct sock *sk)
Hi Lorenzo,
[auto build test WARNING on net-next/master]
url: https://github.com/0day-ci/linux/commits/Lorenzo-Colitti/net-core-Add-a-UID-field-to-struct-sock/20161028-020552
reproduce: make htmldocs
All warnings (new ones prefixed by >>):
include/linux/skbuff.h:947: warning: No description found for parameter 'sk'
include/net/sock.h:450: warning: No description found for parameter 'sk_padding'
>> include/net/sock.h:450: warning: No description found for parameter 'sk_uid'
include/net/sock.h:450: warning: No description found for parameter 'sk_rcu'
include/linux/netdevice.h:1902: warning: No description found for parameter 'prio_tc_map[TC_BITMASK + 1]'
vim +/sk_uid +450 include/net/sock.h
ef64a54f6 Pavel Emelyanov 2012-02-21 434 __s32 sk_peek_off;
^1da177e4 Linus Torvalds 2005-04-16 435 int sk_write_pending;
d5f642384 Alexey Dobriyan 2008-11-04 436 #ifdef CONFIG_SECURITY
^1da177e4 Linus Torvalds 2005-04-16 437 void *sk_security;
d5f642384 Alexey Dobriyan 2008-11-04 438 #endif
2a56a1fec Tejun Heo 2015-12-07 439 struct sock_cgroup_data sk_cgrp_data;
baac50bbc Johannes Weiner 2016-01-14 440 struct mem_cgroup *sk_memcg;
^1da177e4 Linus Torvalds 2005-04-16 441 void (*sk_state_change)(struct sock *sk);
676d23690 David S. Miller 2014-04-11 442 void (*sk_data_ready)(struct sock *sk);
^1da177e4 Linus Torvalds 2005-04-16 443 void (*sk_write_space)(struct sock *sk);
^1da177e4 Linus Torvalds 2005-04-16 444 void (*sk_error_report)(struct sock *sk);
^1da177e4 Linus Torvalds 2005-04-16 445 int (*sk_backlog_rcv)(struct sock *sk,
^1da177e4 Linus Torvalds 2005-04-16 446 struct sk_buff *skb);
^1da177e4 Linus Torvalds 2005-04-16 447 void (*sk_destruct)(struct sock *sk);
ef456144d Craig Gallek 2016-01-04 448 struct sock_reuseport __rcu *sk_reuseport_cb;
a4298e452 Eric Dumazet 2016-04-01 449 struct rcu_head sk_rcu;
^1da177e4 Linus Torvalds 2005-04-16 @450 };
^1da177e4 Linus Torvalds 2005-04-16 451
559835ea7 Pravin B Shelar 2013-09-24 452 #define __sk_user_data(sk) ((*((void __rcu **)&(sk)->sk_user_data)))
559835ea7 Pravin B Shelar 2013-09-24 453
559835ea7 Pravin B Shelar 2013-09-24 454 #define rcu_dereference_sk_user_data(sk) rcu_dereference(__sk_user_data((sk)))
559835ea7 Pravin B Shelar 2013-09-24 455 #define rcu_assign_sk_user_data(sk, ptr) rcu_assign_pointer(__sk_user_data((sk)), ptr)
559835ea7 Pravin B Shelar 2013-09-24 456
4a17fd522 Pavel Emelyanov 2012-04-19 457 /*
4a17fd522 Pavel Emelyanov 2012-04-19 458 * SK_CAN_REUSE and SK_NO_REUSE on a socket mean that the socket is OK
:::::: The code at line 450 was first introduced by commit
:::::: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2
:::::: TO: Linus Torvalds <torvalds@ppc970.osdl.org>
:::::: CC: Linus Torvalds <torvalds@ppc970.osdl.org>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
From: Eric Dumazet <eric.dumazet@gmail.com> Date: Thu, 27 Oct 2016 10:36:26 -0700 > On Fri, 2016-10-28 at 02:20 +0900, Lorenzo Colitti wrote: > >> diff --git a/net/core/sock.c b/net/core/sock.c >> index d8e4532e..831e4e8 100644 >> --- a/net/core/sock.c >> +++ b/net/core/sock.c >> @@ -1570,6 +1570,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) >> */ >> sk_refcnt_debug_inc(newsk); >> sk_set_socket(newsk, NULL); >> + newsk->sk_uid = sk->sk_uid; > > Not sure why this is needed ? > > sk_clone_lock() already copies sk to newsk, using sock_copy(newsk, sk); Agreed.
diff --git a/include/net/sock.h b/include/net/sock.h index 2764895..2086922 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -417,6 +417,7 @@ struct sock { u32 sk_max_ack_backlog; __u32 sk_priority; __u32 sk_mark; + kuid_t sk_uid; struct pid *sk_peer_pid; const struct cred *sk_peer_cred; long sk_rcvtimeo; @@ -1651,6 +1652,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); } @@ -1658,6 +1660,11 @@ static inline void sock_graft(struct sock *sk, struct socket *parent) kuid_t sock_i_uid(struct sock *sk); unsigned long sock_i_ino(struct sock *sk); +static inline kuid_t sock_net_uid(struct net *net, const struct sock *sk) +{ + return sk ? sk->sk_uid : make_kuid(net->user_ns, 0); +} + static inline u32 net_tx_rndhash(void) { u32 v = prandom_u32(); diff --git a/net/core/sock.c b/net/core/sock.c index d8e4532e..831e4e8 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1570,6 +1570,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) */ sk_refcnt_debug_inc(newsk); sk_set_socket(newsk, NULL); + newsk->sk_uid = sk->sk_uid; newsk->sk_wq = NULL; if (newsk->sk_prot->sockets_allocated) @@ -2460,8 +2461,11 @@ void sock_init_data(struct socket *sock, struct sock *sk) sk->sk_type = sock->type; sk->sk_wq = sock->wq; sock->sk = sk; - } else + sk->sk_uid = SOCK_INODE(sock)->i_uid; + } else { sk->sk_wq = NULL; + sk->sk_uid = make_kuid(sock_net(sk)->user_ns, 0); + } rwlock_init(&sk->sk_callback_lock); lockdep_set_class_and_name(&sk->sk_callback_lock, diff --git a/net/socket.c b/net/socket.c index 5a9bf5e..5a4747e 100644 --- a/net/socket.c +++ b/net/socket.c @@ -518,8 +518,22 @@ static ssize_t sockfs_listxattr(struct dentry *dentry, char *buffer, return used; } +int sockfs_setattr(struct dentry *dentry, struct iattr *iattr) +{ + int err = simple_setattr(dentry, iattr); + + if (!err) { + struct socket *sock = SOCKET_I(d_inode(dentry)); + + sock->sk->sk_uid = iattr->ia_uid; + } + + return err; +} + static const struct inode_operations sockfs_inode_ops = { .listxattr = sockfs_listxattr, + .setattr = sockfs_setattr, }; /**
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 (e.g., a kernel ICMP socket): UID 0 inside the user namespace corresponding to the network namespace the socket belongs to. This is arguably better than GLOBAL_ROOT_UID because it allows "--owner-uid 0" to match kernel-originated packets in non-root namespaces. Signed-off-by: Lorenzo Colitti <lorenzo@google.com> --- include/net/sock.h | 7 +++++++ net/core/sock.c | 6 +++++- net/socket.c | 14 ++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-)