From patchwork Thu Jan 25 23:57:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vinicius Costa Gomes X-Patchwork-Id: 192337 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:e09d:b0:103:945f:af90 with SMTP id gm29csp340667dyb; Thu, 25 Jan 2024 16:03:06 -0800 (PST) X-Google-Smtp-Source: AGHT+IEMtjMDiJpyoBD4Ptf6zpZ1DflnTP+1pE9Fq2NU6dwFe7fObALNiERwSV88KD2CkylvvM0Q X-Received: by 2002:a05:6a20:c51a:b0:19c:60e3:4274 with SMTP id gm26-20020a056a20c51a00b0019c60e34274mr427807pzb.94.1706227385861; Thu, 25 Jan 2024 16:03:05 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706227385; cv=pass; d=google.com; s=arc-20160816; b=Rl63H3FQfXncIK7RyQrUO3vj2plYMNuLrraF/9Z3VzNUN9WlgbAnjgQQJ2B6WFYMgV OO4NZjOVKeFuth6iK1jqMpHPzxzWacMmQLAmLksDyGuUnxWltGAY5nKT2a2BMfUoJ5EK egcD9E8PWID9DXZAdZyXyuvrU6390YHtOCzfycVwUzts94G++MYJD3LwaK4b7OYPDMNH WpIM7CDLFbUqA9boo6CKpEa1T7CxULeSRIqMb+LPgyhEX/QhjomhQoUhH7tvozMNUooF lc66+d3GHA91L/tPgbf/XAPXYVJ9QPmjks4GGAjw/b4aLPmZG4Z06KoW7A4WB3HicV53 LTOA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=6WIn40Y8JYVVNeXMpYpYkZ1/h6sE2JdD3Nzeb6tljs0=; fh=0u4WKmQXLbfFx7dTPMZn/CP58jbWkEI+fyqm6Dolj/A=; b=NHNYz4MvHfsQQBrPAzcoo33fvxzHxlmuHmtpDYdRZNOtnvTJZPxDMMmoYKB6wFviFi uOXsBOZTOXkay/EPFkGROUuDNvKKFVrMJ5wFCMGL7j7pNIvtrDqKQDvhNJ60D427zzwy jMmyX7qXz/ljsUOv2/V2cN78l0EbBoD20vvVzUZONXty5lDpVV2+i2LolnpKUFPnyAKN DeWkXG4h3HvJFCiv8eJO2X2wVZ2d+l8A9yLy7/9B4CcwcvRd579drvOcd1U4hLFOoBTe /FNQJK4J60ia8XkUTMIiByPlFmG/rSlyaR6NQsWQr2flMDimTYq6JXMJzieQiuk4PTn9 ksLg== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=EZE7fGnf; arc=pass (i=1 spf=pass spfdomain=intel.com dkim=pass dkdomain=intel.com dmarc=pass fromdomain=intel.com); spf=pass (google.com: domain of linux-kernel+bounces-39431-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-39431-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [2604:1380:40f1:3f00::1]) by mx.google.com with ESMTPS id e25-20020a633719000000b005d5d067e97dsi91776pga.890.2024.01.25.16.03.05 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Jan 2024 16:03:05 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-39431-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) client-ip=2604:1380:40f1:3f00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=EZE7fGnf; arc=pass (i=1 spf=pass spfdomain=intel.com dkim=pass dkdomain=intel.com dmarc=pass fromdomain=intel.com); spf=pass (google.com: domain of linux-kernel+bounces-39431-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-39431-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id 1D9CEB254CE for ; Thu, 25 Jan 2024 23:59:53 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 9B535131E4F; Thu, 25 Jan 2024 23:57:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="EZE7fGnf" Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.8]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E4E3B1A731; Thu, 25 Jan 2024 23:57:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.8 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706227059; cv=none; b=Suijg7OzZVS0+loNCeS5bmBKi/ShYpeeLEpH5KuZnP+dCFj+oUPTq7wAqQmVm1rKnV5WnO2nbBi+VN3OMVNsVTpZvnHPtVYzNmGhCtftoMi6dqRPn/kRCDifNrg4X/K76gye6MBNm0Cq1mk6kYvYiLG9Ckvzh8waLsLQXht6dfU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706227059; c=relaxed/simple; bh=+5d3tyhMXlyo3iELNdYQuZU7PNVS/IBrZgPRKsrWJ48=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TGxeXw3uG8JgV8TRLfS3zR8D1DiN3HlJ44vI+qCBC1URzKB6fD9kodJ/hMHJYcv7mC5ztlREhZvRRn61G0ZrCqAncqD1acrA/B/N8AAPzxAGf8yZqmD56k3uT4wpPXy6AhUeMd/QvM23rUge2BJRiR+BrLQYMXiqqFzk/VAPcK4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=EZE7fGnf; arc=none smtp.client-ip=192.198.163.8 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1706227058; x=1737763058; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=+5d3tyhMXlyo3iELNdYQuZU7PNVS/IBrZgPRKsrWJ48=; b=EZE7fGnfsoNgF9k6Pv/XgFpvgpV9i6DSLRmSXv4CtHsn0EjKXQYxq6s1 23ADwsV2lr+U1Od9FRlVkUf51x0K+FHbAGyhwszksS6Q6LozfXmJTarXD fOB++HmGNoCd22AlzElgEQVbTiYFApn6xw717FbwPItlovWn/HrL78pEQ 5a4/VxjwEJ9o9YQH4kEUE4+VrffsGBhl1EdDOXfRiYScUWvLdgZmDTd3y W3aGdTfJo99dm8YHjXKKvtTxhUgjNEG5UCm1f4HfWcfQtv6FdEbEb286/ kTjAN7k4p4Fim8XI6ieAtv5Mbrq9vwE77l7Lng4t3R8xAk9bHxIGOtOXF g==; X-IronPort-AV: E=McAfee;i="6600,9927,10964"; a="15867567" X-IronPort-AV: E=Sophos;i="6.05,216,1701158400"; d="scan'208";a="15867567" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Jan 2024 15:57:36 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10964"; a="930191101" X-IronPort-AV: E=Sophos;i="6.05,216,1701158400"; d="scan'208";a="930191101" Received: from vcostago-mobl3.jf.intel.com ([10.24.14.99]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Jan 2024 15:57:35 -0800 From: Vinicius Costa Gomes To: brauner@kernel.org, amir73il@gmail.com, hu1.chen@intel.com Cc: miklos@szeredi.hu, malini.bhandaru@intel.com, tim.c.chen@intel.com, mikko.ylinen@intel.com, lizhen.you@intel.com, linux-unionfs@vger.kernel.org, linux-kernel@vger.kernel.org, Vinicius Costa Gomes Subject: [RFC v2 2/4] cred: Add a light version of override/revert_creds() Date: Thu, 25 Jan 2024 15:57:21 -0800 Message-ID: <20240125235723.39507-3-vinicius.gomes@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240125235723.39507-1-vinicius.gomes@intel.com> References: <20240125235723.39507-1-vinicius.gomes@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789109087091628837 X-GMAIL-MSGID: 1789109087091628837 Add a light version of override/revert_creds(), this should only be used when the credentials in question will outlive the critical section and the critical section doesn't change the ->usage of the credentials. To make their usage less error prone, introduce cleanup guards asto be used like this: guard(cred)(credentials_to_override_and_restore); or this: scoped_guard(cred, credentials_to_override_and_restore) { /* with credentials overridden */ } Signed-off-by: Vinicius Costa Gomes --- include/linux/cred.h | 21 +++++++++++++++++++++ kernel/cred.c | 6 +++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/include/linux/cred.h b/include/linux/cred.h index 2976f534a7a3..e9f2237e4bf8 100644 --- a/include/linux/cred.h +++ b/include/linux/cred.h @@ -172,6 +172,27 @@ static inline bool cap_ambient_invariant_ok(const struct cred *cred) cred->cap_inheritable)); } +/* + * Override creds without bumping reference count. Caller must ensure + * reference remains valid or has taken reference. Almost always not the + * interface you want. Use override_creds()/revert_creds() instead. + */ +static inline const struct cred *override_creds_light(const struct cred *override_cred) +{ + const struct cred *old = current->cred; + + rcu_assign_pointer(current->cred, override_cred); + return old; +} + +static inline void revert_creds_light(const struct cred *revert_cred) +{ + rcu_assign_pointer(current->cred, revert_cred); +} + +DEFINE_GUARD(cred, const struct cred *, _T = override_creds_light(_T), + revert_creds_light(_T)); + /** * get_new_cred_many - Get references on a new set of credentials * @cred: The new credentials to reference diff --git a/kernel/cred.c b/kernel/cred.c index c033a201c808..f95f71e3ac1d 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -485,7 +485,7 @@ EXPORT_SYMBOL(abort_creds); */ const struct cred *override_creds(const struct cred *new) { - const struct cred *old = current->cred; + const struct cred *old; kdebug("override_creds(%p{%ld})", new, atomic_long_read(&new->usage)); @@ -499,7 +499,7 @@ const struct cred *override_creds(const struct cred *new) * visible to other threads under RCU. */ get_new_cred((struct cred *)new); - rcu_assign_pointer(current->cred, new); + old = override_creds_light(new); kdebug("override_creds() = %p{%ld}", old, atomic_long_read(&old->usage)); @@ -521,7 +521,7 @@ void revert_creds(const struct cred *old) kdebug("revert_creds(%p{%ld})", old, atomic_long_read(&old->usage)); - rcu_assign_pointer(current->cred, old); + revert_creds_light(old); put_cred(override); } EXPORT_SYMBOL(revert_creds); From patchwork Thu Jan 25 23:57:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vinicius Costa Gomes X-Patchwork-Id: 192338 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:e09d:b0:103:945f:af90 with SMTP id gm29csp341215dyb; Thu, 25 Jan 2024 16:04:01 -0800 (PST) X-Google-Smtp-Source: AGHT+IG+NA9ao7uQU2+bXe703ZAK8jsrWCUwycujQ5/E/HT5xtrdVocdhqghfie3jABeglZ+m6+C X-Received: by 2002:a17:903:2349:b0:1d7:4b27:4ac3 with SMTP id c9-20020a170903234900b001d74b274ac3mr591102plh.31.1706227441595; Thu, 25 Jan 2024 16:04:01 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706227441; cv=pass; d=google.com; s=arc-20160816; b=Mjp4JvUUR9ob3fN75sHURrjY9AtXZ2YAkyQom3sfuKhUXAUTJ4kaXD9EbXm8anHURZ kGu+yz5gU4ESgZCspA/IEax1axx/klOcQb23N/ihjn4g1pEhcaBhsnK7gSqT8jcj8sat RPZBpyMdEKvWKDl0VRZRhMbz/sWvM52jCrRIUAgICdtATfnENjPnrI0suDoBktyAFgyK ADQtf0XR59a/trRtSE0QjAMz3RdVfOabxsM27ScTtMnaazlhVPTUcO507gsx3GIU3NSn dB1FszTs9xhL4Bqj3xN+PqhFvqYxZIW6fOWLtFtLWPRduq5DMppU3iOZzadJIzscYM79 YU2g== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=l6HeqVHILokN1Xz/bVvYG0f/HXT266NlbMDwCPf4MB8=; fh=0u4WKmQXLbfFx7dTPMZn/CP58jbWkEI+fyqm6Dolj/A=; b=mgiIo1OwicFVSPYBGd2PzJhspZp2tSoc56klyuMWxZhe5kcStAaU+UI71CwJULYF7D iR3VbpW80I6RMfYln+hp88NiqWLcr1q74VdJumRe4iPwztfpXGyUg8VIeFUJlmCYE1LY B5izlGkrjVbXhh8BKU5iwkotaAyVqPzmJGUEp1Ns2F6HnXt2O4YOM+SLwey0KTnENUFZ sUe/f+4zuNeybKn+/7SOkGEc9ns/V0MqzZc6wTPWlB+478biUqt3JKigeKhFVulPivO0 OU6k+UOUW9E95OUWtcjso8r1reemHB5OVHOznK6TyC2pc+JxEneFLuMVAE5tWkhMFirF YMmw== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=k+8V+tpH; arc=pass (i=1 spf=pass spfdomain=intel.com dkim=pass dkdomain=intel.com dmarc=pass fromdomain=intel.com); spf=pass (google.com: domain of linux-kernel+bounces-39434-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-39434-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id m15-20020a17090a158f00b0029039784c87si122219pja.185.2024.01.25.16.04.01 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Jan 2024 16:04:01 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-39434-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) client-ip=147.75.48.161; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=k+8V+tpH; arc=pass (i=1 spf=pass spfdomain=intel.com dkim=pass dkdomain=intel.com dmarc=pass fromdomain=intel.com); spf=pass (google.com: domain of linux-kernel+bounces-39434-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-39434-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id EDE35B26AAF for ; Fri, 26 Jan 2024 00:00:33 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 2CC7113B784; Thu, 25 Jan 2024 23:57:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="k+8V+tpH" Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.8]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 374D81B278; Thu, 25 Jan 2024 23:57:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.8 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706227061; cv=none; b=syDwzh3Z813LQGR11+bBC6WcIhAvH7IdoUFtuD5XzqDf3TBsD5wWGF6TdDjqneOrVmdutcXzsxq5u5LpUyRrVE8TEktiavGsj7jdoxHeaI7FDo/BFTIMCIasKlqbBvzCUsi4yQzpnZFoQJvC5Fgq8TwB9zDaIMNEyKF0F8KhT1w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706227061; c=relaxed/simple; bh=oXu8e8sl63m8R+FJnn7qQsxLgGdBr5LYwt69wUkKx08=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=u1uebOqPFa8klVmXiCv1CXGTbmbl/nbUTGntMmlL7ZWjWFmjjV4TqrlbG70+d7OfUJBua/X5y6Nv03VItdChOsOaKigOfoIFSpIGlNfw+k95FFNLshCZXaO4gt1Y3Se8amING67hxrgKDYrsPTAuQU7/I6TOq0JDZ6sHjyFigrg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=k+8V+tpH; arc=none smtp.client-ip=192.198.163.8 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1706227058; x=1737763058; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=oXu8e8sl63m8R+FJnn7qQsxLgGdBr5LYwt69wUkKx08=; b=k+8V+tpH7qKY5HGUzKQ1cS59kvMSjgtGWdxXNgkk+WgJpIDsizyZNWWE iJFD7VjbSeF6ggYz43I09HqqhNj6ejYUDTKJQYIs3zEN13mJpWYzB95MV MBk2VN7gNWRQDvWS1RXOX/XTd+c++VHJhB2jcb3Ncsuk6HV8gF+lFZMNo ds5PlSBUMrT+qVYDQEe09qK12aFX8ifxmF9J21NCCJKlsVPBu4aQeOqrL XrTJPLqD+kFhvb2AFNsWHxwzpbs8ScA75b6T6tRKMentt6/324AAfEMqK EXgJtARgYaTk7A2pv80RnBH90/47a4uwGHxmlr2kqfzT1zo8WVzsPrL/G g==; X-IronPort-AV: E=McAfee;i="6600,9927,10964"; a="15867571" X-IronPort-AV: E=Sophos;i="6.05,216,1701158400"; d="scan'208";a="15867571" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Jan 2024 15:57:37 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10964"; a="930191104" X-IronPort-AV: E=Sophos;i="6.05,216,1701158400"; d="scan'208";a="930191104" Received: from vcostago-mobl3.jf.intel.com ([10.24.14.99]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Jan 2024 15:57:36 -0800 From: Vinicius Costa Gomes To: brauner@kernel.org, amir73il@gmail.com, hu1.chen@intel.com Cc: miklos@szeredi.hu, malini.bhandaru@intel.com, tim.c.chen@intel.com, mikko.ylinen@intel.com, lizhen.you@intel.com, linux-unionfs@vger.kernel.org, linux-kernel@vger.kernel.org, Vinicius Costa Gomes Subject: [RFC v2 3/4] overlayfs: Optimize credentials usage Date: Thu, 25 Jan 2024 15:57:22 -0800 Message-ID: <20240125235723.39507-4-vinicius.gomes@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240125235723.39507-1-vinicius.gomes@intel.com> References: <20240125235723.39507-1-vinicius.gomes@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789109145489414430 X-GMAIL-MSGID: 1789109145489414430 File operations in overlayfs also check against the credentials of the mounter task, stored in the superblock, this credentials will outlive most of the operations. For these cases, use the recently introduced guard statements to guarantee that override/revert_creds() are paired. Signed-off-by: Vinicius Costa Gomes --- fs/overlayfs/copy_up.c | 4 +-- fs/overlayfs/dir.c | 22 +++++++------ fs/overlayfs/file.c | 70 ++++++++++++++++++++++-------------------- fs/overlayfs/inode.c | 60 +++++++++++++++++++----------------- fs/overlayfs/namei.c | 21 ++++++------- fs/overlayfs/readdir.c | 18 +++++------ fs/overlayfs/util.c | 23 +++++++------- fs/overlayfs/xattrs.c | 34 ++++++++++---------- 8 files changed, 130 insertions(+), 122 deletions(-) diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index b8e25ca51016..55d1f2b60775 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -1202,7 +1202,8 @@ static int ovl_copy_up_flags(struct dentry *dentry, int flags) if (err) return err; - old_cred = ovl_override_creds(dentry->d_sb); + old_cred = ovl_creds(dentry->d_sb); + guard(cred)(old_cred); while (!err) { struct dentry *next; struct dentry *parent = NULL; @@ -1227,7 +1228,6 @@ static int ovl_copy_up_flags(struct dentry *dentry, int flags) dput(parent); dput(next); } - revert_creds(old_cred); return err; } diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index 0f8b4a719237..5aa43a3a7b3e 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -687,9 +687,9 @@ static int ovl_set_link_redirect(struct dentry *dentry) const struct cred *old_cred; int err; - old_cred = ovl_override_creds(dentry->d_sb); + old_cred = ovl_creds(dentry->d_sb); + guard(cred)(old_cred); err = ovl_set_redirect(dentry, false); - revert_creds(old_cred); return err; } @@ -894,12 +894,13 @@ static int ovl_do_remove(struct dentry *dentry, bool is_dir) if (err) goto out; - old_cred = ovl_override_creds(dentry->d_sb); - if (!lower_positive) - err = ovl_remove_upper(dentry, is_dir, &list); - else - err = ovl_remove_and_whiteout(dentry, &list); - revert_creds(old_cred); + old_cred = ovl_creds(dentry->d_sb); + scoped_guard(cred, old_cred) { + if (!lower_positive) + err = ovl_remove_upper(dentry, is_dir, &list); + else + err = ovl_remove_and_whiteout(dentry, &list); + } if (!err) { if (is_dir) clear_nlink(dentry->d_inode); @@ -1146,7 +1147,8 @@ static int ovl_rename(struct mnt_idmap *idmap, struct inode *olddir, goto out; } - old_cred = ovl_override_creds(old->d_sb); + old_cred = ovl_creds(old->d_sb); + old_cred = override_creds_light(old_cred); if (!list_empty(&list)) { opaquedir = ovl_clear_empty(new, &list); @@ -1279,7 +1281,7 @@ static int ovl_rename(struct mnt_idmap *idmap, struct inode *olddir, out_unlock: unlock_rename(new_upperdir, old_upperdir); out_revert_creds: - revert_creds(old_cred); + revert_creds_light(old_cred); if (update_nlink) ovl_nlink_end(new); else diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c index 05536964d37f..482bf78555e2 100644 --- a/fs/overlayfs/file.c +++ b/fs/overlayfs/file.c @@ -42,7 +42,8 @@ static struct file *ovl_open_realfile(const struct file *file, if (flags & O_APPEND) acc_mode |= MAY_APPEND; - old_cred = ovl_override_creds(inode->i_sb); + old_cred = ovl_creds(inode->i_sb); + guard(cred)(old_cred); real_idmap = mnt_idmap(realpath->mnt); err = inode_permission(real_idmap, realinode, MAY_OPEN | acc_mode); if (err) { @@ -54,7 +55,6 @@ static struct file *ovl_open_realfile(const struct file *file, realfile = backing_file_open(&file->f_path, flags, realpath, current_cred()); } - revert_creds(old_cred); pr_debug("open(%p[%pD2/%c], 0%o) -> (%p, 0%o)\n", file, file, ovl_whatisit(inode, realinode), file->f_flags, @@ -214,9 +214,9 @@ static loff_t ovl_llseek(struct file *file, loff_t offset, int whence) ovl_inode_lock(inode); real.file->f_pos = file->f_pos; - old_cred = ovl_override_creds(inode->i_sb); - ret = vfs_llseek(real.file, offset, whence); - revert_creds(old_cred); + old_cred = ovl_creds(inode->i_sb); + scoped_guard(cred, old_cred) + ret = vfs_llseek(real.file, offset, whence); file->f_pos = real.file->f_pos; ovl_inode_unlock(inode); @@ -388,7 +388,6 @@ static ssize_t ovl_splice_write(struct pipe_inode_info *pipe, struct file *out, static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync) { struct fd real; - const struct cred *old_cred; int ret; ret = ovl_sync_status(OVL_FS(file_inode(file)->i_sb)); @@ -401,9 +400,11 @@ static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync) /* Don't sync lower file for fear of receiving EROFS error */ if (file_inode(real.file) == ovl_inode_upper(file_inode(file))) { - old_cred = ovl_override_creds(file_inode(file)->i_sb); + const struct cred *old_cred; + + old_cred = ovl_creds(file_inode(file)->i_sb); + guard(cred)(old_cred); ret = vfs_fsync_range(real.file, start, end, datasync); - revert_creds(old_cred); } fdput(real); @@ -441,9 +442,9 @@ static long ovl_fallocate(struct file *file, int mode, loff_t offset, loff_t len if (ret) goto out_unlock; - old_cred = ovl_override_creds(file_inode(file)->i_sb); - ret = vfs_fallocate(real.file, mode, offset, len); - revert_creds(old_cred); + old_cred = ovl_creds(file_inode(file)->i_sb); + scoped_guard(cred, old_cred) + ret = vfs_fallocate(real.file, mode, offset, len); /* Update size */ ovl_file_modified(file); @@ -466,9 +467,9 @@ static int ovl_fadvise(struct file *file, loff_t offset, loff_t len, int advice) if (ret) return ret; - old_cred = ovl_override_creds(file_inode(file)->i_sb); - ret = vfs_fadvise(real.file, offset, len, advice); - revert_creds(old_cred); + old_cred = ovl_creds(file_inode(file)->i_sb); + scoped_guard(cred, old_cred) + ret = vfs_fadvise(real.file, offset, len, advice); fdput(real); @@ -509,25 +510,25 @@ static loff_t ovl_copyfile(struct file *file_in, loff_t pos_in, goto out_unlock; } - old_cred = ovl_override_creds(file_inode(file_out)->i_sb); - switch (op) { - case OVL_COPY: - ret = vfs_copy_file_range(real_in.file, pos_in, - real_out.file, pos_out, len, flags); - break; + old_cred = ovl_creds(file_inode(file_out)->i_sb); + scoped_guard(cred, old_cred) + switch (op) { + case OVL_COPY: + ret = vfs_copy_file_range(real_in.file, pos_in, + real_out.file, pos_out, len, flags); + break; - case OVL_CLONE: - ret = vfs_clone_file_range(real_in.file, pos_in, - real_out.file, pos_out, len, flags); - break; + case OVL_CLONE: + ret = vfs_clone_file_range(real_in.file, pos_in, + real_out.file, pos_out, len, flags); + break; - case OVL_DEDUPE: - ret = vfs_dedupe_file_range_one(real_in.file, pos_in, - real_out.file, pos_out, len, - flags); - break; - } - revert_creds(old_cred); + case OVL_DEDUPE: + ret = vfs_dedupe_file_range_one(real_in.file, pos_in, + real_out.file, pos_out, len, + flags); + break; + } /* Update size */ ovl_file_modified(file_out); @@ -579,7 +580,6 @@ static loff_t ovl_remap_file_range(struct file *file_in, loff_t pos_in, static int ovl_flush(struct file *file, fl_owner_t id) { struct fd real; - const struct cred *old_cred; int err; err = ovl_real_fdget(file, &real); @@ -587,9 +587,11 @@ static int ovl_flush(struct file *file, fl_owner_t id) return err; if (real.file->f_op->flush) { - old_cred = ovl_override_creds(file_inode(file)->i_sb); + const struct cred *old_cred; + + old_cred = ovl_creds(file_inode(file)->i_sb); + guard(cred)(old_cred); err = real.file->f_op->flush(real.file, id); - revert_creds(old_cred); } fdput(real); diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index c63b31a460be..9047f245ba0b 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -79,9 +79,10 @@ int ovl_setattr(struct mnt_idmap *idmap, struct dentry *dentry, goto out_put_write; inode_lock(upperdentry->d_inode); - old_cred = ovl_override_creds(dentry->d_sb); - err = ovl_do_notify_change(ofs, upperdentry, attr); - revert_creds(old_cred); + old_cred = ovl_creds(dentry->d_sb); + scoped_guard(cred, old_cred) + err = ovl_do_notify_change(ofs, upperdentry, attr); + if (!err) ovl_copyattr(dentry->d_inode); inode_unlock(upperdentry->d_inode); @@ -170,7 +171,8 @@ int ovl_getattr(struct mnt_idmap *idmap, const struct path *path, metacopy_blocks = ovl_is_metacopy_dentry(dentry); type = ovl_path_real(dentry, &realpath); - old_cred = ovl_override_creds(dentry->d_sb); + old_cred = ovl_creds(dentry->d_sb); + guard(cred)(old_cred); err = ovl_do_getattr(&realpath, stat, request_mask, flags); if (err) goto out; @@ -281,8 +283,6 @@ int ovl_getattr(struct mnt_idmap *idmap, const struct path *path, stat->nlink = dentry->d_inode->i_nlink; out: - revert_creds(old_cred); - return err; } @@ -310,7 +310,9 @@ int ovl_permission(struct mnt_idmap *idmap, if (err) return err; - old_cred = ovl_override_creds(inode->i_sb); + old_cred = ovl_creds(inode->i_sb); + guard(cred)(old_cred); + if (!upperinode && !special_file(realinode->i_mode) && mask & MAY_WRITE) { mask &= ~(MAY_WRITE | MAY_APPEND); @@ -318,7 +320,6 @@ int ovl_permission(struct mnt_idmap *idmap, mask |= MAY_READ; } err = inode_permission(mnt_idmap(realpath.mnt), realinode, mask); - revert_creds(old_cred); return err; } @@ -333,9 +334,10 @@ static const char *ovl_get_link(struct dentry *dentry, if (!dentry) return ERR_PTR(-ECHILD); - old_cred = ovl_override_creds(dentry->d_sb); + old_cred = ovl_creds(dentry->d_sb); + guard(cred)(old_cred); p = vfs_get_link(ovl_dentry_real(dentry), done); - revert_creds(old_cred); + return p; } @@ -468,9 +470,9 @@ struct posix_acl *do_ovl_get_acl(struct mnt_idmap *idmap, } else { const struct cred *old_cred; - old_cred = ovl_override_creds(inode->i_sb); + old_cred = ovl_creds(inode->i_sb); + guard(cred)(old_cred); acl = ovl_get_acl_path(&realpath, posix_acl_xattr_name(type), noperm); - revert_creds(old_cred); } return acl; @@ -496,10 +498,11 @@ static int ovl_set_or_remove_acl(struct dentry *dentry, struct inode *inode, struct posix_acl *real_acl; ovl_path_lower(dentry, &realpath); - old_cred = ovl_override_creds(dentry->d_sb); - real_acl = vfs_get_acl(mnt_idmap(realpath.mnt), realdentry, - acl_name); - revert_creds(old_cred); + old_cred = ovl_creds(dentry->d_sb); + scoped_guard(cred, old_cred) + real_acl = vfs_get_acl(mnt_idmap(realpath.mnt), realdentry, + acl_name); + if (IS_ERR(real_acl)) { err = PTR_ERR(real_acl); goto out; @@ -519,12 +522,13 @@ static int ovl_set_or_remove_acl(struct dentry *dentry, struct inode *inode, if (err) goto out; - old_cred = ovl_override_creds(dentry->d_sb); - if (acl) - err = ovl_do_set_acl(ofs, realdentry, acl_name, acl); - else - err = ovl_do_remove_acl(ofs, realdentry, acl_name); - revert_creds(old_cred); + old_cred = ovl_creds(dentry->d_sb); + scoped_guard(cred, old_cred) { + if (acl) + err = ovl_do_set_acl(ofs, realdentry, acl_name, acl); + else + err = ovl_do_remove_acl(ofs, realdentry, acl_name); + } ovl_drop_write(dentry); /* copy c/mtime */ @@ -599,9 +603,9 @@ static int ovl_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, if (!realinode->i_op->fiemap) return -EOPNOTSUPP; - old_cred = ovl_override_creds(inode->i_sb); + old_cred = ovl_creds(inode->i_sb); + guard(cred)(old_cred); err = realinode->i_op->fiemap(realinode, fieinfo, start, len); - revert_creds(old_cred); return err; } @@ -661,7 +665,8 @@ int ovl_fileattr_set(struct mnt_idmap *idmap, if (err) goto out; - old_cred = ovl_override_creds(inode->i_sb); + old_cred = ovl_creds(inode->i_sb); + guard(cred)(old_cred); /* * Store immutable/append-only flags in xattr and clear them * in upper fileattr (in case they were set by older kernel) @@ -672,7 +677,6 @@ int ovl_fileattr_set(struct mnt_idmap *idmap, err = ovl_set_protattr(inode, upperpath.dentry, fa); if (!err) err = ovl_real_fileattr_set(&upperpath, fa); - revert_creds(old_cred); ovl_drop_write(dentry); /* @@ -731,10 +735,10 @@ int ovl_fileattr_get(struct dentry *dentry, struct fileattr *fa) ovl_path_real(dentry, &realpath); - old_cred = ovl_override_creds(inode->i_sb); + old_cred = ovl_creds(inode->i_sb); + guard(cred)(old_cred); err = ovl_real_fileattr_get(&realpath, fa); ovl_fileattr_prot_flags(inode, fa); - revert_creds(old_cred); return err; } diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c index 984ffdaeed6c..0b0258c582a0 100644 --- a/fs/overlayfs/namei.c +++ b/fs/overlayfs/namei.c @@ -946,13 +946,12 @@ static int ovl_maybe_validate_verity(struct dentry *dentry) if (!ovl_test_flag(OVL_VERIFIED_DIGEST, inode)) { const struct cred *old_cred; - old_cred = ovl_override_creds(dentry->d_sb); + old_cred = ovl_creds(dentry->d_sb); + guard(cred)(old_cred); err = ovl_validate_verity(ofs, &metapath, &datapath); if (err == 0) ovl_set_flag(OVL_VERIFIED_DIGEST, inode); - - revert_creds(old_cred); } ovl_inode_unlock(inode); @@ -984,9 +983,10 @@ static int ovl_maybe_lookup_lowerdata(struct dentry *dentry) if (ovl_dentry_lowerdata(dentry)) goto out; - old_cred = ovl_override_creds(dentry->d_sb); - err = ovl_lookup_data_layers(dentry, redirect, &datapath); - revert_creds(old_cred); + old_cred = ovl_creds(dentry->d_sb); + scoped_guard(cred, old_cred) + err = ovl_lookup_data_layers(dentry, redirect, &datapath); + if (err) goto out_err; @@ -1052,7 +1052,8 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, if (dentry->d_name.len > ofs->namelen) return ERR_PTR(-ENAMETOOLONG); - old_cred = ovl_override_creds(dentry->d_sb); + old_cred = ovl_creds(dentry->d_sb); + guard(cred)(old_cred); upperdir = ovl_dentry_upper(dentry->d_parent); if (upperdir) { d.mnt = ovl_upper_mnt(ofs); @@ -1331,7 +1332,6 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, ovl_dentry_init_reval(dentry, upperdentry, OVL_I_E(inode)); - revert_creds(old_cred); if (origin_path) { dput(origin_path->dentry); kfree(origin_path); @@ -1355,7 +1355,6 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, kfree(upperredirect); out: kfree(d.redirect); - revert_creds(old_cred); return ERR_PTR(err); } @@ -1379,7 +1378,8 @@ bool ovl_lower_positive(struct dentry *dentry) if (!ovl_dentry_upper(dentry)) return true; - old_cred = ovl_override_creds(dentry->d_sb); + old_cred = ovl_creds(dentry->d_sb); + guard(cred)(old_cred); /* Positive upper -> have to look up lower to see whether it exists */ for (i = 0; !done && !positive && i < ovl_numlower(poe); i++) { struct dentry *this; @@ -1412,7 +1412,6 @@ bool ovl_lower_positive(struct dentry *dentry) dput(this); } } - revert_creds(old_cred); return positive; } diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c index e71156baa7bc..58ea942921fc 100644 --- a/fs/overlayfs/readdir.c +++ b/fs/overlayfs/readdir.c @@ -275,7 +275,8 @@ static int ovl_check_whiteouts(const struct path *path, struct ovl_readdir_data struct dentry *dentry, *dir = path->dentry; const struct cred *old_cred; - old_cred = ovl_override_creds(rdd->dentry->d_sb); + old_cred = ovl_creds(rdd->dentry->d_sb); + guard(cred)(old_cred); err = down_write_killable(&dir->d_inode->i_rwsem); if (!err) { @@ -290,7 +291,6 @@ static int ovl_check_whiteouts(const struct path *path, struct ovl_readdir_data } inode_unlock(dir->d_inode); } - revert_creds(old_cred); return err; } @@ -755,7 +755,8 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx) const struct cred *old_cred; int err; - old_cred = ovl_override_creds(dentry->d_sb); + old_cred = ovl_creds(dentry->d_sb); + guard(cred)(old_cred); if (!ctx->pos) ovl_dir_reset(file); @@ -807,7 +808,6 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx) } err = 0; out: - revert_creds(old_cred); return err; } @@ -857,9 +857,9 @@ static struct file *ovl_dir_open_realfile(const struct file *file, struct file *res; const struct cred *old_cred; - old_cred = ovl_override_creds(file_inode(file)->i_sb); + old_cred = ovl_creds(file_inode(file)->i_sb); + guard(cred)(old_cred); res = ovl_path_open(realpath, O_RDONLY | (file->f_flags & O_LARGEFILE)); - revert_creds(old_cred); return res; } @@ -984,9 +984,9 @@ int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list) struct rb_root root = RB_ROOT; const struct cred *old_cred; - old_cred = ovl_override_creds(dentry->d_sb); - err = ovl_dir_read_merged(dentry, list, &root); - revert_creds(old_cred); + old_cred = ovl_creds(dentry->d_sb); + scoped_guard(cred, old_cred) + err = ovl_dir_read_merged(dentry, list, &root); if (err) return err; diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 0217094c23ea..7ba8449d920e 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -1157,15 +1157,16 @@ int ovl_nlink_start(struct dentry *dentry) if (d_is_dir(dentry) || !ovl_test_flag(OVL_INDEX, inode)) return 0; - old_cred = ovl_override_creds(dentry->d_sb); - /* - * The overlay inode nlink should be incremented/decremented IFF the - * upper operation succeeds, along with nlink change of upper inode. - * Therefore, before link/unlink/rename, we store the union nlink - * value relative to the upper inode nlink in an upper inode xattr. - */ - err = ovl_set_nlink_upper(dentry); - revert_creds(old_cred); + old_cred = ovl_creds(dentry->d_sb); + scoped_guard(cred, old_cred) { + /* + * The overlay inode nlink should be incremented/decremented IFF the + * upper operation succeeds, along with nlink change of upper inode. + * Therefore, before link/unlink/rename, we store the union nlink + * value relative to the upper inode nlink in an upper inode xattr. + */ + err = ovl_set_nlink_upper(dentry); + } if (err) goto out_drop_write; @@ -1188,9 +1189,9 @@ void ovl_nlink_end(struct dentry *dentry) if (ovl_test_flag(OVL_INDEX, inode) && inode->i_nlink == 0) { const struct cred *old_cred; - old_cred = ovl_override_creds(dentry->d_sb); + old_cred = ovl_creds(dentry->d_sb); + guard(cred)(old_cred); ovl_cleanup_index(dentry); - revert_creds(old_cred); } ovl_inode_unlock(inode); diff --git a/fs/overlayfs/xattrs.c b/fs/overlayfs/xattrs.c index 383978e4663c..921a7d086fa1 100644 --- a/fs/overlayfs/xattrs.c +++ b/fs/overlayfs/xattrs.c @@ -45,9 +45,9 @@ static int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char if (!value && !upperdentry) { ovl_path_lower(dentry, &realpath); - old_cred = ovl_override_creds(dentry->d_sb); - err = vfs_getxattr(mnt_idmap(realpath.mnt), realdentry, name, NULL, 0); - revert_creds(old_cred); + old_cred = ovl_creds(dentry->d_sb); + scoped_guard(cred, old_cred) + err = vfs_getxattr(mnt_idmap(realpath.mnt), realdentry, name, NULL, 0); if (err < 0) goto out; } @@ -64,15 +64,16 @@ static int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char if (err) goto out; - old_cred = ovl_override_creds(dentry->d_sb); - if (value) { - err = ovl_do_setxattr(ofs, realdentry, name, value, size, - flags); - } else { - WARN_ON(flags != XATTR_REPLACE); - err = ovl_do_removexattr(ofs, realdentry, name); + old_cred = ovl_creds(dentry->d_sb); + scoped_guard(cred, old_cred) { + if (value) { + err = ovl_do_setxattr(ofs, realdentry, name, value, size, + flags); + } else { + WARN_ON(flags != XATTR_REPLACE); + err = ovl_do_removexattr(ofs, realdentry, name); + } } - revert_creds(old_cred); ovl_drop_write(dentry); /* copy c/mtime */ @@ -89,9 +90,9 @@ static int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char struct path realpath; ovl_i_path_real(inode, &realpath); - old_cred = ovl_override_creds(dentry->d_sb); + old_cred = ovl_creds(dentry->d_sb); + guard(cred)(old_cred); res = vfs_getxattr(mnt_idmap(realpath.mnt), realpath.dentry, name, value, size); - revert_creds(old_cred); return res; } @@ -119,9 +120,9 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) const struct cred *old_cred; size_t prefix_len, name_len; - old_cred = ovl_override_creds(dentry->d_sb); - res = vfs_listxattr(realdentry, list, size); - revert_creds(old_cred); + old_cred = ovl_creds(dentry->d_sb); + scoped_guard(cred, old_cred) + res = vfs_listxattr(realdentry, list, size); if (res <= 0 || size == 0) return res; @@ -268,4 +269,3 @@ const struct xattr_handler * const *ovl_xattr_handlers(struct ovl_fs *ofs) return ofs->config.userxattr ? ovl_user_xattr_handlers : ovl_trusted_xattr_handlers; } - From patchwork Thu Jan 25 23:57:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vinicius Costa Gomes X-Patchwork-Id: 192336 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:e09d:b0:103:945f:af90 with SMTP id gm29csp339161dyb; Thu, 25 Jan 2024 16:00:48 -0800 (PST) X-Google-Smtp-Source: AGHT+IG3IsSNJsq3pYaDmjbbJzFlw55t0V9ySzgsOMb5/adY7y25I9CYzfzB/p7JP57Zq//OfV33 X-Received: by 2002:a05:620a:4513:b0:783:e81:d616 with SMTP id t19-20020a05620a451300b007830e81d616mr632357qkp.132.1706227247894; Thu, 25 Jan 2024 16:00:47 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706227247; cv=pass; d=google.com; s=arc-20160816; b=gedaWGM8FDtBf6rzG1faynMk/IZPM7NnDOmhYSi6ywW5JxMfa32fEvQ892y6p8H62u D0dRzhxEu5xNi2saGM6jP0IIBwG48FE8hKfHmI0ZYKum36zLlOqta4SqOU24SEey2bVk rFBP/MpbgVLLzQ3A7z0DTvhyMP54QuOWWPn2MxO6rkNx9AagSINf2kLJmEeIgYmZElpL S2qwwYif/u2UBp3LxipHR3l/jA0B0NYx8vOQ/PEjoYKItC9XmbBBo2ZIgzYX+40rSW0h 3fxpXyVR4uZ+Bs1bRt7cMWMxdyqS6c6L/Xxt/jvUupQGetxSD6GP2ZBEeqsuWacaH7GE Qrrg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=Ha44OJ8HmwdIyPQ8514ZZDxLsGAObe8anTzj7ICw/cQ=; fh=0u4WKmQXLbfFx7dTPMZn/CP58jbWkEI+fyqm6Dolj/A=; b=Oi2yq6fO3j6Q8AFYhOnMDS78UqvV2z6B5CgK5nu55vol0mhJHcXI1r88GxcNtxjBSE bk+QEbegTXg0bSb4CXoVWd+7h+y7ZDJWS6W6xc7e5vfTH1zFd7EmDj5VJ4d6Vv6YJ6C2 G6yh7QB8J6t088031v6DmWJFYInDIz9oI83Cy9r5sR2saEceYAAp3IA9XVtm98ps5s7X 2/7F8tkfW+zW+bi1JVv6BP66kgPpUUsGoehmlN0UcCMvZOQ54soSkLVR+UGpU0JlTCxE pftQTTlU3cW/4VR5nsBEyIwgkpDPDv5P2ldid7O6FNDmCkdU1WVCtZj8Hc5gSqm3QYlr dRwg== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=Rg6zDdom; arc=pass (i=1 spf=pass spfdomain=intel.com dkim=pass dkdomain=intel.com dmarc=pass fromdomain=intel.com); spf=pass (google.com: domain of linux-kernel+bounces-39433-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-39433-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id br14-20020a05620a460e00b007839d7d59d2si112271qkb.144.2024.01.25.16.00.47 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Jan 2024 16:00:47 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-39433-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=Rg6zDdom; arc=pass (i=1 spf=pass spfdomain=intel.com dkim=pass dkdomain=intel.com dmarc=pass fromdomain=intel.com); spf=pass (google.com: domain of linux-kernel+bounces-39433-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-39433-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 6B3601C21722 for ; Fri, 26 Jan 2024 00:00:12 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id BE36C17732; Thu, 25 Jan 2024 23:57:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="Rg6zDdom" Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.8]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D49961B59A; Thu, 25 Jan 2024 23:57:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.8 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706227061; cv=none; b=hw6tyITyJuZdixd6k3mhaGYCovw500s47eMdh11J8jHPCjiVIfhi+k/HGD0a+uCKt2G8y2KCndy8soEQPaMZ6BDrDep3PH/zZfRbBLp1hH1MHnypFrVbiqToVHjQc2t7igbpb/wb2F2olJ7qUtujJNwKVvM3e4IjE9bYhHLaOCw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706227061; c=relaxed/simple; bh=FKBREtj8gYP8EY7HfUrJK9Zp1Jdp/dowThfEAGkB4+4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=I0fpifCzue4hGDGr4o3fduWoYEDAzvrersN9EYyCtZdZZo+WVLwgItNFIwhkV9xLsANUAPxfGCPmLuTHrtEBkqqwN0F7sBo7qM85WhkLgooH5cSvoA16+b2m1EVWW7jmLrxPRiGzhafaVvPG1aQqLRcFFyF6yb342UOsiV/cMP8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=Rg6zDdom; arc=none smtp.client-ip=192.198.163.8 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1706227059; x=1737763059; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=FKBREtj8gYP8EY7HfUrJK9Zp1Jdp/dowThfEAGkB4+4=; b=Rg6zDdomHb701a52Ibx9TbYZRCiwRVHbp67jgaYQks4Ig5lW0yVTqj0P 8CfqWC/bPJ/PIhMrTYjqaYqqE2x4l8lSnSK9UySwegQTiL+mFGAskFeTJ 6dUQGlVNSs3WPBPuGGv66qE4ZQ7OJ1400S4DLrFBNakHum3U2oBS9IhMl kqbp+sEzQEn4fhMCprQqnQ+/oxzRUdUsYQ00IxOHZcmVKW/r6awtEov6m 4nIOROjEo2Tf0OdwSBW8W+PylP807uOAi+XjPmdKrJyqizhAgPj20FoFb V8wNv33LiV34pVi90EfxtYLFlQCaqYfDSiuxnRCZtjGqaYbYkiBeIu+or Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10964"; a="15867575" X-IronPort-AV: E=Sophos;i="6.05,216,1701158400"; d="scan'208";a="15867575" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Jan 2024 15:57:37 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10964"; a="930191107" X-IronPort-AV: E=Sophos;i="6.05,216,1701158400"; d="scan'208";a="930191107" Received: from vcostago-mobl3.jf.intel.com ([10.24.14.99]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Jan 2024 15:57:36 -0800 From: Vinicius Costa Gomes To: brauner@kernel.org, amir73il@gmail.com, hu1.chen@intel.com Cc: miklos@szeredi.hu, malini.bhandaru@intel.com, tim.c.chen@intel.com, mikko.ylinen@intel.com, lizhen.you@intel.com, linux-unionfs@vger.kernel.org, linux-kernel@vger.kernel.org, Vinicius Costa Gomes Subject: [RFC v2 4/4] fs: Optimize credentials reference count for backing file ops Date: Thu, 25 Jan 2024 15:57:23 -0800 Message-ID: <20240125235723.39507-5-vinicius.gomes@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240125235723.39507-1-vinicius.gomes@intel.com> References: <20240125235723.39507-1-vinicius.gomes@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789108942566116636 X-GMAIL-MSGID: 1789108942566116636 For backing file operations, users are expected to pass credentials that will outlive the backing file common operations. Use the specialized guard statements to override/revert the credentials. Signed-off-by: Vinicius Costa Gomes --- fs/backing-file.c | 124 ++++++++++++++++++++++------------------------ 1 file changed, 60 insertions(+), 64 deletions(-) diff --git a/fs/backing-file.c b/fs/backing-file.c index a681f38d84d8..9874f09f860f 100644 --- a/fs/backing-file.c +++ b/fs/backing-file.c @@ -140,7 +140,7 @@ ssize_t backing_file_read_iter(struct file *file, struct iov_iter *iter, struct backing_file_ctx *ctx) { struct backing_aio *aio = NULL; - const struct cred *old_cred; + const struct cred *old_cred = ctx->cred; ssize_t ret; if (WARN_ON_ONCE(!(file->f_mode & FMODE_BACKING))) @@ -153,29 +153,28 @@ ssize_t backing_file_read_iter(struct file *file, struct iov_iter *iter, !(file->f_mode & FMODE_CAN_ODIRECT)) return -EINVAL; - old_cred = override_creds(ctx->cred); - if (is_sync_kiocb(iocb)) { - rwf_t rwf = iocb_to_rw_flags(flags); + scoped_guard(cred, old_cred) { + if (is_sync_kiocb(iocb)) { + rwf_t rwf = iocb_to_rw_flags(flags); - ret = vfs_iter_read(file, iter, &iocb->ki_pos, rwf); - } else { - ret = -ENOMEM; - aio = kmem_cache_zalloc(backing_aio_cachep, GFP_KERNEL); - if (!aio) - goto out; + ret = vfs_iter_read(file, iter, &iocb->ki_pos, rwf); + } else { + ret = -ENOMEM; + aio = kmem_cache_zalloc(backing_aio_cachep, GFP_KERNEL); + if (!aio) + goto out; - aio->orig_iocb = iocb; - kiocb_clone(&aio->iocb, iocb, get_file(file)); - aio->iocb.ki_complete = backing_aio_rw_complete; - refcount_set(&aio->ref, 2); - ret = vfs_iocb_iter_read(file, &aio->iocb, iter); - backing_aio_put(aio); - if (ret != -EIOCBQUEUED) - backing_aio_cleanup(aio, ret); + aio->orig_iocb = iocb; + kiocb_clone(&aio->iocb, iocb, get_file(file)); + aio->iocb.ki_complete = backing_aio_rw_complete; + refcount_set(&aio->ref, 2); + ret = vfs_iocb_iter_read(file, &aio->iocb, iter); + backing_aio_put(aio); + if (ret != -EIOCBQUEUED) + backing_aio_cleanup(aio, ret); + } } out: - revert_creds(old_cred); - if (ctx->accessed) ctx->accessed(ctx->user_file); @@ -187,7 +186,7 @@ ssize_t backing_file_write_iter(struct file *file, struct iov_iter *iter, struct kiocb *iocb, int flags, struct backing_file_ctx *ctx) { - const struct cred *old_cred; + const struct cred *old_cred = ctx->cred; ssize_t ret; if (WARN_ON_ONCE(!(file->f_mode & FMODE_BACKING))) @@ -210,39 +209,37 @@ ssize_t backing_file_write_iter(struct file *file, struct iov_iter *iter, */ flags &= ~IOCB_DIO_CALLER_COMP; - old_cred = override_creds(ctx->cred); - if (is_sync_kiocb(iocb)) { - rwf_t rwf = iocb_to_rw_flags(flags); + scoped_guard(cred, old_cred) { + if (is_sync_kiocb(iocb)) { + rwf_t rwf = iocb_to_rw_flags(flags); - ret = vfs_iter_write(file, iter, &iocb->ki_pos, rwf); - if (ctx->end_write) - ctx->end_write(ctx->user_file); - } else { - struct backing_aio *aio; + ret = vfs_iter_write(file, iter, &iocb->ki_pos, rwf); + if (ctx->end_write) + ctx->end_write(ctx->user_file); + } else { + struct backing_aio *aio; - ret = backing_aio_init_wq(iocb); - if (ret) - goto out; + ret = backing_aio_init_wq(iocb); + if (ret) + return ret; - ret = -ENOMEM; - aio = kmem_cache_zalloc(backing_aio_cachep, GFP_KERNEL); - if (!aio) - goto out; + ret = -ENOMEM; + aio = kmem_cache_zalloc(backing_aio_cachep, GFP_KERNEL); + if (!aio) + return ret; - aio->orig_iocb = iocb; - aio->end_write = ctx->end_write; - kiocb_clone(&aio->iocb, iocb, get_file(file)); - aio->iocb.ki_flags = flags; - aio->iocb.ki_complete = backing_aio_queue_completion; - refcount_set(&aio->ref, 2); - ret = vfs_iocb_iter_write(file, &aio->iocb, iter); - backing_aio_put(aio); - if (ret != -EIOCBQUEUED) - backing_aio_cleanup(aio, ret); + aio->orig_iocb = iocb; + aio->end_write = ctx->end_write; + kiocb_clone(&aio->iocb, iocb, get_file(file)); + aio->iocb.ki_flags = flags; + aio->iocb.ki_complete = backing_aio_queue_completion; + refcount_set(&aio->ref, 2); + ret = vfs_iocb_iter_write(file, &aio->iocb, iter); + backing_aio_put(aio); + if (ret != -EIOCBQUEUED) + backing_aio_cleanup(aio, ret); + } } -out: - revert_creds(old_cred); - return ret; } EXPORT_SYMBOL_GPL(backing_file_write_iter); @@ -252,15 +249,15 @@ ssize_t backing_file_splice_read(struct file *in, loff_t *ppos, unsigned int flags, struct backing_file_ctx *ctx) { - const struct cred *old_cred; + const struct cred *old_cred = ctx->cred; ssize_t ret; if (WARN_ON_ONCE(!(in->f_mode & FMODE_BACKING))) return -EIO; - old_cred = override_creds(ctx->cred); - ret = vfs_splice_read(in, ppos, pipe, len, flags); - revert_creds(old_cred); + scoped_guard(cred, old_cred) { + ret = vfs_splice_read(in, ppos, pipe, len, flags); + } if (ctx->accessed) ctx->accessed(ctx->user_file); @@ -274,7 +271,7 @@ ssize_t backing_file_splice_write(struct pipe_inode_info *pipe, unsigned int flags, struct backing_file_ctx *ctx) { - const struct cred *old_cred; + const struct cred *old_cred = ctx->cred; ssize_t ret; if (WARN_ON_ONCE(!(out->f_mode & FMODE_BACKING))) @@ -284,12 +281,11 @@ ssize_t backing_file_splice_write(struct pipe_inode_info *pipe, if (ret) return ret; - old_cred = override_creds(ctx->cred); - file_start_write(out); - ret = iter_file_splice_write(pipe, out, ppos, len, flags); - file_end_write(out); - revert_creds(old_cred); - + scoped_guard(cred, old_cred) { + file_start_write(out); + ret = iter_file_splice_write(pipe, out, ppos, len, flags); + file_end_write(out); + } if (ctx->end_write) ctx->end_write(ctx->user_file); @@ -300,7 +296,7 @@ EXPORT_SYMBOL_GPL(backing_file_splice_write); int backing_file_mmap(struct file *file, struct vm_area_struct *vma, struct backing_file_ctx *ctx) { - const struct cred *old_cred; + const struct cred *old_cred = ctx->cred; int ret; if (WARN_ON_ONCE(!(file->f_mode & FMODE_BACKING)) || @@ -312,9 +308,9 @@ int backing_file_mmap(struct file *file, struct vm_area_struct *vma, vma_set_file(vma, file); - old_cred = override_creds(ctx->cred); - ret = call_mmap(vma->vm_file, vma); - revert_creds(old_cred); + scoped_guard(cred, old_cred) { + ret = call_mmap(vma->vm_file, vma); + } if (ctx->accessed) ctx->accessed(ctx->user_file);