summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2012-08-23 02:09:11 +0000
committerWilly Tarreau <w@1wt.eu>2015-09-18 13:51:52 +0200
commit624f4cea32b1f9897b4bf29f12d41295409b0956 (patch)
tree832a23aa2f1c7f892f5b502a3f0aa84c59b43917 /net
parentd447af56f50bdcb4d5ca378ed6b2d48fb0b973ac (diff)
netlink: fix possible spoofing from non-root processes
commit 20e1db19db5d6b9e4e83021595eab0dc8f107bef upstream. Non-root user-space processes can send Netlink messages to other processes that are well-known for being subscribed to Netlink asynchronous notifications. This allows ilegitimate non-root process to send forged messages to Netlink subscribers. The userspace process usually verifies the legitimate origin in two ways: a) Socket credentials. If UID != 0, then the message comes from some ilegitimate process and the message needs to be dropped. b) Netlink portID. In general, portID == 0 means that the origin of the messages comes from the kernel. Thus, discarding any message not coming from the kernel. However, ctnetlink sets the portID in event messages that has been triggered by some user-space process, eg. conntrack utility. So other processes subscribed to ctnetlink events, eg. conntrackd, know that the event was triggered by some user-space action. Neither of the two ways to discard ilegitimate messages coming from non-root processes can help for ctnetlink. This patch adds capability validation in case that dst_pid is set in netlink_sendmsg(). This approach is aggressive since existing applications using any Netlink bus to deliver messages between two user-space processes will break. Note that the exception is NETLINK_USERSOCK, since it is reserved for netlink-to-netlink userspace communication. Still, if anyone wants that his Netlink bus allows netlink-to-netlink userspace, then they can set NL_NONROOT_SEND. However, by default, I don't think it makes sense to allow to use NETLINK_ROUTE to communicate two processes that are sending no matter what information that is not related to link/neighbouring/routing. They should be using NETLINK_USERSOCK instead for that. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: David S. Miller <davem@davemloft.net> [bwh: Backported to 2.6.32: - Adjust context - NETLINK_USERSOCK does not exist, so drop that part] Signed-off-by: Ben Hutchings <ben@decadent.org.uk> CVE-2012-6689 Signed-off-by: Willy Tarreau <w@1wt.eu>
Diffstat (limited to 'net')
-rw-r--r--net/netlink/af_netlink.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 39a6d5d7afcf..223588543093 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1303,7 +1303,8 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
return -EINVAL;
dst_pid = addr->nl_pid;
dst_group = ffs(addr->nl_groups);
- if (dst_group && !netlink_capable(sock, NL_NONROOT_SEND))
+ if ((dst_group || dst_pid) &&
+ !netlink_capable(sock, NL_NONROOT_SEND))
return -EPERM;
} else {
dst_pid = nlk->dst_pid;