From patchwork Thu Apr 12 06:24:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Long X-Patchwork-Id: 897494 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="e03FAtxY"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40M9qc3jZJz9s25 for ; Thu, 12 Apr 2018 16:24:44 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752660AbeDLGYl (ORCPT ); Thu, 12 Apr 2018 02:24:41 -0400 Received: from mail-pf0-f196.google.com ([209.85.192.196]:39603 "EHLO mail-pf0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751794AbeDLGYk (ORCPT ); Thu, 12 Apr 2018 02:24:40 -0400 Received: by mail-pf0-f196.google.com with SMTP id c78so2784366pfj.6; Wed, 11 Apr 2018 23:24:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=hOAztpuSlbB+p3uiI2NipjNFaZZZ90n1cUVlMgvqixA=; b=e03FAtxYkLAiVERhHUu070HyjC2PN8Q3j5JVjAJoDBIjcZW48UedVvZV9+4wafmJ0n gkWbslips0vUeRTpAnCHlbUYisSZ+iZiyEiJQUWuiZ6QFq3FZIZBxi9zrrhN83z08phH ZL3bpTNpPV8cZG9yYptvTSpfym7yDNdSfCdEdUKFN8x9cASeYQwINJh0uJMyvH2YYUH8 /J+NYM9/f1pV5zUHYopAja6qoIpXWPa6b5TlUKZHHpAg+p8N0Ufz+V3E+zCYEhze9fF6 vJZlQWGS5U/xn1DLHejFHlg3P29nvraxk76/FRmLyP0XtxpiSbEDiEP6SGJ4pCaMHTtc XMVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=hOAztpuSlbB+p3uiI2NipjNFaZZZ90n1cUVlMgvqixA=; b=CRYSjtes6YWAX6/2isz9Xijpipuwb+iRs0J90hq8V/ULWlk1uU69dkQTjvhJpcxaRY ySd7SCZqlJK4jA4mb01eO9AImsruBg0tuVVfgRrvx2u/LIbggdOiab8gj6oIjqCPDJO5 P7AGixfx50MjR98em3VZ3kGMfliwXtJieB0v8psi63yXju7MbwuPL6xnoVKJnr2OE2rg ZtMSzUfMMSGiuGkOt+kxqwYKjpcveYgyp9vJRxmMN/x8lE4DLZ7UVYww3ai4AFc1BtGr SiWLMjMCLqaFCSzSBZBQMahRalGLhlWcLVcjLzctul2iyoWXiuK6+Z6qJOPTUJNQhrxg ARmQ== X-Gm-Message-State: ALQs6tC1SdYgZpxZLPpklStjpFx0fzeTsrVvsRyrZ/YIg0Ma+B+4j4xz 9oPMWgl4s/SaaCx+rdEjdD7x7I3s X-Google-Smtp-Source: AIpwx4/hR7XMzFPsZIDPufWxGOmOkVt2mdsaKqQNYFEDjx+FkL9Y0f7QMVFtmJ2Pjyudg1j/Q7FEXg== X-Received: by 10.167.130.22 with SMTP id k22mr6574325pfi.73.1523514279579; Wed, 11 Apr 2018 23:24:39 -0700 (PDT) Received: from localhost ([209.132.188.80]) by smtp.gmail.com with ESMTPSA id f15sm2560837pga.17.2018.04.11.23.24.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 11 Apr 2018 23:24:38 -0700 (PDT) From: Xin Long To: network dev , linux-sctp@vger.kernel.org Cc: davem@davemloft.net, Marcelo Ricardo Leitner , Neil Horman Subject: [PATCHv2 net] sctp: do not check port in sctp_inet6_cmp_addr Date: Thu, 12 Apr 2018 14:24:31 +0800 Message-Id: <7220f314b70726ba4afee91df11e9ae8d1962e01.1523514271.git.lucien.xin@gmail.com> X-Mailer: git-send-email 2.1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org pf->cmp_addr() is called before binding a v6 address to the sock. It should not check ports, like in sctp_inet_cmp_addr. But sctp_inet6_cmp_addr checks the addr by invoking af(6)->cmp_addr, sctp_v6_cmp_addr where it also compares the ports. This would cause that setsockopt(SCTP_SOCKOPT_BINDX_ADD) could bind multiple duplicated IPv6 addresses after Commit 40b4f0fd74e4 ("sctp: lack the check for ports in sctp_v6_cmp_addr"). This patch is to remove af->cmp_addr called in sctp_inet6_cmp_addr, but do the proper check for both v6 addrs and v4mapped addrs. v1->v2: - define __sctp_v6_cmp_addr to do the common address comparison used for both pf and af v6 cmp_addr. Fixes: 40b4f0fd74e4 ("sctp: lack the check for ports in sctp_v6_cmp_addr") Reported-by: Jianwen Ji Signed-off-by: Xin Long Acked-by: Neil Horman --- net/sctp/ipv6.c | 60 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index f1fc48e..09aba03 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -521,46 +521,49 @@ static void sctp_v6_to_addr(union sctp_addr *addr, struct in6_addr *saddr, addr->v6.sin6_scope_id = 0; } -/* Compare addresses exactly. - * v4-mapped-v6 is also in consideration. - */ -static int sctp_v6_cmp_addr(const union sctp_addr *addr1, - const union sctp_addr *addr2) +static int __sctp_v6_cmp_addr(const union sctp_addr *addr1, + const union sctp_addr *addr2) { if (addr1->sa.sa_family != addr2->sa.sa_family) { if (addr1->sa.sa_family == AF_INET && addr2->sa.sa_family == AF_INET6 && - ipv6_addr_v4mapped(&addr2->v6.sin6_addr)) { - if (addr2->v6.sin6_port == addr1->v4.sin_port && - addr2->v6.sin6_addr.s6_addr32[3] == - addr1->v4.sin_addr.s_addr) - return 1; - } + ipv6_addr_v4mapped(&addr2->v6.sin6_addr) && + addr2->v6.sin6_addr.s6_addr32[3] == + addr1->v4.sin_addr.s_addr) + return 1; + if (addr2->sa.sa_family == AF_INET && addr1->sa.sa_family == AF_INET6 && - ipv6_addr_v4mapped(&addr1->v6.sin6_addr)) { - if (addr1->v6.sin6_port == addr2->v4.sin_port && - addr1->v6.sin6_addr.s6_addr32[3] == - addr2->v4.sin_addr.s_addr) - return 1; - } + ipv6_addr_v4mapped(&addr1->v6.sin6_addr) && + addr1->v6.sin6_addr.s6_addr32[3] == + addr2->v4.sin_addr.s_addr) + return 1; + return 0; } - if (addr1->v6.sin6_port != addr2->v6.sin6_port) - return 0; + if (!ipv6_addr_equal(&addr1->v6.sin6_addr, &addr2->v6.sin6_addr)) return 0; + /* If this is a linklocal address, compare the scope_id. */ - if (ipv6_addr_type(&addr1->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) { - if (addr1->v6.sin6_scope_id && addr2->v6.sin6_scope_id && - (addr1->v6.sin6_scope_id != addr2->v6.sin6_scope_id)) { - return 0; - } - } + if ((ipv6_addr_type(&addr1->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) && + addr1->v6.sin6_scope_id && addr2->v6.sin6_scope_id && + addr1->v6.sin6_scope_id != addr2->v6.sin6_scope_id) + return 0; return 1; } +/* Compare addresses exactly. + * v4-mapped-v6 is also in consideration. + */ +static int sctp_v6_cmp_addr(const union sctp_addr *addr1, + const union sctp_addr *addr2) +{ + return __sctp_v6_cmp_addr(addr1, addr2) && + addr1->v6.sin6_port == addr2->v6.sin6_port; +} + /* Initialize addr struct to INADDR_ANY. */ static void sctp_v6_inaddr_any(union sctp_addr *addr, __be16 port) { @@ -846,8 +849,8 @@ static int sctp_inet6_cmp_addr(const union sctp_addr *addr1, const union sctp_addr *addr2, struct sctp_sock *opt) { - struct sctp_af *af1, *af2; struct sock *sk = sctp_opt2sk(opt); + struct sctp_af *af1, *af2; af1 = sctp_get_af_specific(addr1->sa.sa_family); af2 = sctp_get_af_specific(addr2->sa.sa_family); @@ -863,10 +866,7 @@ static int sctp_inet6_cmp_addr(const union sctp_addr *addr1, if (sctp_is_any(sk, addr1) || sctp_is_any(sk, addr2)) return 1; - if (addr1->sa.sa_family != addr2->sa.sa_family) - return 0; - - return af1->cmp_addr(addr1, addr2); + return __sctp_v6_cmp_addr(addr1, addr2); } /* Verify that the provided sockaddr looks bindable. Common verification,