lkml.org 
[lkml]   [2012]   [Aug]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[ 092/109] net: fix rtnetlink IFF_PROMISC and IFF_ALLMULTI handling
    Date
    From: Greg KH <gregkh@linuxfoundation.org>

    3.4-stable review patch. If anyone has any objections, please let me know.

    ------------------


    From: Jiri Benc <jbenc@redhat.com>

    [ Upstream commit b1beb681cba5358f62e6187340660ade226a5fcc ]

    When device flags are set using rtnetlink, IFF_PROMISC and IFF_ALLMULTI
    flags are handled specially. Function dev_change_flags sets IFF_PROMISC and
    IFF_ALLMULTI bits in dev->gflags according to the passed value but
    do_setlink passes a result of rtnl_dev_combine_flags which takes those bits
    from dev->flags.

    This can be easily trigerred by doing:

    tcpdump -i eth0 &
    ip l s up eth0

    ip sets IFF_UP flag in ifi_flags and ifi_change, which is combined with
    IFF_PROMISC by rtnl_dev_combine_flags, causing __dev_change_flags to set
    IFF_PROMISC in gflags.

    Reported-by: Max Matveev <makc@redhat.com>
    Signed-off-by: Jiri Benc <jbenc@redhat.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    net/core/rtnetlink.c | 8 +++++++-
    1 file changed, 7 insertions(+), 1 deletion(-)

    --- a/net/core/rtnetlink.c
    +++ b/net/core/rtnetlink.c
    @@ -671,6 +671,12 @@ static void set_operstate(struct net_dev
    }
    }

    +static unsigned int rtnl_dev_get_flags(const struct net_device *dev)
    +{
    + return (dev->flags & ~(IFF_PROMISC | IFF_ALLMULTI)) |
    + (dev->gflags & (IFF_PROMISC | IFF_ALLMULTI));
    +}
    +
    static unsigned int rtnl_dev_combine_flags(const struct net_device *dev,
    const struct ifinfomsg *ifm)
    {
    @@ -679,7 +685,7 @@ static unsigned int rtnl_dev_combine_fla
    /* bugwards compatibility: ifi_change == 0 is treated as ~0 */
    if (ifm->ifi_change)
    flags = (flags & ifm->ifi_change) |
    - (dev->flags & ~ifm->ifi_change);
    + (rtnl_dev_get_flags(dev) & ~ifm->ifi_change);

    return flags;
    }



    \
     
     \ /
      Last update: 2012-08-08 01:42    [W:3.851 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site