From patchwork Fri Jun 16 14:23:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serhey Popovych X-Patchwork-Id: 776780 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3wq2gg5lWLz9s7m for ; Sat, 17 Jun 2017 00:24:31 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="O3NJpNz0"; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754242AbdFPOY3 (ORCPT ); Fri, 16 Jun 2017 10:24:29 -0400 Received: from mail-lf0-f66.google.com ([209.85.215.66]:33101 "EHLO mail-lf0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754094AbdFPOYW (ORCPT ); Fri, 16 Jun 2017 10:24:22 -0400 Received: by mail-lf0-f66.google.com with SMTP id u62so4370720lfg.0 for ; Fri, 16 Jun 2017 07:24:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:in-reply-to :references; bh=DA/C0acVsbya7ufhmGiQG1rc8Jay4gBkI+EG3mTlcFk=; b=O3NJpNz0qyrB0mepXyw/AHbwuaORGexCZ9vMVtY7LX7QZLiyuOht3lo5u30TXX/I73 DzYo8Z2uZGf6+eLsoR6tBvp8dbVj3QQjYJ4VDovXvRPldlceYtkdA6OjiOiOteYY7meB JFxzQDr+3YC2JozcDgQYexnn2iffoOSfsDcHCF07Ziu8J+yOlWzCKZrPVgk93xtnnbFR d/GOcXggQTTu7KKvVva8+Q5Ng8Ych3g9z4ye8KBZAYpq6i5+Ivo+ZxI7Q87folVomBtM LZ4LN3M2ts1fgiIRdXQjMSClFSAa8VHmdpSKQx60+kra3SYKMe6JGKJGAt+9bNtkpK1b gt0w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=DA/C0acVsbya7ufhmGiQG1rc8Jay4gBkI+EG3mTlcFk=; b=LBuq8/aX4Y+h9GFFvsSPX7gr8/bQvnZs4K2ofe8ruq73MC8jfASLS10AMmJaWGLEvV ych/eCyMjk4atQG9kqpbbqA5pS3/vkX5ebW8GVoxFsggQKXolqFwPGHBZPBGEPIsLdoT +CKDhKx7bmFgHG21Fa8dJylyRfv8SIoJp4bYTuGlMvaHEy0H0RF/ExE+i/H+w+XRd+ks Na9oXEArtHV72ac2gRlZIfTz1v6NUJAk43VhTlF1pTBJ/TBwK9QDE595Xe/lmbAw0VWw xkfq4UN8jPolR9EDRyXUmOFHNgwCy/BlroYRA0wQYgxpOLYhYknpCogmZWRVFDx7Bdvu MIuw== X-Gm-Message-State: AKS2vOx0AqTgtkMhb1A0NaxZkMpM4RZJRwzz73MhiLik9prfMK42XWKH HQs8WENDG0TU3mq5SiQ8NQ== X-Received: by 10.25.44.74 with SMTP id s71mr3699633lfs.97.1497623060469; Fri, 16 Jun 2017 07:24:20 -0700 (PDT) Received: from tuxracer.synapse.com ([195.238.92.77]) by smtp.gmail.com with ESMTPSA id z10sm486566lja.6.2017.06.16.07.24.19 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 16 Jun 2017 07:24:20 -0700 (PDT) From: Serhey Popovych To: netdev@vger.kernel.org Subject: [PATCH 2/3] dev: Avoid infinite loop on network device index exhaustion Date: Fri, 16 Jun 2017 17:23:52 +0300 Message-Id: X-Mailer: git-send-email 1.8.3.1 In-Reply-To: References: In-Reply-To: References: Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org If network device indexes exhaust in namespace dev_new_index() can loop indefinitely since there is no condition to exit except case where free index is found. Since all it's caller hold RTNL mutex this may completely lock down network subsystem configuration operations. Instead of retrying with ifindex == 1 (LOOPBACK_IFINDEX) in dev_new_index() we should fail and return invalid index value (0). Adjust callers to correctly handle error case of dev_new_index(). Signed-off-by: Serhey Popovych --- net/core/dev.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index dae8010..6f573f7 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -7014,7 +7014,9 @@ int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack, * @net: the applicable net namespace * * Returns a suitable unique value for a new device interface - * number. The caller must hold the rtnl semaphore or the + * number or zero in case of no free indexes in net namespace. + * + * The caller must hold the rtnl mutex or the * dev_base_lock to be sure it remains unique. */ static int dev_new_index(struct net *net) @@ -7023,7 +7025,7 @@ static int dev_new_index(struct net *net) for (;;) { if (++ifindex <= 0) - ifindex = 1; + return 0; if (!__dev_get_by_index(net, ifindex)) return net->ifindex = ifindex; } @@ -7491,9 +7493,12 @@ int register_netdevice(struct net_device *dev) } ret = -EBUSY; - if (dev->ifindex <= 0) - dev->ifindex = dev_new_index(net); - else if (__dev_get_by_index(net, dev->ifindex)) + if (dev->ifindex <= 0) { + int ifindex = dev_new_index(net); + if (!ifindex) + goto err_uninit; + dev->ifindex = ifindex; + } else if (__dev_get_by_index(net, dev->ifindex)) goto err_uninit; /* Transfer changeable features to wanted_features and enable @@ -8174,6 +8179,7 @@ void unregister_netdev(struct net_device *dev) int dev_change_net_namespace(struct net_device *dev, struct net *net, const char *pat) { + int ifindex = 0; int err; ASSERT_RTNL(); @@ -8192,6 +8198,14 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char if (net_eq(dev_net(dev), net)) goto out; + /* If there is an ifindex conflict assign a new one */ + err = -EBUSY; + if (__dev_get_by_index(net, dev->ifindex)) { + ifindex = dev_new_index(net); + if (!ifindex) + goto out; + } + /* Pick the destination device name, and ensure * we can use it in the destination network namespace. */ @@ -8245,9 +8259,9 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char /* Actually switch the network namespace */ dev_net_set(dev, net); - /* If there is an ifindex conflict assign a new one */ - if (__dev_get_by_index(net, dev->ifindex)) - dev->ifindex = dev_new_index(net); + /* Actually change the ifindex */ + if (ifindex) + dev->ifindex = ifindex; /* Send a netdev-add uevent to the new namespace */ kobject_uevent(&dev->dev.kobj, KOBJ_ADD);