Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp3466ybl; Tue, 7 Jan 2020 12:59:16 -0800 (PST) X-Google-Smtp-Source: APXvYqwgl0/ZiGOUe1OGWDxTOXoq1reE3BS2m2UrlTOOH3ncoCqanLVXjNBrAtUUuaDs5Pam8pzr X-Received: by 2002:a05:6830:174e:: with SMTP id 14mr1658050otz.142.1578430755932; Tue, 07 Jan 2020 12:59:15 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1578430755; cv=none; d=google.com; s=arc-20160816; b=LwE9yrpu5m65GUiIqIVle/XXtnihL0Mda2fTSJb87DaU3uSdkt05ZuBktIXZLsO53e Zjc0oaBTsngUFpqNRYRhehp63k+4NZ0BF+ZfAnZJcAdz7qhTHVrNswLzrYXtZUvkUIJN 7d4Vjsuo7MmWNyKWHB07s6O5WHzF+jSGsrtsOoaa3PVajRw+v3TvVoc3CuMyZCV4bgeu bp0hxMcU4dY/oHcW2oRKEmt3CWVexR0Qao9Qi4Aac3/JUwUpiQ/KvE6kJSXG+IkkWc4C iQxj32NA51HkwvuFcg+BlZBR+8SJAMbkAh5Ytoz5bwvAIxrW3KCQfO0RqzjBigKERaVj p27A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=nu/vg+e/VfPI5RLRRHAbLPl2WBKvlh5uqL++dsJowNI=; b=C5jprHeXNAUVtzHLjFX09O2aWO9J1icxTzjUvm9qUNev7U1ZXYZ4C7im/WRd21BA5Z jRr0YZpuIGtF5FWU41jKZRdfZ1AQkkedB3li+0pSSQ31TXxSMn4t8e9Ks97+PBEiR4Sm l/ilyk4rYLV62NLBJn8lLRETaJjSfWFXQBxKyvy14NomgABO7+RquZMELqP4N8xuHXHq oTt67tvP6vuv3Y45dk4n7yEu7yRPByS3qoKS6k3U0qNgWv57NsqY7AMHLpDgciuwVpR7 3V3nAGZIZnv+TEsng9zf5yx2q57tRPfZosToUhotv1kiYspydAiInGdkj1tY16LrHeBi MT4A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=RBjKpj4r; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x3si592282oic.251.2020.01.07.12.59.02; Tue, 07 Jan 2020 12:59:15 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=RBjKpj4r; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727721AbgAGU5v (ORCPT + 99 others); Tue, 7 Jan 2020 15:57:51 -0500 Received: from mail.kernel.org ([198.145.29.99]:55722 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727710AbgAGU5u (ORCPT ); Tue, 7 Jan 2020 15:57:50 -0500 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id E00BA214D8; Tue, 7 Jan 2020 20:57:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1578430669; bh=xSJgGPp4d9gWvGBek+XotORuU+rJ+I8UUfyF2G9TwA0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RBjKpj4rvIgRrkCsNiLX0f3rhncLqaCGRIIJu6n3CI8zH06OJ3kdkBiW+v9HLQGPx HP1i1phwo3cG3HbH1767m5nJVqf4qomE/i+uA26QJsGzDmzXSo9YW9FM5JicbMUMxJ js2yyL0YbA+Zo4AkUAUjK3Q7vuOUBiAZOzhcE+Xw= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Marc Dionne , David Howells , Sasha Levin Subject: [PATCH 5.4 019/191] afs: Fix afs_find_server lookups for ipv4 peers Date: Tue, 7 Jan 2020 21:52:19 +0100 Message-Id: <20200107205334.034314210@linuxfoundation.org> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200107205332.984228665@linuxfoundation.org> References: <20200107205332.984228665@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Marc Dionne [ Upstream commit 9bd0160d12370a076e44f8d1320cde9c83f2c647 ] afs_find_server tries to find a server that has an address that matches the transport address of an rxrpc peer. The code assumes that the transport address is always ipv6, with ipv4 represented as ipv4 mapped addresses, but that's not the case. If the transport family is AF_INET, srx->transport.sin6.sin6_addr.s6_addr32[] will be beyond the actual ipv4 address and will always be 0, and all ipv4 addresses will be seen as matching. As a result, the first ipv4 address seen on any server will be considered a match, and the server returned may be the wrong one. One of the consequences is that callbacks received over ipv4 will only be correctly applied for the server that happens to have the first ipv4 address on the fs_addresses4 list. Callbacks over ipv4 from all other servers are dropped, causing the client to serve stale data. This is fixed by looking at the transport family, and comparing ipv4 addresses based on a sockaddr_in structure rather than a sockaddr_in6. Fixes: d2ddc776a458 ("afs: Overhaul volume and server record caching and fileserver rotation") Signed-off-by: Marc Dionne Signed-off-by: David Howells Signed-off-by: Sasha Levin --- fs/afs/server.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/fs/afs/server.c b/fs/afs/server.c index 64d440aaabc0..ca8115ba1724 100644 --- a/fs/afs/server.c +++ b/fs/afs/server.c @@ -32,18 +32,11 @@ static void afs_dec_servers_outstanding(struct afs_net *net) struct afs_server *afs_find_server(struct afs_net *net, const struct sockaddr_rxrpc *srx) { - const struct sockaddr_in6 *a = &srx->transport.sin6, *b; const struct afs_addr_list *alist; struct afs_server *server = NULL; unsigned int i; - bool ipv6 = true; int seq = 0, diff; - if (srx->transport.sin6.sin6_addr.s6_addr32[0] == 0 || - srx->transport.sin6.sin6_addr.s6_addr32[1] == 0 || - srx->transport.sin6.sin6_addr.s6_addr32[2] == htonl(0xffff)) - ipv6 = false; - rcu_read_lock(); do { @@ -52,7 +45,8 @@ struct afs_server *afs_find_server(struct afs_net *net, server = NULL; read_seqbegin_or_lock(&net->fs_addr_lock, &seq); - if (ipv6) { + if (srx->transport.family == AF_INET6) { + const struct sockaddr_in6 *a = &srx->transport.sin6, *b; hlist_for_each_entry_rcu(server, &net->fs_addresses6, addr6_link) { alist = rcu_dereference(server->addresses); for (i = alist->nr_ipv4; i < alist->nr_addrs; i++) { @@ -68,15 +62,16 @@ struct afs_server *afs_find_server(struct afs_net *net, } } } else { + const struct sockaddr_in *a = &srx->transport.sin, *b; hlist_for_each_entry_rcu(server, &net->fs_addresses4, addr4_link) { alist = rcu_dereference(server->addresses); for (i = 0; i < alist->nr_ipv4; i++) { - b = &alist->addrs[i].transport.sin6; - diff = ((u16 __force)a->sin6_port - - (u16 __force)b->sin6_port); + b = &alist->addrs[i].transport.sin; + diff = ((u16 __force)a->sin_port - + (u16 __force)b->sin_port); if (diff == 0) - diff = ((u32 __force)a->sin6_addr.s6_addr32[3] - - (u32 __force)b->sin6_addr.s6_addr32[3]); + diff = ((u32 __force)a->sin_addr.s_addr - + (u32 __force)b->sin_addr.s_addr); if (diff == 0) goto found; } -- 2.20.1