Commit 9eea9515 authored by Eric W. Biederman's avatar Eric W. Biederman

userns: nfnetlink_log: Report socket uids in the log sockets user namespace

At logging instance creation capture the peer netlink socket's user
namespace. Use the captured peer user namespace when reporting socket
uids to the peer.

The peer socket's user namespace is guaranateed to be valid until the user
closes the netlink socket.  nfnetlink_log removes instances during the final
close of a socket.  __build_packet_message does not get called after an
instance is destroyed.   Therefore it is safe to let the peer netlink socket
take care of the user namespace reference counting for us.
Acked-by: default avatarDavid S. Miller <davem@davemloft.net>
Acked-by: default avatarSerge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: default avatarEric W. Biederman <ebiederm@xmission.com>
parent d06ca956
...@@ -947,7 +947,6 @@ config UIDGID_CONVERTED ...@@ -947,7 +947,6 @@ config UIDGID_CONVERTED
depends on NETFILTER_XT_MATCH_OWNER = n depends on NETFILTER_XT_MATCH_OWNER = n
depends on NETFILTER_XT_MATCH_RECENT = n depends on NETFILTER_XT_MATCH_RECENT = n
depends on NETFILTER_XT_TARGET_LOG = n depends on NETFILTER_XT_TARGET_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 DNS_RESOLVER = n depends on DNS_RESOLVER = n
......
...@@ -55,6 +55,7 @@ struct nfulnl_instance { ...@@ -55,6 +55,7 @@ struct nfulnl_instance {
unsigned int qlen; /* number of nlmsgs in skb */ unsigned int qlen; /* number of nlmsgs in skb */
struct sk_buff *skb; /* pre-allocatd skb */ struct sk_buff *skb; /* pre-allocatd skb */
struct timer_list timer; struct timer_list timer;
struct user_namespace *peer_user_ns; /* User namespace of the peer process */
int peer_pid; /* PID of the peer process */ int peer_pid; /* PID of the peer process */
/* configurable parameters */ /* configurable parameters */
...@@ -132,7 +133,7 @@ instance_put(struct nfulnl_instance *inst) ...@@ -132,7 +133,7 @@ instance_put(struct nfulnl_instance *inst)
static void nfulnl_timer(unsigned long data); static void nfulnl_timer(unsigned long data);
static struct nfulnl_instance * static struct nfulnl_instance *
instance_create(u_int16_t group_num, int pid) instance_create(u_int16_t group_num, int pid, struct user_namespace *user_ns)
{ {
struct nfulnl_instance *inst; struct nfulnl_instance *inst;
int err; int err;
...@@ -162,6 +163,7 @@ instance_create(u_int16_t group_num, int pid) ...@@ -162,6 +163,7 @@ instance_create(u_int16_t group_num, int pid)
setup_timer(&inst->timer, nfulnl_timer, (unsigned long)inst); setup_timer(&inst->timer, nfulnl_timer, (unsigned long)inst);
inst->peer_user_ns = user_ns;
inst->peer_pid = pid; inst->peer_pid = pid;
inst->group_num = group_num; inst->group_num = group_num;
...@@ -503,8 +505,11 @@ __build_packet_message(struct nfulnl_instance *inst, ...@@ -503,8 +505,11 @@ __build_packet_message(struct nfulnl_instance *inst,
read_lock_bh(&skb->sk->sk_callback_lock); read_lock_bh(&skb->sk->sk_callback_lock);
if (skb->sk->sk_socket && skb->sk->sk_socket->file) { if (skb->sk->sk_socket && skb->sk->sk_socket->file) {
struct file *file = skb->sk->sk_socket->file; struct file *file = skb->sk->sk_socket->file;
__be32 uid = htonl(file->f_cred->fsuid); __be32 uid = htonl(from_kuid_munged(inst->peer_user_ns,
__be32 gid = htonl(file->f_cred->fsgid); file->f_cred->fsuid));
__be32 gid = htonl(from_kgid_munged(inst->peer_user_ns,
file->f_cred->fsgid));
/* need to unlock here since NLA_PUT may goto */
read_unlock_bh(&skb->sk->sk_callback_lock); read_unlock_bh(&skb->sk->sk_callback_lock);
if (nla_put_be32(inst->skb, NFULA_UID, uid) || if (nla_put_be32(inst->skb, NFULA_UID, uid) ||
nla_put_be32(inst->skb, NFULA_GID, gid)) nla_put_be32(inst->skb, NFULA_GID, gid))
...@@ -783,7 +788,8 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, ...@@ -783,7 +788,8 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
} }
inst = instance_create(group_num, inst = instance_create(group_num,
NETLINK_CB(skb).pid); NETLINK_CB(skb).pid,
sk_user_ns(NETLINK_CB(skb).ssk));
if (IS_ERR(inst)) { if (IS_ERR(inst)) {
ret = PTR_ERR(inst); ret = PTR_ERR(inst);
goto out; goto out;
......
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