* [PATCH v2 0/8] Backport to stable-3.4 for fix CVE-2014-0181
@ 2014-07-25 8:22 Wangyufen
2014-07-25 8:22 ` [PATCH v2 1/8] netlink: Make the sending netlink socket availabe in NETLINK_CB Wangyufen
` (8 more replies)
0 siblings, 9 replies; 13+ messages in thread
From: Wangyufen @ 2014-07-25 8:22 UTC (permalink / raw)
To: davem; +Cc: netdev, Wang Yufen
From: Wang Yufen <wangyufen@huawei.com>
Hi David,
This backport fix CVE-2014-0181 which would still be vulnerable in
stable-3.4, please add it.
patchset from 5187cd055b6e to 90f62cf30a78 fixed CVE-2014-0181,
which can't backport to stable-3.4 directly,
Those three patches are needed:
commit 935d8aabd4331f47a89c3e1daa5779d23cf244ee
commit 038e7332b8d4c0629a2965e3ede1a92e8e427bd6
commit 3fbc290540a1ed1a8a076ed8f53bee7a38a9f408
and this patch is unneeded:
commit a53b72c83a4216f2eb883ed45a0cbce014b8e62d
v2:
1) Add the patch:
commit 2d7a85f4b06e9c27ff629f07a524c48074f07f81
which fixes this series to not break applications like Zebra.
2) Change the From: to the original author.
--
1.7.12
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 1/8] netlink: Make the sending netlink socket availabe in NETLINK_CB
2014-07-25 8:22 [PATCH v2 0/8] Backport to stable-3.4 for fix CVE-2014-0181 Wangyufen
@ 2014-07-25 8:22 ` Wangyufen
2014-07-25 8:22 ` [PATCH v2 2/8] userns: make each net (net_ns) belong to a user_ns Wangyufen
` (7 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Wangyufen @ 2014-07-25 8:22 UTC (permalink / raw)
To: davem; +Cc: netdev, Eric W. Biederman, Wang Yufen
From: Eric W. Biederman <ebiederm@xmission.com>
The sending socket of an skb is already available by it's port id
in the NETLINK_CB. If you want to know more like to examine the
credentials on the sending socket you have to look up the sending
socket by it's port id and all of the needed functions and data
structures are static inside of af_netlink.c. So do the simple
thing and pass the sending socket to the receivers in the NETLINK_CB.
I intend to use this to get the user namespace of the sending socket
in inet_diag so that I can report uids in the context of the process
who opened the socket, the same way I report uids in the contect
of the process who opens files.
Acked-by: David S. Miller <davem@davemloft.net>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Wang Yufen <wangyufen@huawei.com>
---
include/linux/netlink.h | 1 +
net/netlink/af_netlink.c | 6 ++++--
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index b23e9cd..af6c763 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -166,6 +166,7 @@ struct netlink_skb_parms {
struct ucred creds; /* Skb credentials */
__u32 pid;
__u32 dst_group;
+ struct sock *ssk;
};
#define NETLINK_CB(skb) (*(struct netlink_skb_parms*)&((skb)->cb))
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index ff960b7..571fc2c 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -899,7 +899,8 @@ static void netlink_rcv_wake(struct sock *sk)
wake_up_interruptible(&nlk->wait);
}
-static int netlink_unicast_kernel(struct sock *sk, struct sk_buff *skb)
+static int netlink_unicast_kernel(struct sock *sk, struct sk_buff *skb,
+ struct sock *ssk)
{
int ret;
struct netlink_sock *nlk = nlk_sk(sk);
@@ -908,6 +909,7 @@ static int netlink_unicast_kernel(struct sock *sk, struct sk_buff *skb)
if (nlk->netlink_rcv != NULL) {
ret = skb->len;
skb_set_owner_r(skb, sk);
+ NETLINK_CB(skb).ssk = ssk;
nlk->netlink_rcv(skb);
}
kfree_skb(skb);
@@ -932,7 +934,7 @@ retry:
return PTR_ERR(sk);
}
if (netlink_is_kernel(sk))
- return netlink_unicast_kernel(sk, skb);
+ return netlink_unicast_kernel(sk, skb, ssk);
if (sk_filter(sk, skb)) {
err = skb->len;
--
1.8.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 2/8] userns: make each net (net_ns) belong to a user_ns
2014-07-25 8:22 [PATCH v2 0/8] Backport to stable-3.4 for fix CVE-2014-0181 Wangyufen
2014-07-25 8:22 ` [PATCH v2 1/8] netlink: Make the sending netlink socket availabe in NETLINK_CB Wangyufen
@ 2014-07-25 8:22 ` Wangyufen
2014-07-25 8:22 ` [PATCH v2 3/8] Add file_ns_capable() helper function for open-time capability checking Wangyufen
` (6 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Wangyufen @ 2014-07-25 8:22 UTC (permalink / raw)
To: davem; +Cc: netdev, Eric W. Biederman, Wang Yufen
From: Eric W. Biederman <ebiederm@xmission.com>
The user namespace which creates a new network namespace owns that
namespace and all resources created in it. This way we can target
capability checks for privileged operations against network resources to
the user_ns which created the network namespace in which the resource
lives. Privilege to the user namespace which owns the network
namespace, or any parent user namespace thereof, provides the same
privilege to the network resource.
This patch is reworked from a version originally by
Serge E. Hallyn <serge.hallyn@canonical.com>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Wang Yufen <wangyufen@huawei.com>
---
include/net/net_namespace.h | 9 +++++++--
kernel/nsproxy.c | 2 +-
net/core/net_namespace.c | 15 +++++++++++----
3 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index ee547c1..9594ef9 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -22,6 +22,7 @@
#endif
#include <net/netns/xfrm.h>
+struct user_namespace;
struct proc_dir_entry;
struct net_device;
struct sock;
@@ -52,6 +53,8 @@ struct net {
struct list_head cleanup_list; /* namespaces on death row */
struct list_head exit_list; /* Use only net_mutex */
+ struct user_namespace *user_ns; /* Owning user namespace */
+
struct proc_dir_entry *proc_net;
struct proc_dir_entry *proc_net_stat;
@@ -110,10 +113,12 @@ struct net {
extern struct net init_net;
#ifdef CONFIG_NET
-extern struct net *copy_net_ns(unsigned long flags, struct net *net_ns);
+extern struct net *copy_net_ns(unsigned long flags,
+ struct user_namespace *user_ns, struct net *old_net);
#else /* CONFIG_NET */
-static inline struct net *copy_net_ns(unsigned long flags, struct net *net_ns)
+static inline struct net *copy_net_ns(unsigned long flags,
+ struct user_namespace *user_ns, struct net *old_net)
{
/* There is nothing to copy so this is a noop */
return net_ns;
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index b576f7f..7e1c3de 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -90,7 +90,7 @@ static struct nsproxy *create_new_namespaces(unsigned long flags,
goto out_pid;
}
- new_nsp->net_ns = copy_net_ns(flags, tsk->nsproxy->net_ns);
+ new_nsp->net_ns = copy_net_ns(flags, task_cred_xxx(tsk, user_ns), tsk->nsproxy->net_ns);
if (IS_ERR(new_nsp->net_ns)) {
err = PTR_ERR(new_nsp->net_ns);
goto out_net;
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index dd00b71..31cc840 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -11,6 +11,7 @@
#include <linux/proc_fs.h>
#include <linux/file.h>
#include <linux/export.h>
+#include <linux/user_namespace.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
@@ -143,7 +144,7 @@ static void ops_free_list(const struct pernet_operations *ops,
/*
* setup_net runs the initializers for the network namespace object.
*/
-static __net_init int setup_net(struct net *net)
+static __net_init int setup_net(struct net *net, struct user_namespace *user_ns)
{
/* Must be called with net_mutex held */
const struct pernet_operations *ops, *saved_ops;
@@ -153,6 +154,7 @@ static __net_init int setup_net(struct net *net)
atomic_set(&net->count, 1);
atomic_set(&net->passive, 1);
net->dev_base_seq = 1;
+ net->user_ns = user_ns;
#ifdef NETNS_REFCNT_DEBUG
atomic_set(&net->use_count, 0);
@@ -230,7 +232,8 @@ void net_drop_ns(void *p)
net_free(ns);
}
-struct net *copy_net_ns(unsigned long flags, struct net *old_net)
+struct net *copy_net_ns(unsigned long flags,
+ struct user_namespace *user_ns, struct net *old_net)
{
struct net *net;
int rv;
@@ -241,8 +244,11 @@ struct net *copy_net_ns(unsigned long flags, struct net *old_net)
net = net_alloc();
if (!net)
return ERR_PTR(-ENOMEM);
+
+ get_user_ns(user_ns);
+
mutex_lock(&net_mutex);
- rv = setup_net(net);
+ rv = setup_net(net, user_ns);
if (rv == 0) {
rtnl_lock();
list_add_tail_rcu(&net->list, &net_namespace_list);
@@ -250,6 +256,7 @@ struct net *copy_net_ns(unsigned long flags, struct net *old_net)
}
mutex_unlock(&net_mutex);
if (rv < 0) {
+ put_user_ns(user_ns);
net_drop_ns(net);
return ERR_PTR(rv);
}
@@ -400,7 +407,7 @@ static int __init net_ns_init(void)
rcu_assign_pointer(init_net.gen, ng);
mutex_lock(&net_mutex);
- if (setup_net(&init_net))
+ if (setup_net(&init_net, &init_user_ns))
panic("Could not setup the initial network namespace");
rtnl_lock();
--
1.8.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 3/8] Add file_ns_capable() helper function for open-time capability checking
2014-07-25 8:22 [PATCH v2 0/8] Backport to stable-3.4 for fix CVE-2014-0181 Wangyufen
2014-07-25 8:22 ` [PATCH v2 1/8] netlink: Make the sending netlink socket availabe in NETLINK_CB Wangyufen
2014-07-25 8:22 ` [PATCH v2 2/8] userns: make each net (net_ns) belong to a user_ns Wangyufen
@ 2014-07-25 8:22 ` Wangyufen
2014-07-25 8:22 ` [PATCH v2 4/8] netlink: Rename netlink_capable netlink_allowed Wangyufen
` (5 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Wangyufen @ 2014-07-25 8:22 UTC (permalink / raw)
To: davem; +Cc: netdev, Linus Torvalds, Wang Yufen
From: Linus Torvalds <torvalds@linux-foundation.org>
Nothing is using it yet, but this will allow us to delay the open-time
checks to use time, without breaking the normal UNIX permission
semantics where permissions are determined by the opener (and the file
descriptor can then be passed to a different process, or the process can
drop capabilities).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Wang Yufen <wangyufen@huawei.com>
---
include/linux/capability.h | 3 ++-
kernel/capability.c | 24 ++++++++++++++++++++++++
2 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/include/linux/capability.h b/include/linux/capability.h
index 12d52de..7273027 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -373,7 +373,7 @@ struct cpu_vfs_cap_data {
#define CAP_TO_MASK(x) (1 << ((x) & 31)) /* mask for indexed __u32 */
#ifdef __KERNEL__
-
+struct file;
struct dentry;
struct user_namespace;
@@ -548,6 +548,7 @@ extern bool has_ns_capability_noaudit(struct task_struct *t,
extern bool capable(int cap);
extern bool ns_capable(struct user_namespace *ns, int cap);
extern bool nsown_capable(int cap);
+extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap);
/* audit system wants to get cap info from files as well */
extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps);
diff --git a/kernel/capability.c b/kernel/capability.c
index 3f1adb6..cc8c4845 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -393,6 +393,30 @@ bool ns_capable(struct user_namespace *ns, int cap)
EXPORT_SYMBOL(ns_capable);
/**
+ * file_ns_capable - Determine if the file's opener had a capability in effect
+ * @file: The file we want to check
+ * @ns: The usernamespace we want the capability in
+ * @cap: The capability to be tested for
+ *
+ * Return true if task that opened the file had a capability in effect
+ * when the file was opened.
+ *
+ * This does not set PF_SUPERPRIV because the caller may not
+ * actually be privileged.
+ */
+bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap)
+{
+ if (WARN_ON_ONCE(!cap_valid(cap)))
+ return false;
+
+ if (security_capable(file->f_cred, ns, cap) == 0)
+ return true;
+
+ return false;
+}
+EXPORT_SYMBOL(file_ns_capable);
+
+/**
* capable - Determine if the current task has a superior capability in effect
* @cap: The capability to be tested for
*
--
1.8.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 4/8] netlink: Rename netlink_capable netlink_allowed
2014-07-25 8:22 [PATCH v2 0/8] Backport to stable-3.4 for fix CVE-2014-0181 Wangyufen
` (2 preceding siblings ...)
2014-07-25 8:22 ` [PATCH v2 3/8] Add file_ns_capable() helper function for open-time capability checking Wangyufen
@ 2014-07-25 8:22 ` Wangyufen
2014-07-25 8:22 ` [PATCH v2 5/8] net: Add variants of capable for use on on sockets Wangyufen
` (4 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Wangyufen @ 2014-07-25 8:22 UTC (permalink / raw)
To: davem; +Cc: netdev, Eric W. Biederman, Wang Yufen
From: "Eric W. Biederman" <ebiederm@xmission.com>
netlink_capable is a static internal function in af_netlink.c and we
have better uses for the name netlink_capable.
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Wang Yufen <wangyufen@huawei.com>
---
net/netlink/af_netlink.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 571fc2c..18b4cc6 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -590,7 +590,7 @@ retry:
return err;
}
-static inline int netlink_capable(const struct socket *sock, unsigned int flag)
+static inline int netlink_allowed(const struct socket *sock, unsigned int flag)
{
return (nl_table[sock->sk->sk_protocol].nl_nonroot & flag) ||
capable(CAP_NET_ADMIN);
@@ -655,7 +655,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
/* Only superuser is allowed to listen multicasts */
if (nladdr->nl_groups) {
- if (!netlink_capable(sock, NL_NONROOT_RECV))
+ if (!netlink_allowed(sock, NL_NONROOT_RECV))
return -EPERM;
err = netlink_realloc_groups(sk);
if (err)
@@ -708,7 +708,7 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
return -EINVAL;
/* Only superuser is allowed to send multicasts */
- if (nladdr->nl_groups && !netlink_capable(sock, NL_NONROOT_SEND))
+ if (nladdr->nl_groups && !netlink_allowed(sock, NL_NONROOT_SEND))
return -EPERM;
if (!nlk->pid)
@@ -1229,7 +1229,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
break;
case NETLINK_ADD_MEMBERSHIP:
case NETLINK_DROP_MEMBERSHIP: {
- if (!netlink_capable(sock, NL_NONROOT_RECV))
+ if (!netlink_allowed(sock, NL_NONROOT_RECV))
return -EPERM;
err = netlink_realloc_groups(sk);
if (err)
@@ -1356,7 +1356,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
dst_group = ffs(addr->nl_groups);
err = -EPERM;
if ((dst_group || dst_pid) &&
- !netlink_capable(sock, NL_NONROOT_SEND))
+ !netlink_allowed(sock, NL_NONROOT_SEND))
goto out;
} else {
dst_pid = nlk->dst_pid;
--
1.8.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 5/8] net: Add variants of capable for use on on sockets
2014-07-25 8:22 [PATCH v2 0/8] Backport to stable-3.4 for fix CVE-2014-0181 Wangyufen
` (3 preceding siblings ...)
2014-07-25 8:22 ` [PATCH v2 4/8] netlink: Rename netlink_capable netlink_allowed Wangyufen
@ 2014-07-25 8:22 ` Wangyufen
2014-07-25 8:22 ` [PATCH v2 6/8] net: Add variants of capable for use on netlink messages Wangyufen
` (3 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Wangyufen @ 2014-07-25 8:22 UTC (permalink / raw)
To: davem; +Cc: netdev, Eric W. Biederman, Wang Yufen
From: "Eric W. Biederman" <ebiederm@xmission.com>
sk_net_capable - The common case, operations that are safe in a network namespace.
sk_capable - Operations that are not known to be safe in a network namespace
sk_ns_capable - The general case for special cases.
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Wang Yufen <wangyufen@huawei.com>
---
include/net/sock.h | 5 +++++
net/core/sock.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 54 insertions(+)
diff --git a/include/net/sock.h b/include/net/sock.h
index f673ba5..8d4046c 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -2148,6 +2148,11 @@ extern void sock_enable_timestamp(struct sock *sk, int flag);
extern int sock_get_timestamp(struct sock *, struct timeval __user *);
extern int sock_get_timestampns(struct sock *, struct timespec __user *);
+bool sk_ns_capable(const struct sock *sk,
+ struct user_namespace *user_ns, int cap);
+bool sk_capable(const struct sock *sk, int cap);
+bool sk_net_capable(const struct sock *sk, int cap);
+
/*
* Enable debug/info messages
*/
diff --git a/net/core/sock.c b/net/core/sock.c
index 832cf04..43854b0 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -139,6 +139,55 @@
static DEFINE_MUTEX(proto_list_mutex);
static LIST_HEAD(proto_list);
+/**
+ * sk_ns_capable - General socket capability test
+ * @sk: Socket to use a capability on or through
+ * @user_ns: The user namespace of the capability to use
+ * @cap: The capability to use
+ *
+ * Test to see if the opener of the socket had when the socket was
+ * created and the current process has the capability @cap in the user
+ * namespace @user_ns.
+ */
+bool sk_ns_capable(const struct sock *sk,
+ struct user_namespace *user_ns, int cap)
+{
+ return file_ns_capable(sk->sk_socket->file, user_ns, cap) &&
+ ns_capable(user_ns, cap);
+}
+EXPORT_SYMBOL(sk_ns_capable);
+
+/**
+ * sk_capable - Socket global capability test
+ * @sk: Socket to use a capability on or through
+ * @cap: The global capbility to use
+ *
+ * Test to see if the opener of the socket had when the socket was
+ * created and the current process has the capability @cap in all user
+ * namespaces.
+ */
+bool sk_capable(const struct sock *sk, int cap)
+{
+ return sk_ns_capable(sk, &init_user_ns, cap);
+}
+EXPORT_SYMBOL(sk_capable);
+
+/**
+ * sk_net_capable - Network namespace socket capability test
+ * @sk: Socket to use a capability on or through
+ * @cap: The capability to use
+ *
+ * Test to see if the opener of the socket had when the socke was created
+ * and the current process has the capability @cap over the network namespace
+ * the socket is a member of.
+ */
+bool sk_net_capable(const struct sock *sk, int cap)
+{
+ return sk_ns_capable(sk, sock_net(sk)->user_ns, cap);
+}
+EXPORT_SYMBOL(sk_net_capable);
+
+
#ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM
int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss)
{
--
1.8.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 6/8] net: Add variants of capable for use on netlink messages
2014-07-25 8:22 [PATCH v2 0/8] Backport to stable-3.4 for fix CVE-2014-0181 Wangyufen
` (4 preceding siblings ...)
2014-07-25 8:22 ` [PATCH v2 5/8] net: Add variants of capable for use on on sockets Wangyufen
@ 2014-07-25 8:22 ` Wangyufen
2014-07-25 8:22 ` [PATCH v2 7/8] net: Use netlink_ns_capable to verify the permisions of " Wangyufen
` (2 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Wangyufen @ 2014-07-25 8:22 UTC (permalink / raw)
To: davem; +Cc: netdev, Eric W. Biederman, Wang Yufen
From: "Eric W. Biederman" <ebiederm@xmission.com>
netlink_net_capable - The common case use, for operations that are safe on a network namespace
netlink_capable - For operations that are only known to be safe for the global root
netlink_ns_capable - The general case of capable used to handle special cases
__netlink_ns_capable - Same as netlink_ns_capable except taking a netlink_skb_parms instead of
the skbuff of a netlink message.
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Wang Yufen <wangyufen@huawei.com>
---
include/linux/netlink.h | 7 ++++++
net/netlink/af_netlink.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 72 insertions(+)
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index af6c763..f4b56b7 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -279,6 +279,13 @@ static inline int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
#define NL_NONROOT_SEND 0x2
extern void netlink_set_nonroot(int protocol, unsigned flag);
+bool __netlink_ns_capable(const struct netlink_skb_parms *nsp,
+ struct user_namespace *ns, int cap);
+bool netlink_ns_capable(const struct sk_buff *skb,
+ struct user_namespace *ns, int cap);
+bool netlink_capable(const struct sk_buff *skb, int cap);
+bool netlink_net_capable(const struct sk_buff *skb, int cap);
+
#endif /* __KERNEL__ */
#endif /* __LINUX_NETLINK_H */
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 18b4cc6..7d3cfc9 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -590,6 +590,71 @@ retry:
return err;
}
+/**
+ * __netlink_ns_capable - General netlink message capability test
+ * @nsp: NETLINK_CB of the socket buffer holding a netlink command from userspace.
+ * @user_ns: The user namespace of the capability to use
+ * @cap: The capability to use
+ *
+ * Test to see if the opener of the socket we received the message
+ * from had when the netlink socket was created and the sender of the
+ * message has has the capability @cap in the user namespace @user_ns.
+ */
+bool __netlink_ns_capable(const struct netlink_skb_parms *nsp,
+ struct user_namespace *user_ns, int cap)
+{
+ return sk_ns_capable(nsp->ssk, user_ns, cap);
+}
+EXPORT_SYMBOL(__netlink_ns_capable);
+
+/**
+ * netlink_ns_capable - General netlink message capability test
+ * @skb: socket buffer holding a netlink command from userspace
+ * @user_ns: The user namespace of the capability to use
+ * @cap: The capability to use
+ *
+ * Test to see if the opener of the socket we received the message
+ * from had when the netlink socket was created and the sender of the
+ * message has has the capability @cap in the user namespace @user_ns.
+ */
+bool netlink_ns_capable(const struct sk_buff *skb,
+ struct user_namespace *user_ns, int cap)
+{
+ return __netlink_ns_capable(&NETLINK_CB(skb), user_ns, cap);
+}
+EXPORT_SYMBOL(netlink_ns_capable);
+
+/**
+ * netlink_capable - Netlink global message capability test
+ * @skb: socket buffer holding a netlink command from userspace
+ * @cap: The capability to use
+ *
+ * Test to see if the opener of the socket we received the message
+ * from had when the netlink socket was created and the sender of the
+ * message has has the capability @cap in all user namespaces.
+ */
+bool netlink_capable(const struct sk_buff *skb, int cap)
+{
+ return netlink_ns_capable(skb, &init_user_ns, cap);
+}
+EXPORT_SYMBOL(netlink_capable);
+
+/**
+ * netlink_net_capable - Netlink network namespace message capability test
+ * @skb: socket buffer holding a netlink command from userspace
+ * @cap: The capability to use
+ *
+ * Test to see if the opener of the socket we received the message
+ * from had when the netlink socket was created and the sender of the
+ * message has has the capability @cap over the network namespace of
+ * the socket we received the message from.
+ */
+bool netlink_net_capable(const struct sk_buff *skb, int cap)
+{
+ return netlink_ns_capable(skb, sock_net(skb->sk)->user_ns, cap);
+}
+EXPORT_SYMBOL(netlink_net_capable);
+
static inline int netlink_allowed(const struct socket *sock, unsigned int flag)
{
return (nl_table[sock->sk->sk_protocol].nl_nonroot & flag) ||
--
1.8.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 7/8] net: Use netlink_ns_capable to verify the permisions of netlink messages
2014-07-25 8:22 [PATCH v2 0/8] Backport to stable-3.4 for fix CVE-2014-0181 Wangyufen
` (5 preceding siblings ...)
2014-07-25 8:22 ` [PATCH v2 6/8] net: Add variants of capable for use on netlink messages Wangyufen
@ 2014-07-25 8:22 ` Wangyufen
2014-07-31 22:06 ` Jonathan Toppins
2014-07-25 8:22 ` [PATCH v2 8/8] netlink: Only check file credentials for implicit destinations Wangyufen
2014-07-29 0:14 ` [PATCH v2 0/8] Backport to stable-3.4 for fix CVE-2014-0181 David Miller
8 siblings, 1 reply; 13+ messages in thread
From: Wangyufen @ 2014-07-25 8:22 UTC (permalink / raw)
To: davem; +Cc: netdev, Eric W. Biederman, Wang Yufen
From: "Eric W. Biederman" <ebiederm@xmission.com>
It is possible by passing a netlink socket to a more privileged
executable and then to fool that executable into writing to the socket
data that happens to be valid netlink message to do something that
privileged executable did not intend to do.
To keep this from happening replace bare capable and ns_capable calls
with netlink_capable, netlink_net_calls and netlink_ns_capable calls.
Which act the same as the previous calls except they verify that the
opener of the socket had the desired permissions as well.
Reported-by: Andy Lutomirski <luto@amacapital.net>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Wang Yufen <wangyufen@huawei.com>
---
crypto/crypto_user.c | 2 +-
drivers/connector/cn_proc.c | 2 +-
drivers/scsi/scsi_netlink.c | 2 +-
kernel/audit.c | 4 ++--
net/core/rtnetlink.c | 2 +-
net/decnet/dn_dev.c | 2 +-
net/decnet/netfilter/dn_rtmsg.c | 2 +-
net/netfilter/nfnetlink.c | 2 +-
net/netlink/genetlink.c | 2 +-
net/phonet/pn_netlink.c | 4 ++--
net/tipc/netlink.c | 2 +-
net/xfrm/xfrm_user.c | 2 +-
12 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 910497b..c86969e 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -452,7 +452,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
type -= CRYPTO_MSG_BASE;
link = &crypto_dispatch[type];
- if (!capable(CAP_NET_ADMIN))
+ if (!netlink_capable(skb, CAP_NET_ADMIN))
return -EPERM;
if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) &&
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 094a710..46856ae 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -332,7 +332,7 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg,
return;
/* Can only change if privileged. */
- if (!capable(CAP_NET_ADMIN)) {
+ if (!__netlink_ns_capable(nsp, &init_user_ns, CAP_NET_ADMIN)) {
err = EPERM;
goto out;
}
diff --git a/drivers/scsi/scsi_netlink.c b/drivers/scsi/scsi_netlink.c
index c77628a..a930b66 100644
--- a/drivers/scsi/scsi_netlink.c
+++ b/drivers/scsi/scsi_netlink.c
@@ -112,7 +112,7 @@ scsi_nl_rcv_msg(struct sk_buff *skb)
goto next_msg;
}
- if (!capable(CAP_SYS_ADMIN)) {
+ if (!netlink_capable(skb, CAP_SYS_ADMIN)) {
err = -EPERM;
goto next_msg;
}
diff --git a/kernel/audit.c b/kernel/audit.c
index b4efae8..3c3a31c 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -601,13 +601,13 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
case AUDIT_TTY_SET:
case AUDIT_TRIM:
case AUDIT_MAKE_EQUIV:
- if (!capable(CAP_AUDIT_CONTROL))
+ if (!netlink_capable(skb, CAP_AUDIT_CONTROL))
err = -EPERM;
break;
case AUDIT_USER:
case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
- if (!capable(CAP_AUDIT_WRITE))
+ if (!netlink_capable(skb, CAP_AUDIT_WRITE))
err = -EPERM;
break;
default: /* bad msg */
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index a133427..d3ac150 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2010,7 +2010,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
sz_idx = type>>2;
kind = type&3;
- if (kind != 2 && !capable(CAP_NET_ADMIN))
+ if (kind != 2 && !netlink_net_capable(skb, CAP_NET_ADMIN))
return -EPERM;
if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index c00e307..b79ce1e 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -440,7 +440,7 @@ int dn_dev_ioctl(unsigned int cmd, void __user *arg)
case SIOCGIFADDR:
break;
case SIOCSIFADDR:
- if (!capable(CAP_NET_ADMIN))
+ if (!netlink_capable(skb, CAP_NET_ADMIN))
return -EACCES;
if (sdn->sdn_family != AF_DECnet)
return -EINVAL;
diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c
index 1531135..dc750e2 100644
--- a/net/decnet/netfilter/dn_rtmsg.c
+++ b/net/decnet/netfilter/dn_rtmsg.c
@@ -108,7 +108,7 @@ static inline void dnrmg_receive_user_skb(struct sk_buff *skb)
if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
return;
- if (!capable(CAP_NET_ADMIN))
+ if (!netlink_capable(skb, CAP_NET_ADMIN))
RCV_SKB_FAIL(-EPERM);
/* Eventually we might send routing messages too */
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index e6ddde1..5cfc865 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -129,7 +129,7 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
const struct nfnetlink_subsystem *ss;
int type, err;
- if (!capable(CAP_NET_ADMIN))
+ if (!netlink_net_capable(skb, CAP_NET_ADMIN))
return -EPERM;
/* All the messages must at least contain nfgenmsg */
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 73d3f0c..dff8562 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -556,7 +556,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
return -EOPNOTSUPP;
if ((ops->flags & GENL_ADMIN_PERM) &&
- !capable(CAP_NET_ADMIN))
+ !netlink_capable(skb, CAP_NET_ADMIN))
return -EPERM;
if (nlh->nlmsg_flags & NLM_F_DUMP) {
diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c
index d61f676..18485cd 100644
--- a/net/phonet/pn_netlink.c
+++ b/net/phonet/pn_netlink.c
@@ -70,7 +70,7 @@ static int addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *attr)
int err;
u8 pnaddr;
- if (!capable(CAP_SYS_ADMIN))
+ if (!netlink_capable(skb, CAP_SYS_ADMIN))
return -EPERM;
ASSERT_RTNL();
@@ -228,7 +228,7 @@ static int route_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *attr)
int err;
u8 dst;
- if (!capable(CAP_SYS_ADMIN))
+ if (!netlink_capable(skb, CAP_SYS_ADMIN))
return -EPERM;
ASSERT_RTNL();
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 7bda8e3..0b4cf4f 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -47,7 +47,7 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info)
int hdr_space = NLMSG_SPACE(GENL_HDRLEN + TIPC_GENL_HDRLEN);
u16 cmd;
- if ((req_userhdr->cmd & 0xC000) && (!capable(CAP_NET_ADMIN)))
+ if ((req_userhdr->cmd & 0xC000) && (!netlink_capable(skb, CAP_NET_ADMIN)))
cmd = TIPC_CMD_NOT_NET_ADMIN;
else
cmd = req_userhdr->cmd;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index c8b903d..ce16eba 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -2317,7 +2317,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
link = &xfrm_dispatch[type];
/* All operations require privileges, even GET */
- if (!capable(CAP_NET_ADMIN))
+ if (!netlink_net_capable(skb, CAP_NET_ADMIN))
return -EPERM;
if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) ||
--
1.8.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 8/8] netlink: Only check file credentials for implicit destinations
2014-07-25 8:22 [PATCH v2 0/8] Backport to stable-3.4 for fix CVE-2014-0181 Wangyufen
` (6 preceding siblings ...)
2014-07-25 8:22 ` [PATCH v2 7/8] net: Use netlink_ns_capable to verify the permisions of " Wangyufen
@ 2014-07-25 8:22 ` Wangyufen
2014-07-29 0:14 ` [PATCH v2 0/8] Backport to stable-3.4 for fix CVE-2014-0181 David Miller
8 siblings, 0 replies; 13+ messages in thread
From: Wangyufen @ 2014-07-25 8:22 UTC (permalink / raw)
To: davem; +Cc: netdev, Eric W. Biederman, stable, Andy Lutomirski, Wang Yufen
From: "Eric W. Biederman" <ebiederm@xmission.com>
It was possible to get a setuid root or setcap executable to write to
it's stdout or stderr (which has been set made a netlink socket) and
inadvertently reconfigure the networking stack.
To prevent this we check that both the creator of the socket and
the currentl applications has permission to reconfigure the network
stack.
Unfortunately this breaks Zebra which always uses sendto/sendmsg
and creates it's socket without any privileges.
To keep Zebra working don't bother checking if the creator of the
socket has privilege when a destination address is specified. Instead
rely exclusively on the privileges of the sender of the socket.
Note from Andy: This is exactly Eric's code except for some comment
clarifications and formatting fixes. Neither I nor, I think, anyone
else is thrilled with this approach, but I'm hesitant to wait on a
better fix since 3.15 is almost here.
Note to stable maintainers: This is a mess. An earlier series of
patches in 3.15 fix a rather serious security issue (CVE-2014-0181),
but they did so in a way that breaks Zebra. The offending series
includes:
commit aa4cf9452f469f16cea8c96283b641b4576d4a7b
Author: Eric W. Biederman <ebiederm@xmission.com>
Date: Wed Apr 23 14:28:03 2014 -0700
net: Add variants of capable for use on netlink messages
If a given kernel version is missing that series of fixes, it's
probably worth backporting it and this patch. if that series is
present, then this fix is critical if you care about Zebra.
Cc: stable@vger.kernel.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Andy Lutomirski <luto@amacapital.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Wang Yufen <wangyufen@huawei.com>
---
include/linux/netlink.h | 3 ++-
net/netlink/af_netlink.c | 7 ++++++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index f4b56b7..dbf29e5 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -166,9 +166,10 @@ struct netlink_skb_parms {
struct ucred creds; /* Skb credentials */
__u32 pid;
__u32 dst_group;
+ __u32 flags;
struct sock *ssk;
};
-
+#define NETLINK_SKB_DST 0x8 /* Dst set in sendto or sendmsg */
#define NETLINK_CB(skb) (*(struct netlink_skb_parms*)&((skb)->cb))
#define NETLINK_CREDS(skb) (&NETLINK_CB((skb)).creds)
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 41d345b..231249e 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -603,7 +603,9 @@ retry:
bool __netlink_ns_capable(const struct netlink_skb_parms *nsp,
struct user_namespace *user_ns, int cap)
{
- return sk_ns_capable(nsp->ssk, user_ns, cap);
+ return ((nsp->flags & NETLINK_SKB_DST) ||
+ file_ns_capable(nsp->ssk->sk_socket->file, user_ns, cap)) &&
+ ns_capable(user_ns, cap);
}
EXPORT_SYMBOL(__netlink_ns_capable);
@@ -1402,6 +1404,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
struct sk_buff *skb;
int err;
struct scm_cookie scm;
+ u32 netlink_skb_flags = 0;
if (msg->msg_flags&MSG_OOB)
return -EOPNOTSUPP;
@@ -1423,6 +1426,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
if ((dst_group || dst_pid) &&
!netlink_allowed(sock, NL_NONROOT_SEND))
goto out;
+ netlink_skb_flags |= NETLINK_SKB_DST;
} else {
dst_pid = nlk->dst_pid;
dst_group = nlk->dst_group;
@@ -1444,6 +1448,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
NETLINK_CB(skb).pid = nlk->pid;
NETLINK_CB(skb).dst_group = dst_group;
+ NETLINK_CB(skb).flags = netlink_skb_flags;
memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
err = -EFAULT;
--
1.8.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v2 0/8] Backport to stable-3.4 for fix CVE-2014-0181
2014-07-25 8:22 [PATCH v2 0/8] Backport to stable-3.4 for fix CVE-2014-0181 Wangyufen
` (7 preceding siblings ...)
2014-07-25 8:22 ` [PATCH v2 8/8] netlink: Only check file credentials for implicit destinations Wangyufen
@ 2014-07-29 0:14 ` David Miller
8 siblings, 0 replies; 13+ messages in thread
From: David Miller @ 2014-07-29 0:14 UTC (permalink / raw)
To: wangyufen; +Cc: netdev
From: Wangyufen <wangyufen@huawei.com>
Date: Fri, 25 Jul 2014 16:22:21 +0800
> From: Wang Yufen <wangyufen@huawei.com>
>
> Hi David,
>
> This backport fix CVE-2014-0181 which would still be vulnerable in
> stable-3.4, please add it.
>
> patchset from 5187cd055b6e to 90f62cf30a78 fixed CVE-2014-0181,
> which can't backport to stable-3.4 directly,
>
> Those three patches are needed:
> commit 935d8aabd4331f47a89c3e1daa5779d23cf244ee
> commit 038e7332b8d4c0629a2965e3ede1a92e8e427bd6
> commit 3fbc290540a1ed1a8a076ed8f53bee7a38a9f408
>
> and this patch is unneeded:
> commit a53b72c83a4216f2eb883ed45a0cbce014b8e62d
>
> v2:
> 1) Add the patch:
> commit 2d7a85f4b06e9c27ff629f07a524c48074f07f81
> which fixes this series to not break applications like Zebra.
>
> 2) Change the From: to the original author.
This looks better, I've queued this series up and will submit it to
-stable soon.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 7/8] net: Use netlink_ns_capable to verify the permisions of netlink messages
2014-07-25 8:22 ` [PATCH v2 7/8] net: Use netlink_ns_capable to verify the permisions of " Wangyufen
@ 2014-07-31 22:06 ` Jonathan Toppins
2014-08-15 7:38 ` wangyufen
0 siblings, 1 reply; 13+ messages in thread
From: Jonathan Toppins @ 2014-07-31 22:06 UTC (permalink / raw)
To: Wangyufen, davem; +Cc: netdev, Eric W. Biederman
[-- Attachment #1: Type: text/plain, Size: 9015 bytes --]
On 7/25/14, 4:22 AM, Wangyufen wrote:
> From: "Eric W. Biederman" <ebiederm@xmission.com>
>
> It is possible by passing a netlink socket to a more privileged
> executable and then to fool that executable into writing to the socket
> data that happens to be valid netlink message to do something that
> privileged executable did not intend to do.
>
> To keep this from happening replace bare capable and ns_capable calls
> with netlink_capable, netlink_net_calls and netlink_ns_capable calls.
> Which act the same as the previous calls except they verify that the
> opener of the socket had the desired permissions as well.
>
> Reported-by: Andy Lutomirski <luto@amacapital.net>
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
> Signed-off-by: David S. Miller <davem@davemloft.net>
> Signed-off-by: Wang Yufen <wangyufen@huawei.com>
> ---
> crypto/crypto_user.c | 2 +-
> drivers/connector/cn_proc.c | 2 +-
> drivers/scsi/scsi_netlink.c | 2 +-
> kernel/audit.c | 4 ++--
> net/core/rtnetlink.c | 2 +-
> net/decnet/dn_dev.c | 2 +-
> net/decnet/netfilter/dn_rtmsg.c | 2 +-
> net/netfilter/nfnetlink.c | 2 +-
> net/netlink/genetlink.c | 2 +-
> net/phonet/pn_netlink.c | 4 ++--
> net/tipc/netlink.c | 2 +-
> net/xfrm/xfrm_user.c | 2 +-
> 12 files changed, 14 insertions(+), 14 deletions(-)
>
> diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
> index 910497b..c86969e 100644
> --- a/crypto/crypto_user.c
> +++ b/crypto/crypto_user.c
> @@ -452,7 +452,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
> type -= CRYPTO_MSG_BASE;
> link = &crypto_dispatch[type];
>
> - if (!capable(CAP_NET_ADMIN))
> + if (!netlink_capable(skb, CAP_NET_ADMIN))
> return -EPERM;
>
> if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) &&
> diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
> index 094a710..46856ae 100644
> --- a/drivers/connector/cn_proc.c
> +++ b/drivers/connector/cn_proc.c
> @@ -332,7 +332,7 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg,
> return;
>
> /* Can only change if privileged. */
> - if (!capable(CAP_NET_ADMIN)) {
> + if (!__netlink_ns_capable(nsp, &init_user_ns, CAP_NET_ADMIN)) {
> err = EPERM;
> goto out;
> }
> diff --git a/drivers/scsi/scsi_netlink.c b/drivers/scsi/scsi_netlink.c
> index c77628a..a930b66 100644
> --- a/drivers/scsi/scsi_netlink.c
> +++ b/drivers/scsi/scsi_netlink.c
> @@ -112,7 +112,7 @@ scsi_nl_rcv_msg(struct sk_buff *skb)
> goto next_msg;
> }
>
> - if (!capable(CAP_SYS_ADMIN)) {
> + if (!netlink_capable(skb, CAP_SYS_ADMIN)) {
> err = -EPERM;
> goto next_msg;
> }
> diff --git a/kernel/audit.c b/kernel/audit.c
> index b4efae8..3c3a31c 100644
> --- a/kernel/audit.c
> +++ b/kernel/audit.c
> @@ -601,13 +601,13 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
> case AUDIT_TTY_SET:
> case AUDIT_TRIM:
> case AUDIT_MAKE_EQUIV:
> - if (!capable(CAP_AUDIT_CONTROL))
> + if (!netlink_capable(skb, CAP_AUDIT_CONTROL))
> err = -EPERM;
> break;
> case AUDIT_USER:
> case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
> case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
> - if (!capable(CAP_AUDIT_WRITE))
> + if (!netlink_capable(skb, CAP_AUDIT_WRITE))
> err = -EPERM;
> break;
> default: /* bad msg */
> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> index a133427..d3ac150 100644
> --- a/net/core/rtnetlink.c
> +++ b/net/core/rtnetlink.c
> @@ -2010,7 +2010,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
> sz_idx = type>>2;
> kind = type&3;
>
> - if (kind != 2 && !capable(CAP_NET_ADMIN))
> + if (kind != 2 && !netlink_net_capable(skb, CAP_NET_ADMIN))
> return -EPERM;
>
> if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
> diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
> index c00e307..b79ce1e 100644
> --- a/net/decnet/dn_dev.c
> +++ b/net/decnet/dn_dev.c
> @@ -440,7 +440,7 @@ int dn_dev_ioctl(unsigned int cmd, void __user *arg)
> case SIOCGIFADDR:
> break;
> case SIOCSIFADDR:
> - if (!capable(CAP_NET_ADMIN))
> + if (!netlink_capable(skb, CAP_NET_ADMIN))
Hello,
I am working on the 3.2 backport based off of these patches and am
getting a compile error here. It appears even the 3.4 series doesn't
compile, snippet of compile log for 3.4 series below:
net/decnet/dn_dev.c: In function ‘dn_dev_ioctl’:
net/decnet/dn_dev.c:443:24: error: ‘skb’ undeclared (first use in this
function)
net/decnet/dn_dev.c:443:24: note: each undeclared identifier is reported
only once for each function it appears in
make[2]: *** [net/decnet/dn_dev.o] Error 1
make[1]: *** [net/decnet] Error 2
jtoppins@debian-devel:~/linux/linux-stable$ git log --oneline -10
a926d22 netlink: Only check file credentials for implicit destinations
070d4a0 net: Use netlink_ns_capable to verify the permisions of netlink
messages
31393c4 net: Add variants of capable for use on netlink messages
45a1d1f net: Add variants of capable for use on on sockets
9f2effc netlink: Rename netlink_capable netlink_allowed
f4d5163 Add file_ns_capable() helper function for open-time capability
checking
3e8d4ac userns: make each net (net_ns) belong to a user_ns
9087c45 netlink: Make the sending netlink socket availabe in NETLINK_CB
82f9c4a Linux 3.4.100
21870a3 iommu/vt-d: Disable translation if already enabled
Am I missing something?
Thanks,
-Jon
> return -EACCES;
> if (sdn->sdn_family != AF_DECnet)
> return -EINVAL;
> diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c
> index 1531135..dc750e2 100644
> --- a/net/decnet/netfilter/dn_rtmsg.c
> +++ b/net/decnet/netfilter/dn_rtmsg.c
> @@ -108,7 +108,7 @@ static inline void dnrmg_receive_user_skb(struct sk_buff *skb)
> if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
> return;
>
> - if (!capable(CAP_NET_ADMIN))
> + if (!netlink_capable(skb, CAP_NET_ADMIN))
> RCV_SKB_FAIL(-EPERM);
>
> /* Eventually we might send routing messages too */
> diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
> index e6ddde1..5cfc865 100644
> --- a/net/netfilter/nfnetlink.c
> +++ b/net/netfilter/nfnetlink.c
> @@ -129,7 +129,7 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
> const struct nfnetlink_subsystem *ss;
> int type, err;
>
> - if (!capable(CAP_NET_ADMIN))
> + if (!netlink_net_capable(skb, CAP_NET_ADMIN))
> return -EPERM;
>
> /* All the messages must at least contain nfgenmsg */
> diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
> index 73d3f0c..dff8562 100644
> --- a/net/netlink/genetlink.c
> +++ b/net/netlink/genetlink.c
> @@ -556,7 +556,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
> return -EOPNOTSUPP;
>
> if ((ops->flags & GENL_ADMIN_PERM) &&
> - !capable(CAP_NET_ADMIN))
> + !netlink_capable(skb, CAP_NET_ADMIN))
> return -EPERM;
>
> if (nlh->nlmsg_flags & NLM_F_DUMP) {
> diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c
> index d61f676..18485cd 100644
> --- a/net/phonet/pn_netlink.c
> +++ b/net/phonet/pn_netlink.c
> @@ -70,7 +70,7 @@ static int addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *attr)
> int err;
> u8 pnaddr;
>
> - if (!capable(CAP_SYS_ADMIN))
> + if (!netlink_capable(skb, CAP_SYS_ADMIN))
> return -EPERM;
>
> ASSERT_RTNL();
> @@ -228,7 +228,7 @@ static int route_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *attr)
> int err;
> u8 dst;
>
> - if (!capable(CAP_SYS_ADMIN))
> + if (!netlink_capable(skb, CAP_SYS_ADMIN))
> return -EPERM;
>
> ASSERT_RTNL();
> diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
> index 7bda8e3..0b4cf4f 100644
> --- a/net/tipc/netlink.c
> +++ b/net/tipc/netlink.c
> @@ -47,7 +47,7 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info)
> int hdr_space = NLMSG_SPACE(GENL_HDRLEN + TIPC_GENL_HDRLEN);
> u16 cmd;
>
> - if ((req_userhdr->cmd & 0xC000) && (!capable(CAP_NET_ADMIN)))
> + if ((req_userhdr->cmd & 0xC000) && (!netlink_capable(skb, CAP_NET_ADMIN)))
> cmd = TIPC_CMD_NOT_NET_ADMIN;
> else
> cmd = req_userhdr->cmd;
> diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
> index c8b903d..ce16eba 100644
> --- a/net/xfrm/xfrm_user.c
> +++ b/net/xfrm/xfrm_user.c
> @@ -2317,7 +2317,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
> link = &xfrm_dispatch[type];
>
> /* All operations require privileges, even GET */
> - if (!capable(CAP_NET_ADMIN))
> + if (!netlink_net_capable(skb, CAP_NET_ADMIN))
> return -EPERM;
>
> if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) ||
>
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 947 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 7/8] net: Use netlink_ns_capable to verify the permisions of netlink messages
2014-07-31 22:06 ` Jonathan Toppins
@ 2014-08-15 7:38 ` wangyufen
2014-08-15 9:24 ` wangyufen
0 siblings, 1 reply; 13+ messages in thread
From: wangyufen @ 2014-08-15 7:38 UTC (permalink / raw)
To: Jonathan Toppins; +Cc: davem, netdev, Eric W. Biederman
On 2014/8/1 6:06, Jonathan Toppins wrote:
> On 7/25/14, 4:22 AM, Wangyufen wrote:
>> From: "Eric W. Biederman" <ebiederm@xmission.com>
>>
>> It is possible by passing a netlink socket to a more privileged
>> executable and then to fool that executable into writing to the socket
>> data that happens to be valid netlink message to do something that
>> privileged executable did not intend to do.
>>
>> To keep this from happening replace bare capable and ns_capable calls
>> with netlink_capable, netlink_net_calls and netlink_ns_capable calls.
>> Which act the same as the previous calls except they verify that the
>> opener of the socket had the desired permissions as well.
>>
>> Reported-by: Andy Lutomirski <luto@amacapital.net>
>> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
>> Signed-off-by: David S. Miller <davem@davemloft.net>
>> Signed-off-by: Wang Yufen <wangyufen@huawei.com>
>> ---
>> crypto/crypto_user.c | 2 +-
>> drivers/connector/cn_proc.c | 2 +-
>> drivers/scsi/scsi_netlink.c | 2 +-
>> kernel/audit.c | 4 ++--
>> net/core/rtnetlink.c | 2 +-
>> net/decnet/dn_dev.c | 2 +-
>> net/decnet/netfilter/dn_rtmsg.c | 2 +-
>> net/netfilter/nfnetlink.c | 2 +-
>> net/netlink/genetlink.c | 2 +-
>> net/phonet/pn_netlink.c | 4 ++--
>> net/tipc/netlink.c | 2 +-
>> net/xfrm/xfrm_user.c | 2 +-
>> 12 files changed, 14 insertions(+), 14 deletions(-)
>>
>> diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
>> index 910497b..c86969e 100644
>> --- a/crypto/crypto_user.c
>> +++ b/crypto/crypto_user.c
>> @@ -452,7 +452,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
>> type -= CRYPTO_MSG_BASE;
>> link = &crypto_dispatch[type];
>>
>> - if (!capable(CAP_NET_ADMIN))
>> + if (!netlink_capable(skb, CAP_NET_ADMIN))
>> return -EPERM;
>>
>> if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) &&
>> diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
>> index 094a710..46856ae 100644
>> --- a/drivers/connector/cn_proc.c
>> +++ b/drivers/connector/cn_proc.c
>> @@ -332,7 +332,7 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg,
>> return;
>>
>> /* Can only change if privileged. */
>> - if (!capable(CAP_NET_ADMIN)) {
>> + if (!__netlink_ns_capable(nsp, &init_user_ns, CAP_NET_ADMIN)) {
>> err = EPERM;
>> goto out;
>> }
>> diff --git a/drivers/scsi/scsi_netlink.c b/drivers/scsi/scsi_netlink.c
>> index c77628a..a930b66 100644
>> --- a/drivers/scsi/scsi_netlink.c
>> +++ b/drivers/scsi/scsi_netlink.c
>> @@ -112,7 +112,7 @@ scsi_nl_rcv_msg(struct sk_buff *skb)
>> goto next_msg;
>> }
>>
>> - if (!capable(CAP_SYS_ADMIN)) {
>> + if (!netlink_capable(skb, CAP_SYS_ADMIN)) {
>> err = -EPERM;
>> goto next_msg;
>> }
>> diff --git a/kernel/audit.c b/kernel/audit.c
>> index b4efae8..3c3a31c 100644
>> --- a/kernel/audit.c
>> +++ b/kernel/audit.c
>> @@ -601,13 +601,13 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
>> case AUDIT_TTY_SET:
>> case AUDIT_TRIM:
>> case AUDIT_MAKE_EQUIV:
>> - if (!capable(CAP_AUDIT_CONTROL))
>> + if (!netlink_capable(skb, CAP_AUDIT_CONTROL))
>> err = -EPERM;
>> break;
>> case AUDIT_USER:
>> case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
>> case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
>> - if (!capable(CAP_AUDIT_WRITE))
>> + if (!netlink_capable(skb, CAP_AUDIT_WRITE))
>> err = -EPERM;
>> break;
>> default: /* bad msg */
>> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
>> index a133427..d3ac150 100644
>> --- a/net/core/rtnetlink.c
>> +++ b/net/core/rtnetlink.c
>> @@ -2010,7 +2010,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
>> sz_idx = type>>2;
>> kind = type&3;
>>
>> - if (kind != 2 && !capable(CAP_NET_ADMIN))
>> + if (kind != 2 && !netlink_net_capable(skb, CAP_NET_ADMIN))
>> return -EPERM;
>>
>> if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
>> diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
>> index c00e307..b79ce1e 100644
>> --- a/net/decnet/dn_dev.c
>> +++ b/net/decnet/dn_dev.c
>> @@ -440,7 +440,7 @@ int dn_dev_ioctl(unsigned int cmd, void __user *arg)
>> case SIOCGIFADDR:
>> break;
>> case SIOCSIFADDR:
>> - if (!capable(CAP_NET_ADMIN))
>> + if (!netlink_capable(skb, CAP_NET_ADMIN))
>
> Hello,
>
> I am working on the 3.2 backport based off of these patches and am
> getting a compile error here. It appears even the 3.4 series doesn't
> compile, snippet of compile log for 3.4 series below:
>
> net/decnet/dn_dev.c: In function ‘dn_dev_ioctl’:
> net/decnet/dn_dev.c:443:24: error: ‘skb’ undeclared (first use in this
> function)
> net/decnet/dn_dev.c:443:24: note: each undeclared identifier is reported
> only once for each function it appears in
> make[2]: *** [net/decnet/dn_dev.o] Error 1
> make[1]: *** [net/decnet] Error 2
>
> jtoppins@debian-devel:~/linux/linux-stable$ git log --oneline -10
> a926d22 netlink: Only check file credentials for implicit destinations
> 070d4a0 net: Use netlink_ns_capable to verify the permisions of netlink
> messages
> 31393c4 net: Add variants of capable for use on netlink messages
> 45a1d1f net: Add variants of capable for use on on sockets
> 9f2effc netlink: Rename netlink_capable netlink_allowed
> f4d5163 Add file_ns_capable() helper function for open-time capability
> checking
> 3e8d4ac userns: make each net (net_ns) belong to a user_ns
> 9087c45 netlink: Make the sending netlink socket availabe in NETLINK_CB
> 82f9c4a Linux 3.4.100
> 21870a3 iommu/vt-d: Disable translation if already enabled
>
> Am I missing something?
>
> Thanks,
> -Jon
>
>
sorry for that, I made a big mistake.
I used the wrong .config file and net/decnet/dn_dev.c did't compiled in.
I checked the patch, there is no need to change net/decnet/dn_dev.c, it's ioctl not netlink.
>> return -EACCES;
>> if (sdn->sdn_family != AF_DECnet)
>> return -EINVAL;
>> diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c
>> index 1531135..dc750e2 100644
>> --- a/net/decnet/netfilter/dn_rtmsg.c
>> +++ b/net/decnet/netfilter/dn_rtmsg.c
>> @@ -108,7 +108,7 @@ static inline void dnrmg_receive_user_skb(struct sk_buff *skb)
>> if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
>> return;
>>
>> - if (!capable(CAP_NET_ADMIN))
>> + if (!netlink_capable(skb, CAP_NET_ADMIN))
>> RCV_SKB_FAIL(-EPERM);
>>
>> /* Eventually we might send routing messages too */
>> diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
>> index e6ddde1..5cfc865 100644
>> --- a/net/netfilter/nfnetlink.c
>> +++ b/net/netfilter/nfnetlink.c
>> @@ -129,7 +129,7 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
>> const struct nfnetlink_subsystem *ss;
>> int type, err;
>>
>> - if (!capable(CAP_NET_ADMIN))
>> + if (!netlink_net_capable(skb, CAP_NET_ADMIN))
>> return -EPERM;
>>
>> /* All the messages must at least contain nfgenmsg */
>> diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
>> index 73d3f0c..dff8562 100644
>> --- a/net/netlink/genetlink.c
>> +++ b/net/netlink/genetlink.c
>> @@ -556,7 +556,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
>> return -EOPNOTSUPP;
>>
>> if ((ops->flags & GENL_ADMIN_PERM) &&
>> - !capable(CAP_NET_ADMIN))
>> + !netlink_capable(skb, CAP_NET_ADMIN))
>> return -EPERM;
>>
>> if (nlh->nlmsg_flags & NLM_F_DUMP) {
>> diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c
>> index d61f676..18485cd 100644
>> --- a/net/phonet/pn_netlink.c
>> +++ b/net/phonet/pn_netlink.c
>> @@ -70,7 +70,7 @@ static int addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *attr)
>> int err;
>> u8 pnaddr;
>>
>> - if (!capable(CAP_SYS_ADMIN))
>> + if (!netlink_capable(skb, CAP_SYS_ADMIN))
>> return -EPERM;
>>
>> ASSERT_RTNL();
>> @@ -228,7 +228,7 @@ static int route_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *attr)
>> int err;
>> u8 dst;
>>
>> - if (!capable(CAP_SYS_ADMIN))
>> + if (!netlink_capable(skb, CAP_SYS_ADMIN))
>> return -EPERM;
>>
>> ASSERT_RTNL();
>> diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
>> index 7bda8e3..0b4cf4f 100644
>> --- a/net/tipc/netlink.c
>> +++ b/net/tipc/netlink.c
>> @@ -47,7 +47,7 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info)
>> int hdr_space = NLMSG_SPACE(GENL_HDRLEN + TIPC_GENL_HDRLEN);
>> u16 cmd;
>>
>> - if ((req_userhdr->cmd & 0xC000) && (!capable(CAP_NET_ADMIN)))
>> + if ((req_userhdr->cmd & 0xC000) && (!netlink_capable(skb, CAP_NET_ADMIN)))
>> cmd = TIPC_CMD_NOT_NET_ADMIN;
>> else
>> cmd = req_userhdr->cmd;
>> diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
>> index c8b903d..ce16eba 100644
>> --- a/net/xfrm/xfrm_user.c
>> +++ b/net/xfrm/xfrm_user.c
>> @@ -2317,7 +2317,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
>> link = &xfrm_dispatch[type];
>>
>> /* All operations require privileges, even GET */
>> - if (!capable(CAP_NET_ADMIN))
>> + if (!netlink_net_capable(skb, CAP_NET_ADMIN))
>> return -EPERM;
>>
>> if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) ||
>>
>
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 7/8] net: Use netlink_ns_capable to verify the permisions of netlink messages
2014-08-15 7:38 ` wangyufen
@ 2014-08-15 9:24 ` wangyufen
0 siblings, 0 replies; 13+ messages in thread
From: wangyufen @ 2014-08-15 9:24 UTC (permalink / raw)
To: Jonathan Toppins; +Cc: davem, netdev, Eric W. Biederman
On 2014/8/15 15:38, wangyufen wrote:
> On 2014/8/1 6:06, Jonathan Toppins wrote:
>> On 7/25/14, 4:22 AM, Wangyufen wrote:
>>> From: "Eric W. Biederman" <ebiederm@xmission.com>
>>>
>>> It is possible by passing a netlink socket to a more privileged
>>> executable and then to fool that executable into writing to the socket
>>> data that happens to be valid netlink message to do something that
>>> privileged executable did not intend to do.
>>>
>>> To keep this from happening replace bare capable and ns_capable calls
>>> with netlink_capable, netlink_net_calls and netlink_ns_capable calls.
>>> Which act the same as the previous calls except they verify that the
>>> opener of the socket had the desired permissions as well.
>>>
>>> Reported-by: Andy Lutomirski <luto@amacapital.net>
>>> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
>>> Signed-off-by: David S. Miller <davem@davemloft.net>
>>> Signed-off-by: Wang Yufen <wangyufen@huawei.com>
>>> ---
>>> crypto/crypto_user.c | 2 +-
>>> drivers/connector/cn_proc.c | 2 +-
>>> drivers/scsi/scsi_netlink.c | 2 +-
>>> kernel/audit.c | 4 ++--
>>> net/core/rtnetlink.c | 2 +-
>>> net/decnet/dn_dev.c | 2 +-
>>> net/decnet/netfilter/dn_rtmsg.c | 2 +-
>>> net/netfilter/nfnetlink.c | 2 +-
>>> net/netlink/genetlink.c | 2 +-
>>> net/phonet/pn_netlink.c | 4 ++--
>>> net/tipc/netlink.c | 2 +-
>>> net/xfrm/xfrm_user.c | 2 +-
>>> 12 files changed, 14 insertions(+), 14 deletions(-)
>>>
>>> diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
>>> index 910497b..c86969e 100644
>>> --- a/crypto/crypto_user.c
>>> +++ b/crypto/crypto_user.c
>>> @@ -452,7 +452,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
>>> type -= CRYPTO_MSG_BASE;
>>> link = &crypto_dispatch[type];
>>>
>>> - if (!capable(CAP_NET_ADMIN))
>>> + if (!netlink_capable(skb, CAP_NET_ADMIN))
>>> return -EPERM;
>>>
>>> if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) &&
>>> diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
>>> index 094a710..46856ae 100644
>>> --- a/drivers/connector/cn_proc.c
>>> +++ b/drivers/connector/cn_proc.c
>>> @@ -332,7 +332,7 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg,
>>> return;
>>>
>>> /* Can only change if privileged. */
>>> - if (!capable(CAP_NET_ADMIN)) {
>>> + if (!__netlink_ns_capable(nsp, &init_user_ns, CAP_NET_ADMIN)) {
>>> err = EPERM;
>>> goto out;
>>> }
>>> diff --git a/drivers/scsi/scsi_netlink.c b/drivers/scsi/scsi_netlink.c
>>> index c77628a..a930b66 100644
>>> --- a/drivers/scsi/scsi_netlink.c
>>> +++ b/drivers/scsi/scsi_netlink.c
>>> @@ -112,7 +112,7 @@ scsi_nl_rcv_msg(struct sk_buff *skb)
>>> goto next_msg;
>>> }
>>>
>>> - if (!capable(CAP_SYS_ADMIN)) {
>>> + if (!netlink_capable(skb, CAP_SYS_ADMIN)) {
>>> err = -EPERM;
>>> goto next_msg;
>>> }
>>> diff --git a/kernel/audit.c b/kernel/audit.c
>>> index b4efae8..3c3a31c 100644
>>> --- a/kernel/audit.c
>>> +++ b/kernel/audit.c
>>> @@ -601,13 +601,13 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
>>> case AUDIT_TTY_SET:
>>> case AUDIT_TRIM:
>>> case AUDIT_MAKE_EQUIV:
>>> - if (!capable(CAP_AUDIT_CONTROL))
>>> + if (!netlink_capable(skb, CAP_AUDIT_CONTROL))
>>> err = -EPERM;
>>> break;
>>> case AUDIT_USER:
>>> case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
>>> case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
>>> - if (!capable(CAP_AUDIT_WRITE))
>>> + if (!netlink_capable(skb, CAP_AUDIT_WRITE))
>>> err = -EPERM;
>>> break;
>>> default: /* bad msg */
>>> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
>>> index a133427..d3ac150 100644
>>> --- a/net/core/rtnetlink.c
>>> +++ b/net/core/rtnetlink.c
>>> @@ -2010,7 +2010,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
>>> sz_idx = type>>2;
>>> kind = type&3;
>>>
>>> - if (kind != 2 && !capable(CAP_NET_ADMIN))
>>> + if (kind != 2 && !netlink_net_capable(skb, CAP_NET_ADMIN))
>>> return -EPERM;
>>>
>>> if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
>>> diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
>>> index c00e307..b79ce1e 100644
>>> --- a/net/decnet/dn_dev.c
>>> +++ b/net/decnet/dn_dev.c
>>> @@ -440,7 +440,7 @@ int dn_dev_ioctl(unsigned int cmd, void __user *arg)
>>> case SIOCGIFADDR:
>>> break;
>>> case SIOCSIFADDR:
>>> - if (!capable(CAP_NET_ADMIN))
>>> + if (!netlink_capable(skb, CAP_NET_ADMIN))
>>
>> Hello,
>>
>> I am working on the 3.2 backport based off of these patches and am
>> getting a compile error here. It appears even the 3.4 series doesn't
>> compile, snippet of compile log for 3.4 series below:
>>
>> net/decnet/dn_dev.c: In function ‘dn_dev_ioctl’:
>> net/decnet/dn_dev.c:443:24: error: ‘skb’ undeclared (first use in this
>> function)
>> net/decnet/dn_dev.c:443:24: note: each undeclared identifier is reported
>> only once for each function it appears in
>> make[2]: *** [net/decnet/dn_dev.o] Error 1
>> make[1]: *** [net/decnet] Error 2
>>
>> jtoppins@debian-devel:~/linux/linux-stable$ git log --oneline -10
>> a926d22 netlink: Only check file credentials for implicit destinations
>> 070d4a0 net: Use netlink_ns_capable to verify the permisions of netlink
>> messages
>> 31393c4 net: Add variants of capable for use on netlink messages
>> 45a1d1f net: Add variants of capable for use on on sockets
>> 9f2effc netlink: Rename netlink_capable netlink_allowed
>> f4d5163 Add file_ns_capable() helper function for open-time capability
>> checking
>> 3e8d4ac userns: make each net (net_ns) belong to a user_ns
>> 9087c45 netlink: Make the sending netlink socket availabe in NETLINK_CB
>> 82f9c4a Linux 3.4.100
>> 21870a3 iommu/vt-d: Disable translation if already enabled
>>
>> Am I missing something?
>>
>> Thanks,
>> -Jon
>>
>>
>
> sorry for that, I made a big mistake.
> I used the wrong .config file and net/decnet/dn_dev.c did't compiled in.
> I checked the patch, there is no need to change net/decnet/dn_dev.c, it's ioctl not netlink.
>
>>> return -EACCES;
>>> if (sdn->sdn_family != AF_DECnet)
>>> return -EINVAL;
>>> diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c
>>> index 1531135..dc750e2 100644
>>> --- a/net/decnet/netfilter/dn_rtmsg.c
>>> +++ b/net/decnet/netfilter/dn_rtmsg.c
>>> @@ -108,7 +108,7 @@ static inline void dnrmg_receive_user_skb(struct sk_buff *skb)
>>> if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
>>> return;
>>>
>>> - if (!capable(CAP_NET_ADMIN))
>>> + if (!netlink_capable(skb, CAP_NET_ADMIN))
>>> RCV_SKB_FAIL(-EPERM);
>>>
>>> /* Eventually we might send routing messages too */
>>> diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
>>> index e6ddde1..5cfc865 100644
>>> --- a/net/netfilter/nfnetlink.c
>>> +++ b/net/netfilter/nfnetlink.c
>>> @@ -129,7 +129,7 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
>>> const struct nfnetlink_subsystem *ss;
>>> int type, err;
>>>
>>> - if (!capable(CAP_NET_ADMIN))
>>> + if (!netlink_net_capable(skb, CAP_NET_ADMIN))
>>> return -EPERM;
>>>
>>> /* All the messages must at least contain nfgenmsg */
>>> diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
>>> index 73d3f0c..dff8562 100644
>>> --- a/net/netlink/genetlink.c
>>> +++ b/net/netlink/genetlink.c
>>> @@ -556,7 +556,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
>>> return -EOPNOTSUPP;
>>>
>>> if ((ops->flags & GENL_ADMIN_PERM) &&
>>> - !capable(CAP_NET_ADMIN))
>>> + !netlink_capable(skb, CAP_NET_ADMIN))
>>> return -EPERM;
>>>
>>> if (nlh->nlmsg_flags & NLM_F_DUMP) {
>>> diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c
>>> index d61f676..18485cd 100644
>>> --- a/net/phonet/pn_netlink.c
>>> +++ b/net/phonet/pn_netlink.c
>>> @@ -70,7 +70,7 @@ static int addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *attr)
>>> int err;
>>> u8 pnaddr;
>>>
>>> - if (!capable(CAP_SYS_ADMIN))
>>> + if (!netlink_capable(skb, CAP_SYS_ADMIN))
>>> return -EPERM;
>>>
>>> ASSERT_RTNL();
>>> @@ -228,7 +228,7 @@ static int route_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *attr)
>>> int err;
>>> u8 dst;
>>>
>>> - if (!capable(CAP_SYS_ADMIN))
>>> + if (!netlink_capable(skb, CAP_SYS_ADMIN))
>>> return -EPERM;
>>>
>>> ASSERT_RTNL();
>>> diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
>>> index 7bda8e3..0b4cf4f 100644
>>> --- a/net/tipc/netlink.c
>>> +++ b/net/tipc/netlink.c
>>> @@ -47,7 +47,7 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info)
>>> int hdr_space = NLMSG_SPACE(GENL_HDRLEN + TIPC_GENL_HDRLEN);
>>> u16 cmd;
>>>
>>> - if ((req_userhdr->cmd & 0xC000) && (!capable(CAP_NET_ADMIN)))
>>> + if ((req_userhdr->cmd & 0xC000) && (!netlink_capable(skb, CAP_NET_ADMIN)))
>>> cmd = TIPC_CMD_NOT_NET_ADMIN;
>>> else
>>> cmd = req_userhdr->cmd;
>>> diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
>>> index c8b903d..ce16eba 100644
>>> --- a/net/xfrm/xfrm_user.c
>>> +++ b/net/xfrm/xfrm_user.c
>>> @@ -2317,7 +2317,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
>>> link = &xfrm_dispatch[type];
>>>
>>> /* All operations require privileges, even GET */
>>> - if (!capable(CAP_NET_ADMIN))
>>> + if (!netlink_net_capable(skb, CAP_NET_ADMIN))
>>> return -EPERM;
>>>
>>> if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) ||
>>>
>>
>>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
> .
>
This patch would be OK, I checked Kconfig, opened menuconfig options
to ensure thoes files be compiled in.
From: "Eric W. Biederman" <ebiederm@xmission.com>
It is possible by passing a netlink socket to a more privileged
executable and then to fool that executable into writing to the socket
data that happens to be valid netlink message to do something that
privileged executable did not intend to do.
To keep this from happening replace bare capable and ns_capable calls
with netlink_capable, netlink_net_calls and netlink_ns_capable calls.
Which act the same as the previous calls except they verify that the
opener of the socket had the desired permissions as well.
Reported-by: Andy Lutomirski <luto@amacapital.net>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Wang Yufen <wangyufen@huawei.com>
---
crypto/crypto_user.c | 2 +-
drivers/connector/cn_proc.c | 2 +-
drivers/scsi/scsi_netlink.c | 2 +-
kernel/audit.c | 4 ++--
net/core/rtnetlink.c | 2 +-
net/decnet/netfilter/dn_rtmsg.c | 2 +-
net/netfilter/nfnetlink.c | 2 +-
net/netlink/genetlink.c | 2 +-
net/phonet/pn_netlink.c | 4 ++--
net/tipc/netlink.c | 2 +-
net/xfrm/xfrm_user.c | 2 +-
11 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 910497b..c86969e 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -452,7 +452,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
type -= CRYPTO_MSG_BASE;
link = &crypto_dispatch[type];
- if (!capable(CAP_NET_ADMIN))
+ if (!netlink_capable(skb, CAP_NET_ADMIN))
return -EPERM;
if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) &&
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 094a710..46856ae 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -332,7 +332,7 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg,
return;
/* Can only change if privileged. */
- if (!capable(CAP_NET_ADMIN)) {
+ if (!__netlink_ns_capable(nsp, &init_user_ns, CAP_NET_ADMIN)) {
err = EPERM;
goto out;
}
diff --git a/drivers/scsi/scsi_netlink.c b/drivers/scsi/scsi_netlink.c
index c77628a..a930b66 100644
--- a/drivers/scsi/scsi_netlink.c
+++ b/drivers/scsi/scsi_netlink.c
@@ -112,7 +112,7 @@ scsi_nl_rcv_msg(struct sk_buff *skb)
goto next_msg;
}
- if (!capable(CAP_SYS_ADMIN)) {
+ if (!netlink_capable(skb, CAP_SYS_ADMIN)) {
err = -EPERM;
goto next_msg;
}
diff --git a/kernel/audit.c b/kernel/audit.c
index b4efae8..3c3a31c 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -601,13 +601,13 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
case AUDIT_TTY_SET:
case AUDIT_TRIM:
case AUDIT_MAKE_EQUIV:
- if (!capable(CAP_AUDIT_CONTROL))
+ if (!netlink_capable(skb, CAP_AUDIT_CONTROL))
err = -EPERM;
break;
case AUDIT_USER:
case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
- if (!capable(CAP_AUDIT_WRITE))
+ if (!netlink_capable(skb, CAP_AUDIT_WRITE))
err = -EPERM;
break;
default: /* bad msg */
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index a133427..d3ac150 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2010,7 +2010,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
sz_idx = type>>2;
kind = type&3;
- if (kind != 2 && !capable(CAP_NET_ADMIN))
+ if (kind != 2 && !netlink_net_capable(skb, CAP_NET_ADMIN))
return -EPERM;
if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c
index 1531135..dc750e2 100644
--- a/net/decnet/netfilter/dn_rtmsg.c
+++ b/net/decnet/netfilter/dn_rtmsg.c
@@ -108,7 +108,7 @@ static inline void dnrmg_receive_user_skb(struct sk_buff *skb)
if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
return;
- if (!capable(CAP_NET_ADMIN))
+ if (!netlink_capable(skb, CAP_NET_ADMIN))
RCV_SKB_FAIL(-EPERM);
/* Eventually we might send routing messages too */
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index e6ddde1..5cfc865 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -129,7 +129,7 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
const struct nfnetlink_subsystem *ss;
int type, err;
- if (!capable(CAP_NET_ADMIN))
+ if (!netlink_net_capable(skb, CAP_NET_ADMIN))
return -EPERM;
/* All the messages must at least contain nfgenmsg */
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 73d3f0c..dff8562 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -556,7 +556,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
return -EOPNOTSUPP;
if ((ops->flags & GENL_ADMIN_PERM) &&
- !capable(CAP_NET_ADMIN))
+ !netlink_capable(skb, CAP_NET_ADMIN))
return -EPERM;
if (nlh->nlmsg_flags & NLM_F_DUMP) {
diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c
index d61f676..18485cd 100644
--- a/net/phonet/pn_netlink.c
+++ b/net/phonet/pn_netlink.c
@@ -70,7 +70,7 @@ static int addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *attr)
int err;
u8 pnaddr;
- if (!capable(CAP_SYS_ADMIN))
+ if (!netlink_capable(skb, CAP_SYS_ADMIN))
return -EPERM;
ASSERT_RTNL();
@@ -228,7 +228,7 @@ static int route_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *attr)
int err;
u8 dst;
- if (!capable(CAP_SYS_ADMIN))
+ if (!netlink_capable(skb, CAP_SYS_ADMIN))
return -EPERM;
ASSERT_RTNL();
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 7bda8e3..0b4cf4f 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -47,7 +47,7 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info)
int hdr_space = NLMSG_SPACE(GENL_HDRLEN + TIPC_GENL_HDRLEN);
u16 cmd;
- if ((req_userhdr->cmd & 0xC000) && (!capable(CAP_NET_ADMIN)))
+ if ((req_userhdr->cmd & 0xC000) && (!netlink_capable(skb, CAP_NET_ADMIN)))
cmd = TIPC_CMD_NOT_NET_ADMIN;
else
cmd = req_userhdr->cmd;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index c8b903d..ce16eba 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -2317,7 +2317,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
link = &xfrm_dispatch[type];
/* All operations require privileges, even GET */
- if (!capable(CAP_NET_ADMIN))
+ if (!netlink_net_capable(skb, CAP_NET_ADMIN))
return -EPERM;
if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) ||
--
1.8.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
end of thread, other threads:[~2014-08-15 9:25 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-07-25 8:22 [PATCH v2 0/8] Backport to stable-3.4 for fix CVE-2014-0181 Wangyufen
2014-07-25 8:22 ` [PATCH v2 1/8] netlink: Make the sending netlink socket availabe in NETLINK_CB Wangyufen
2014-07-25 8:22 ` [PATCH v2 2/8] userns: make each net (net_ns) belong to a user_ns Wangyufen
2014-07-25 8:22 ` [PATCH v2 3/8] Add file_ns_capable() helper function for open-time capability checking Wangyufen
2014-07-25 8:22 ` [PATCH v2 4/8] netlink: Rename netlink_capable netlink_allowed Wangyufen
2014-07-25 8:22 ` [PATCH v2 5/8] net: Add variants of capable for use on on sockets Wangyufen
2014-07-25 8:22 ` [PATCH v2 6/8] net: Add variants of capable for use on netlink messages Wangyufen
2014-07-25 8:22 ` [PATCH v2 7/8] net: Use netlink_ns_capable to verify the permisions of " Wangyufen
2014-07-31 22:06 ` Jonathan Toppins
2014-08-15 7:38 ` wangyufen
2014-08-15 9:24 ` wangyufen
2014-07-25 8:22 ` [PATCH v2 8/8] netlink: Only check file credentials for implicit destinations Wangyufen
2014-07-29 0:14 ` [PATCH v2 0/8] Backport to stable-3.4 for fix CVE-2014-0181 David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).