Received: by 2002:ac0:98c7:0:0:0:0:0 with SMTP id g7-v6csp2458274imd; Fri, 2 Nov 2018 11:45:12 -0700 (PDT) X-Google-Smtp-Source: AJdET5eSgBEjzeDWxLX40TTbhgw7sQoNNGJtO8u0u1BG2ypWDEkStbgV/zkftuthhKkbz4/5cg4j X-Received: by 2002:a17:902:5a2:: with SMTP id f31-v6mr12579661plf.320.1541184311945; Fri, 02 Nov 2018 11:45:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1541184311; cv=none; d=google.com; s=arc-20160816; b=n+8aTqhtvEsvhEL+eKy2ZGXNXToi+koX0+uiZOYKFdUQu8CNuMY+P6V26qs70uSE9d HOGm7CsGBMGqpq9JxoV/A0CtZuwG8LH8CEw0XTw9s7NsdxRbHzG6YVy49ASSQatTm5uv 4OKlRT2AkVRgk1BhOOmajSox0rznW8r0dXmJuxim+7X8nSmYygwbHagrOnks249JR9mf MBROKYY+0CWNfc+Xo+cSGWZMA/7mJPJzND1LLzDhB3lVJchHGqRXgf6gYHWHW7Y68nmk wgZTxp+5B5B1qpfcwUkjfkHDwFIWYUQHPko1vRtGUX7gRjLCc0BD/R7Kc4uxju7J8cPQ ERLQ== 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=fOTcoheAtAKgomfiZiLSuAMlPToD35JFUr7OreOksoM=; b=yDCEg7sRQm5BVVjHLFNm4uhUxERA/KJAHXiH8J3VF+Tk0RNnxEo9UzwVWzZZI7wj+R tohSzzpTmOV4qL4KvWzQcBXKtOd4a1T+FcieuzFO1QYMHndJ7VQuarYY38JN5JapZxCE D1jQXGtjfB9GmLkIP9VDxwaMXpZ5ltNK7MITDCTjBQOnrAmPls0n03LeZMd9NLJx9T7t 2Te5vZSV2rHdPDrypa3Ffh4SB69NxuYrn3dtZjqBnTHRAxqoHCmIFrfPfeMus+qy6Hl/ 80EdvIDmfiPIDC1VG0g8DpeQ+xygnoBF/m8xckidoXbjynNneytnbt8MyLSvGHIhY31g vY1w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=oCjsBLxE; 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 z126-v6si12980062pfb.280.2018.11.02.11.44.57; Fri, 02 Nov 2018 11:45:11 -0700 (PDT) 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=oCjsBLxE; 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 S1729840AbeKCDux (ORCPT + 99 others); Fri, 2 Nov 2018 23:50:53 -0400 Received: from mail.kernel.org ([198.145.29.99]:46012 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728033AbeKCDuw (ORCPT ); Fri, 2 Nov 2018 23:50:52 -0400 Received: from localhost (5356596B.cm-6-7b.dynamic.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 8CBCF2084A; Fri, 2 Nov 2018 18:42:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1541184160; bh=ibF1WGoIvnw+u4sOeai+2ytFatK0ZogfiXeehmswJgE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oCjsBLxEwIr6k8KFhSh533TcKLjkhD7eYUTpqrdBF9ksr+Do0Vm2o6ZCz9VijpDtK RI+1rsPy088OrZpQ4u5OxME1z2iMxDhzFjk/xYvDknPhTuIZbpcVkff4qVuSeX1Pzv wqZCEpEloPed668or+wiLh7BUvYHCoAmhlXs+PDE= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, David Howells , Sasha Levin Subject: [PATCH 4.18 098/150] afs: Fix cell proc list Date: Fri, 2 Nov 2018 19:34:20 +0100 Message-Id: <20181102182910.229418164@linuxfoundation.org> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181102182902.250560510@linuxfoundation.org> References: <20181102182902.250560510@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review 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 4.18-stable review patch. If anyone has any objections, please let me know. ------------------ [ Upstream commit 6b3944e42e2e554aa5a4be681ecd70dccd459114 ] Access to the list of cells by /proc/net/afs/cells has a couple of problems: (1) It should be checking against SEQ_START_TOKEN for the keying the header line. (2) It's only holding the RCU read lock, so it can't just walk over the list without following the proper RCU methods. Fix these by using an hlist instead of an ordinary list and using the appropriate accessor functions to follow it with RCU. Since the code that adds a cell to the list must also necessarily change, sort the list on insertion whilst we're at it. Fixes: 989782dcdc91 ("afs: Overhaul cell database management") Signed-off-by: David Howells Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- fs/afs/cell.c | 17 +++++++++++++++-- fs/afs/dynroot.c | 2 +- fs/afs/internal.h | 4 ++-- fs/afs/main.c | 2 +- fs/afs/proc.c | 7 +++---- 5 files changed, 22 insertions(+), 10 deletions(-) diff --git a/fs/afs/cell.c b/fs/afs/cell.c index f3d0bef16d78..6127f0fcd62c 100644 --- a/fs/afs/cell.c +++ b/fs/afs/cell.c @@ -514,6 +514,8 @@ static int afs_alloc_anon_key(struct afs_cell *cell) */ static int afs_activate_cell(struct afs_net *net, struct afs_cell *cell) { + struct hlist_node **p; + struct afs_cell *pcell; int ret; if (!cell->anonymous_key) { @@ -534,7 +536,18 @@ static int afs_activate_cell(struct afs_net *net, struct afs_cell *cell) return ret; mutex_lock(&net->proc_cells_lock); - list_add_tail(&cell->proc_link, &net->proc_cells); + for (p = &net->proc_cells.first; *p; p = &(*p)->next) { + pcell = hlist_entry(*p, struct afs_cell, proc_link); + if (strcmp(cell->name, pcell->name) < 0) + break; + } + + cell->proc_link.pprev = p; + cell->proc_link.next = *p; + rcu_assign_pointer(*p, &cell->proc_link.next); + if (cell->proc_link.next) + cell->proc_link.next->pprev = &cell->proc_link.next; + afs_dynroot_mkdir(net, cell); mutex_unlock(&net->proc_cells_lock); return 0; @@ -550,7 +563,7 @@ static void afs_deactivate_cell(struct afs_net *net, struct afs_cell *cell) afs_proc_cell_remove(cell); mutex_lock(&net->proc_cells_lock); - list_del_init(&cell->proc_link); + hlist_del_rcu(&cell->proc_link); afs_dynroot_rmdir(net, cell); mutex_unlock(&net->proc_cells_lock); diff --git a/fs/afs/dynroot.c b/fs/afs/dynroot.c index 174e843f0633..7de7223843cc 100644 --- a/fs/afs/dynroot.c +++ b/fs/afs/dynroot.c @@ -286,7 +286,7 @@ int afs_dynroot_populate(struct super_block *sb) return -ERESTARTSYS; net->dynroot_sb = sb; - list_for_each_entry(cell, &net->proc_cells, proc_link) { + hlist_for_each_entry(cell, &net->proc_cells, proc_link) { ret = afs_dynroot_mkdir(net, cell); if (ret < 0) goto error; diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 9778df135717..270d1caa27c6 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -241,7 +241,7 @@ struct afs_net { seqlock_t cells_lock; struct mutex proc_cells_lock; - struct list_head proc_cells; + struct hlist_head proc_cells; /* Known servers. Theoretically each fileserver can only be in one * cell, but in practice, people create aliases and subsets and there's @@ -319,7 +319,7 @@ struct afs_cell { struct afs_net *net; struct key *anonymous_key; /* anonymous user key for this cell */ struct work_struct manager; /* Manager for init/deinit/dns */ - struct list_head proc_link; /* /proc cell list link */ + struct hlist_node proc_link; /* /proc cell list link */ #ifdef CONFIG_AFS_FSCACHE struct fscache_cookie *cache; /* caching cookie */ #endif diff --git a/fs/afs/main.c b/fs/afs/main.c index e84fe822a960..107427688edd 100644 --- a/fs/afs/main.c +++ b/fs/afs/main.c @@ -87,7 +87,7 @@ static int __net_init afs_net_init(struct net *net_ns) timer_setup(&net->cells_timer, afs_cells_timer, 0); mutex_init(&net->proc_cells_lock); - INIT_LIST_HEAD(&net->proc_cells); + INIT_HLIST_HEAD(&net->proc_cells); seqlock_init(&net->fs_lock); net->fs_servers = RB_ROOT; diff --git a/fs/afs/proc.c b/fs/afs/proc.c index 476dcbb79713..9101f62707af 100644 --- a/fs/afs/proc.c +++ b/fs/afs/proc.c @@ -33,9 +33,8 @@ static inline struct afs_net *afs_seq2net_single(struct seq_file *m) static int afs_proc_cells_show(struct seq_file *m, void *v) { struct afs_cell *cell = list_entry(v, struct afs_cell, proc_link); - struct afs_net *net = afs_seq2net(m); - if (v == &net->proc_cells) { + if (v == SEQ_START_TOKEN) { /* display header on line 1 */ seq_puts(m, "USE NAME\n"); return 0; @@ -50,12 +49,12 @@ static void *afs_proc_cells_start(struct seq_file *m, loff_t *_pos) __acquires(rcu) { rcu_read_lock(); - return seq_list_start_head(&afs_seq2net(m)->proc_cells, *_pos); + return seq_hlist_start_head_rcu(&afs_seq2net(m)->proc_cells, *_pos); } static void *afs_proc_cells_next(struct seq_file *m, void *v, loff_t *pos) { - return seq_list_next(v, &afs_seq2net(m)->proc_cells, pos); + return seq_hlist_next_rcu(v, &afs_seq2net(m)->proc_cells, pos); } static void afs_proc_cells_stop(struct seq_file *m, void *v) -- 2.17.1