Received: by 2002:a25:683:0:0:0:0:0 with SMTP id 125csp679363ybg; Fri, 12 Jun 2020 11:38:03 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwEhFUiDzhUCABqsK1ZSj17VEHdVYF5ILNklPPQPBKgPf0UavESs1xw04X3QBQIHi94t6WO X-Received: by 2002:a17:906:847:: with SMTP id f7mr13165369ejd.147.1591987082565; Fri, 12 Jun 2020 11:38:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1591987082; cv=none; d=google.com; s=arc-20160816; b=VkVdpaAxoWuu93c574zjwAyY9qyaNagmbgLyptoxqOaEHRAUDHGqOuJ+QeruOnXr5F YJnHo6bIdWXJ5czVzX3/7bG532r4mTgSj3CKTQc4gdtaGjtTbTMeRQOeXL8NpappG+Gi kL/pQQk4s7sW3eNMcGFPYFkHG2D4lZYxDS9fmvI60R5gvI/syC2v239WZXGL+PB6Anhz 3HZHmeTEntvdzJ+eSIhrqX4PLGdZDmvKbioc+x78SwFykPY5HHevNd8Ugi+Gmui+roUJ +O4ium9QBDj8JZkXZGYP6aALrpG+WJorhCaayDJooOAayn54E8sovzLI2TYmilTbpaPM 4k0w== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=BKq2bqjoIrTxoszw+QjbBisLqsmMqZ1oiRk0VcTa+rw=; b=PW5yQqXSOluHxp5dLp8H6wMROyhOFDK3HMlRhoDX3d/3on9N4rq2rCAxrkLIYRBTu7 OZj/8d4HD91Fy3uVqXvXafsiiU8B7NIUJBPko5vH9/qw4LyLh966pCNDN5pJQ0uWgz5O hiRj1niKCIkmIHKhY6smxCKempKBu8GmwIgmssJtrNYBbVIpGK4YwkD4y2q6e1WyFA76 mbARr6mlg7NTMfNkYxbGFciRmoAYV30KEgvhjKySlmUI4y2AVK/c8dV8LHL3KT8yFCV2 14M075ptx2hq6MT7RTED3iWWYGtGg9GWAzLlBLegIl3mbKoREdrYguVNnAQrHDxe779V rGVQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=b6e1Ceye; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id h17si4071032eds.347.2020.06.12.11.37.40; Fri, 12 Jun 2020 11:38:02 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=b6e1Ceye; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726379AbgFLSfN (ORCPT + 99 others); Fri, 12 Jun 2020 14:35:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37308 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726366AbgFLSfF (ORCPT ); Fri, 12 Jun 2020 14:35:05 -0400 Received: from mail-pg1-x541.google.com (mail-pg1-x541.google.com [IPv6:2607:f8b0:4864:20::541]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BCBE9C03E96F for ; Fri, 12 Jun 2020 11:35:03 -0700 (PDT) Received: by mail-pg1-x541.google.com with SMTP id t7so4510599pgt.3 for ; Fri, 12 Jun 2020 11:35:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=BKq2bqjoIrTxoszw+QjbBisLqsmMqZ1oiRk0VcTa+rw=; b=b6e1CeyehqcVZ+b1y8LNMq44/UsTWrA7jMw9137JjYrq04Fg9eQuNDfbFYlwKk5548 o028X1KTz4zDiz1RALJtRxUpcWcNn8ojihcqPULTySWuzfMTHt96pkY2Z9yIK6uZ7uRO cu/r83h4hea7aVWhSuoXGDugUp4F4Jv5eJD1g= 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:in-reply-to :references:mime-version:content-transfer-encoding; bh=BKq2bqjoIrTxoszw+QjbBisLqsmMqZ1oiRk0VcTa+rw=; b=CSskZkF+A7fkvRLS4g4ciZt1nMzAkcVxuH2cUKpGNVpah8NIp6iJfYNksLzaft+KCD cKxTFLzM44VlXJEjc9NRzGi6r/o7A5HO79UheBvW6ogEuJ+4rIqK1Ute5fjZJQC//VVZ XD4QSvymoQ/uMQ7cQsgFxxEKJOJn9EQAhFGaOENwHsvF5fcXjlb5C2IVx9mH4vF8e9h6 nVTF4WlLCZFGiCl51qi1i+qaNW390GK+Hl8G5N2jnMaQGnRvIBqedZuJt0ZmjaPSxDCi RLSNowoBhIcEUP74NkMvySGWwTW2XlsDk8mDQFsHDzDWT2g0sHO3XnB8doDs1i5/GlIg kZcA== X-Gm-Message-State: AOAM533sJlOOs3C82JGfPP4ww5PL/UZekhbRqg1phTUeK8PHLKmLO3az /kDLOjy6qZVc5NAzc78bIOrNDg== X-Received: by 2002:a62:2f45:: with SMTP id v66mr13684525pfv.45.1591986903296; Fri, 12 Jun 2020 11:35:03 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id b6sm6725353pfp.24.2020.06.12.11.35.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Jun 2020 11:35:01 -0700 (PDT) From: Kees Cook To: Peter Zijlstra Cc: Kees Cook , Elena Reshetova , David Windsor , Hans Liljestrand , Xiaoming Ni , Paul Moore , edumazet@google.com, paulmck@kernel.org, David Howells , shakeelb@google.com, James Morris , alex.huangjianhui@huawei.com, dylix.dailei@huawei.com, chenzefeng2@huawei.com, linux-kernel@vger.kernel.org Subject: [PATCH 1/3] nsproxy: convert nsproxy.count to refcount_t Date: Fri, 12 Jun 2020 11:34:48 -0700 Message-Id: <20200612183450.4189588-2-keescook@chromium.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200612183450.4189588-1-keescook@chromium.org> References: <20200612183450.4189588-1-keescook@chromium.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Elena Reshetova atomic_t variables are currently used to implement reference counters with the following properties: - counter is initialized to 1 using atomic_set() - a resource is freed upon counter reaching zero - once counter reaches zero, its further increments aren't allowed - counter schema uses basic atomic operations (set, inc, inc_not_zero, dec_and_test, etc.) Such atomic variables should be converted to a newly provided refcount_t type and API that prevents accidental counter overflows and underflows. This is important since overflows and underflows can lead to use-after-free situation and be exploitable. The variable nsproxy.count is used as pure reference counter. Convert it to refcount_t and fix up the operations. **Important note for maintainers: Some functions from refcount_t API defined in lib/refcount.c have different memory ordering guarantees than their atomic counterparts.Please check Documentation/core-api/refcount-vs-atomic.rst for more information. Normally the differences should not matter since refcount_t provides enough guarantees to satisfy the refcounting use cases, but in some rare cases it might matter. Please double check that you don't have some undocumented memory guarantees for this variable usage. For the nsproxy.count it might make a difference in following places: - put_nsproxy() and switch_task_namespaces(): decrement in refcount_dec_and_test() only provides RELEASE ordering and ACQUIRE ordering on success vs. fully ordered atomic counterpart Suggested-by: Kees Cook Signed-off-by: Elena Reshetova Reviewed-by: David Windsor Reviewed-by: Hans Liljestrand Link: https://lore.kernel.org/r/20190306110549.7628-2-elena.reshetova@intel.com Signed-off-by: Kees Cook --- include/linux/nsproxy.h | 7 +++---- kernel/nsproxy.c | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h index cdb171efc7cb..6bd95f02de05 100644 --- a/include/linux/nsproxy.h +++ b/include/linux/nsproxy.h @@ -29,7 +29,7 @@ struct fs_struct; * nsproxy is copied. */ struct nsproxy { - atomic_t count; + refcount_t count; struct uts_namespace *uts_ns; struct ipc_namespace *ipc_ns; struct mnt_namespace *mnt_ns; @@ -101,14 +101,13 @@ int __init nsproxy_cache_init(void); static inline void put_nsproxy(struct nsproxy *ns) { - if (atomic_dec_and_test(&ns->count)) { + if (refcount_dec_and_test(&ns->count)) free_nsproxy(ns); - } } static inline void get_nsproxy(struct nsproxy *ns) { - atomic_inc(&ns->count); + refcount_inc(&ns->count); } #endif diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c index b03df67621d0..74b5e6925e0f 100644 --- a/kernel/nsproxy.c +++ b/kernel/nsproxy.c @@ -30,7 +30,7 @@ static struct kmem_cache *nsproxy_cachep; struct nsproxy init_nsproxy = { - .count = ATOMIC_INIT(1), + .count = REFCOUNT_INIT(1), .uts_ns = &init_uts_ns, #if defined(CONFIG_POSIX_MQUEUE) || defined(CONFIG_SYSVIPC) .ipc_ns = &init_ipc_ns, @@ -55,7 +55,7 @@ static inline struct nsproxy *create_nsproxy(void) nsproxy = kmem_cache_alloc(nsproxy_cachep, GFP_KERNEL); if (nsproxy) - atomic_set(&nsproxy->count, 1); + refcount_set(&nsproxy->count, 1); return nsproxy; } @@ -250,7 +250,7 @@ void switch_task_namespaces(struct task_struct *p, struct nsproxy *new) p->nsproxy = new; task_unlock(p); - if (ns && atomic_dec_and_test(&ns->count)) + if (ns && refcount_dec_and_test(&ns->count)) free_nsproxy(ns); } -- 2.25.1