[lkml]   [2012]   [Sep]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    Patch in this message
    Subject[ 071/135] netlink: fix possible spoofing from non-root processes
    3.2-stable review patch.  If anyone has any objections, please let me know.


    From: Pablo Neira Ayuso <>

    [ Upstream commit 20e1db19db5d6b9e4e83021595eab0dc8f107bef ]

    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 <>
    Signed-off-by: David S. Miller <>
    Signed-off-by: Ben Hutchings <>
    net/netlink/af_netlink.c | 4 +++-
    1 file changed, 3 insertions(+), 1 deletion(-)

    diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
    index 1af8542..38b78b9 100644
    --- a/net/netlink/af_netlink.c
    +++ b/net/netlink/af_netlink.c
    @@ -1344,7 +1344,8 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
    dst_pid = addr->nl_pid;
    dst_group = ffs(addr->nl_groups);
    err = -EPERM;
    - if (dst_group && !netlink_capable(sock, NL_NONROOT_SEND))
    + if ((dst_group || dst_pid) &&
    + !netlink_capable(sock, NL_NONROOT_SEND))
    goto out;
    } else {
    dst_pid = nlk->dst_pid;
    @@ -2103,6 +2104,7 @@ static void __init netlink_add_usersock_entry(void)
    rcu_assign_pointer(nl_table[NETLINK_USERSOCK].listeners, listeners);
    nl_table[NETLINK_USERSOCK].module = THIS_MODULE;
    nl_table[NETLINK_USERSOCK].registered = 1;
    + nl_table[NETLINK_USERSOCK].nl_nonroot = NL_NONROOT_SEND;


     \ /
      Last update: 2012-09-17 04:01    [W:0.023 / U:52.224 seconds]
    ©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site