Commit d06ca956 authored by Eric W. Biederman's avatar Eric W. Biederman

userns: Teach inet_diag to work with user namespaces

Compute the user namespace of the socket that we are replying to
and translate the kuids of reported sockets into that user namespace.

Cc: Andrew Vagin <avagin@openvz.org>
Acked-by: default avatarDavid S. Miller <davem@davemloft.net>
Acked-by: default avatarPavel Emelyanov <xemul@parallels.com>
Acked-by: default avatarSerge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: default avatarEric W. Biederman <ebiederm@xmission.com>
parent c336d148
...@@ -159,6 +159,7 @@ struct inet_diag_handler { ...@@ -159,6 +159,7 @@ struct inet_diag_handler {
struct inet_connection_sock; struct inet_connection_sock;
int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
struct sk_buff *skb, struct inet_diag_req_v2 *req, struct sk_buff *skb, struct inet_diag_req_v2 *req,
struct user_namespace *user_ns,
u32 pid, u32 seq, u16 nlmsg_flags, u32 pid, u32 seq, u16 nlmsg_flags,
const struct nlmsghdr *unlh); const struct nlmsghdr *unlh);
void inet_diag_dump_icsk(struct inet_hashinfo *h, struct sk_buff *skb, void inet_diag_dump_icsk(struct inet_hashinfo *h, struct sk_buff *skb,
......
...@@ -950,7 +950,6 @@ config UIDGID_CONVERTED ...@@ -950,7 +950,6 @@ config UIDGID_CONVERTED
depends on NETFILTER_NETLINK_LOG = n depends on NETFILTER_NETLINK_LOG = n
depends on AF_RXRPC = n depends on AF_RXRPC = n
depends on NET_KEY = n depends on NET_KEY = n
depends on INET_DIAG = n
depends on DNS_RESOLVER = n depends on DNS_RESOLVER = n
# Filesystems # Filesystems
......
...@@ -69,6 +69,7 @@ static inline void inet_diag_unlock_handler( ...@@ -69,6 +69,7 @@ static inline void inet_diag_unlock_handler(
int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
struct sk_buff *skb, struct inet_diag_req_v2 *req, struct sk_buff *skb, struct inet_diag_req_v2 *req,
struct user_namespace *user_ns,
u32 pid, u32 seq, u16 nlmsg_flags, u32 pid, u32 seq, u16 nlmsg_flags,
const struct nlmsghdr *unlh) const struct nlmsghdr *unlh)
{ {
...@@ -124,7 +125,7 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, ...@@ -124,7 +125,7 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
} }
#endif #endif
r->idiag_uid = sock_i_uid(sk); r->idiag_uid = from_kuid_munged(user_ns, sock_i_uid(sk));
r->idiag_inode = sock_i_ino(sk); r->idiag_inode = sock_i_ino(sk);
if (ext & (1 << (INET_DIAG_MEMINFO - 1))) { if (ext & (1 << (INET_DIAG_MEMINFO - 1))) {
...@@ -199,11 +200,12 @@ EXPORT_SYMBOL_GPL(inet_sk_diag_fill); ...@@ -199,11 +200,12 @@ EXPORT_SYMBOL_GPL(inet_sk_diag_fill);
static int inet_csk_diag_fill(struct sock *sk, static int inet_csk_diag_fill(struct sock *sk,
struct sk_buff *skb, struct inet_diag_req_v2 *req, struct sk_buff *skb, struct inet_diag_req_v2 *req,
struct user_namespace *user_ns,
u32 pid, u32 seq, u16 nlmsg_flags, u32 pid, u32 seq, u16 nlmsg_flags,
const struct nlmsghdr *unlh) const struct nlmsghdr *unlh)
{ {
return inet_sk_diag_fill(sk, inet_csk(sk), return inet_sk_diag_fill(sk, inet_csk(sk),
skb, req, pid, seq, nlmsg_flags, unlh); skb, req, user_ns, pid, seq, nlmsg_flags, unlh);
} }
static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
...@@ -256,14 +258,16 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, ...@@ -256,14 +258,16 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
} }
static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, static int sk_diag_fill(struct sock *sk, struct sk_buff *skb,
struct inet_diag_req_v2 *r, u32 pid, u32 seq, u16 nlmsg_flags, struct inet_diag_req_v2 *r,
struct user_namespace *user_ns,
u32 pid, u32 seq, u16 nlmsg_flags,
const struct nlmsghdr *unlh) const struct nlmsghdr *unlh)
{ {
if (sk->sk_state == TCP_TIME_WAIT) if (sk->sk_state == TCP_TIME_WAIT)
return inet_twsk_diag_fill((struct inet_timewait_sock *)sk, return inet_twsk_diag_fill((struct inet_timewait_sock *)sk,
skb, r, pid, seq, nlmsg_flags, skb, r, pid, seq, nlmsg_flags,
unlh); unlh);
return inet_csk_diag_fill(sk, skb, r, pid, seq, nlmsg_flags, unlh); return inet_csk_diag_fill(sk, skb, r, user_ns, pid, seq, nlmsg_flags, unlh);
} }
int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_skb, int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_skb,
...@@ -311,6 +315,7 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_s ...@@ -311,6 +315,7 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_s
} }
err = sk_diag_fill(sk, rep, req, err = sk_diag_fill(sk, rep, req,
sk_user_ns(NETLINK_CB(in_skb).ssk),
NETLINK_CB(in_skb).pid, NETLINK_CB(in_skb).pid,
nlh->nlmsg_seq, 0, nlh); nlh->nlmsg_seq, 0, nlh);
if (err < 0) { if (err < 0) {
...@@ -551,6 +556,7 @@ static int inet_csk_diag_dump(struct sock *sk, ...@@ -551,6 +556,7 @@ static int inet_csk_diag_dump(struct sock *sk,
return 0; return 0;
return inet_csk_diag_fill(sk, skb, r, return inet_csk_diag_fill(sk, skb, r,
sk_user_ns(NETLINK_CB(cb->skb).ssk),
NETLINK_CB(cb->skb).pid, NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh); cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh);
} }
...@@ -591,7 +597,9 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw, ...@@ -591,7 +597,9 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw,
} }
static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk,
struct request_sock *req, u32 pid, u32 seq, struct request_sock *req,
struct user_namespace *user_ns,
u32 pid, u32 seq,
const struct nlmsghdr *unlh) const struct nlmsghdr *unlh)
{ {
const struct inet_request_sock *ireq = inet_rsk(req); const struct inet_request_sock *ireq = inet_rsk(req);
...@@ -625,7 +633,7 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, ...@@ -625,7 +633,7 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk,
r->idiag_expires = jiffies_to_msecs(tmo); r->idiag_expires = jiffies_to_msecs(tmo);
r->idiag_rqueue = 0; r->idiag_rqueue = 0;
r->idiag_wqueue = 0; r->idiag_wqueue = 0;
r->idiag_uid = sock_i_uid(sk); r->idiag_uid = from_kuid_munged(user_ns, sock_i_uid(sk));
r->idiag_inode = 0; r->idiag_inode = 0;
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
if (r->idiag_family == AF_INET6) { if (r->idiag_family == AF_INET6) {
...@@ -702,6 +710,7 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, ...@@ -702,6 +710,7 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk,
} }
err = inet_diag_fill_req(skb, sk, req, err = inet_diag_fill_req(skb, sk, req,
sk_user_ns(NETLINK_CB(cb->skb).ssk),
NETLINK_CB(cb->skb).pid, NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq, cb->nlh); cb->nlh->nlmsg_seq, cb->nlh);
if (err < 0) { if (err < 0) {
......
...@@ -24,7 +24,9 @@ static int sk_diag_dump(struct sock *sk, struct sk_buff *skb, ...@@ -24,7 +24,9 @@ static int sk_diag_dump(struct sock *sk, struct sk_buff *skb,
if (!inet_diag_bc_sk(bc, sk)) if (!inet_diag_bc_sk(bc, sk))
return 0; return 0;
return inet_sk_diag_fill(sk, NULL, skb, req, NETLINK_CB(cb->skb).pid, return inet_sk_diag_fill(sk, NULL, skb, req,
sk_user_ns(NETLINK_CB(cb->skb).ssk),
NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh); cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh);
} }
...@@ -69,6 +71,7 @@ static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb, ...@@ -69,6 +71,7 @@ static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb,
goto out; goto out;
err = inet_sk_diag_fill(sk, NULL, rep, req, err = inet_sk_diag_fill(sk, NULL, rep, req,
sk_user_ns(NETLINK_CB(in_skb).ssk),
NETLINK_CB(in_skb).pid, NETLINK_CB(in_skb).pid,
nlh->nlmsg_seq, 0, nlh); nlh->nlmsg_seq, 0, nlh);
if (err < 0) { if (err < 0) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment