Message ID | 20230114180224.1777699-2-mjguzik@gmail.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp395950wrn; Sat, 14 Jan 2023 10:18:25 -0800 (PST) X-Google-Smtp-Source: AMrXdXvR6b79cmbztCdUODc6WuLpYJ3Jhaz3+IMt9CbG9YSS5j/QMmAIS0CMyoKBuyfKR3//7MbX X-Received: by 2002:a17:907:a28c:b0:7c1:6794:1623 with SMTP id rd12-20020a170907a28c00b007c167941623mr87998214ejc.58.1673720305374; Sat, 14 Jan 2023 10:18:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1673720305; cv=none; d=google.com; s=arc-20160816; b=r6NWCRw+GkaRl7uKRnv6iYVHeNgHqJYOErkk9JY/tydZN7IkxR9RHBKoB1bUGTqzmc EwcTeZYbYWsjzbqgt2IleBGdZfamIN5sR+sn1F1JEUS5yKtsbBrCAm3cCCQWUWU2u1m4 H3r8uH1b4lSMFZysY+WntLV7/HEynMBTslPj615CZPnKegC7oJWM8lnc4eubaAdzhU4/ ZFqRu3jHpIZEhtHRtWb43Zxac0TfQ21Z9wYdf3FbaupI2pgs3QoDyH8WaEpNaA3s1Par 07+QrmtGO2Xy3jDeRlHYOIaTD7SGbXAraQvaiKPvmOoxNli/raCHcP6P6F08N/gy++F/ fcQQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=DiozvCaMITGYcphAARs79W4NXPgo9KLi6rj9QC8zgn0=; b=OVFh5KgMtaUeKWrNTVA+pOh5QLw7wJAFu6VozzwPMwpdihIkL413QpCmAp8uP4lWeZ 9oxhbBRymW6SlZPBXpDHhHHHo8pPt48zaF68OZj5h2NuuAbfx/saHHxoDokQGOjHx1Dq EN7CAw670UjTlcCAV/jR5Ebg9F+s2Aa5HofLu7dpSDEBeMOh2E/BWSJ74Ozs3MAlC2Wp kEv1p2ODv5ZODrpC+sHF49F2WL/n6rBsIXvOwq0qYOM1GY43IpuKsUMbdQRl+8aqzhJK fdSxybf6OST5ws1+ljES/H92zB2tjnf1HKIr8PX9TLqBdl2d6LmuQEOV6ZvskMcb3Mg+ RvOQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=MQ0GgH52; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id xe6-20020a170907318600b0084cbde35b2fsi25889258ejb.465.2023.01.14.10.18.02; Sat, 14 Jan 2023 10:18:25 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=MQ0GgH52; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230369AbjANSCv (ORCPT <rfc822;stefanalexe802@gmail.com> + 99 others); Sat, 14 Jan 2023 13:02:51 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50042 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230231AbjANSCs (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Sat, 14 Jan 2023 13:02:48 -0500 Received: from mail-ej1-x634.google.com (mail-ej1-x634.google.com [IPv6:2a00:1450:4864:20::634]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ACB4CBBAC; Sat, 14 Jan 2023 10:02:46 -0800 (PST) Received: by mail-ej1-x634.google.com with SMTP id u19so59137626ejm.8; Sat, 14 Jan 2023 10:02:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=DiozvCaMITGYcphAARs79W4NXPgo9KLi6rj9QC8zgn0=; b=MQ0GgH52Jyj5zgcCIKehozrBZUZmbh25poVp6JSmLbjNCBXko2KXRfE2tBAbzXvBHm ZLRh924mbrfN5cOPknP1rGaVdJe8hVMchF6KKzbQ8rqNlZ5osuFg+xyUgZ8yp3DSEeho Hmvq7UftpHgmXri1QZ14UEjZwaU+US+YtQAxytMSuJHwgKj9kz8OWG+Vr6dvXEpAJOGh hc5ulqUcWgHfNzlTG+YDIysgFZvgAZCRrUPKdXdLzq7gTAlmr3yApDj3uS99J5p0RC7g E1yIXrPgn3mBLd6QopWJFUyq5wGJ/0ZGUmQg06PLt82JTPeHubfvMH1H5/Kh9jL8CsMv PZOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=DiozvCaMITGYcphAARs79W4NXPgo9KLi6rj9QC8zgn0=; b=gCzsj9nOAdSOp3bUJLKpH3kcgA9ceb0RsGHQ3nH8JOCD8kVqPyrA/Vmd5Zz6/12Wlx gXqFNJjMj0tP5dLgroS6erGXsndNA2++JZPaS4/9cG2kJe5yoCeO42nJTM3ebhsTCyYq LWQXEKwgWlAKuh1nAJ37Esww5V3C7jVI63IxFCCVOJ1rqsxyzjp96zdp2+Hnsby0Acru 6itGklF0XbBjrlSDwyJurzxPHIEDkRkkxDDYtwPpO/OjeClBJQbjXqc0c/1gMaSUtiBJ 3iW5dUHV3/7JMKXlr44QhnPpgKbRzb89PFWIRIpJOfUv6lL+XloL/nasQK3AVlcnCMTq 1pAg== X-Gm-Message-State: AFqh2kr2pEU2To/wxe8F7aDoFUhyMUIZpP2MiqqboxvGIfBlRokbNUZW QJoGgWHQrbyRWf1q/pzxjwDTKJFSwcU8cg== X-Received: by 2002:a17:907:6e16:b0:7c1:b64:e290 with SMTP id sd22-20020a1709076e1600b007c10b64e290mr126029725ejc.45.1673719365211; Sat, 14 Jan 2023 10:02:45 -0800 (PST) Received: from f.. (cst-prg-72-175.cust.vodafone.cz. [46.135.72.175]) by smtp.gmail.com with ESMTPSA id eg49-20020a05640228b100b00488117821ffsm9623220edb.31.2023.01.14.10.02.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 14 Jan 2023 10:02:44 -0800 (PST) From: Mateusz Guzik <mjguzik@gmail.com> To: viro@zeniv.linux.org.uk Cc: serge@hallyn.com, torvalds@linux-foundation.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, Mateusz Guzik <mjguzik@gmail.com> Subject: [PATCH 2/2] vfs: avoid duplicating creds in faccessat if possible Date: Sat, 14 Jan 2023 19:02:24 +0100 Message-Id: <20230114180224.1777699-2-mjguzik@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230114180224.1777699-1-mjguzik@gmail.com> References: <20230114180224.1777699-1-mjguzik@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1755022943075986094?= X-GMAIL-MSGID: =?utf-8?q?1755022943075986094?= |
Series |
[1/2] capability: add cap_isidentical
|
|
Commit Message
Mateusz Guzik
Jan. 14, 2023, 6:02 p.m. UTC
access(2) remains commonly used, for example on exec:
access("/etc/ld.so.preload", R_OK)
or when running gcc: strace -c gcc empty.c
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
0.00 0.000000 0 42 26 access
It falls down to do_faccessat without the AT_EACCESS flag, which in turn
results in allocation of new creds in order to modify fsuid/fsgid and
caps. This is a very expensive process single-threaded and most notably
multi-threaded, with numerous structures getting refed and unrefed on
imminent new cred destruction.
Turns out for typical consumers the resulting creds would be identical
and this can be checked upfront, avoiding the hard work.
An access benchmark plugged into will-it-scale running on Cascade Lake
shows:
test proc before after
access1 1 1310582 2908735 (+121%) # distinct files
access1 24 4716491 63822173 (+1353%) # distinct files
access2 24 2378041 5370335 (+125%) # same file
The above benchmarks are not integrated into will-it-scale, but can be
found in a pull request:
https://github.com/antonblanchard/will-it-scale/pull/36/files
Signed-off-by: Mateusz Guzik <mjguzik@gmail.com>
---
fs/open.c | 32 +++++++++++++++++++++++++++++++-
1 file changed, 31 insertions(+), 1 deletion(-)
Comments
Hi Mateusz, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on viro-vfs/for-next] [also build test WARNING on linus/master v6.2-rc3 next-20230113] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Mateusz-Guzik/vfs-avoid-duplicating-creds-in-faccessat-if-possible/20230115-020359 base: https://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git for-next patch link: https://lore.kernel.org/r/20230114180224.1777699-2-mjguzik%40gmail.com patch subject: [PATCH 2/2] vfs: avoid duplicating creds in faccessat if possible config: ia64-randconfig-s051-20230115 compiler: ia64-linux-gcc (GCC) 12.1.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # apt-get install sparse # sparse version: v0.6.4-39-gce1a6720-dirty # https://github.com/intel-lab-lkp/linux/commit/66a936fbf1bdfa33fa679f2906b306c426b7d0da git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Mateusz-Guzik/vfs-avoid-duplicating-creds-in-faccessat-if-possible/20230115-020359 git checkout 66a936fbf1bdfa33fa679f2906b306c426b7d0da # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=ia64 olddefconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=ia64 SHELL=/bin/bash If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot <lkp@intel.com> sparse warnings: (new ones prefixed by >>) >> fs/open.c:381:14: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct cred const *cred @@ got struct cred const [noderef] __rcu *cred @@ fs/open.c:381:14: sparse: expected struct cred const *cred fs/open.c:381:14: sparse: got struct cred const [noderef] __rcu *cred fs/open.c:1151:21: sparse: sparse: restricted fmode_t degrades to integer vim +381 fs/open.c 365 366 /* 367 * access() needs to use the real uid/gid, not the effective uid/gid. 368 * We do this by temporarily clearing all FS-related capabilities and 369 * switching the fsuid/fsgid around to the real ones. 370 * 371 * Creating new credentials is expensive, so we try to skip doing it, 372 * which we can if the result would match what we already got. 373 */ 374 static bool access_need_override_creds(int flags) 375 { 376 const struct cred *cred; 377 378 if (flags & AT_EACCESS) 379 return false; 380 > 381 cred = current->cred; 382 if (!uid_eq(cred->fsuid, cred->uid) || 383 !gid_eq(cred->fsgid, cred->gid)) 384 return true; 385 386 if (!issecure(SECURE_NO_SETUID_FIXUP)) { 387 kuid_t root_uid = make_kuid(cred->user_ns, 0); 388 if (!uid_eq(cred->uid, root_uid)) { 389 if (!cap_isclear(cred->cap_effective)) 390 return true; 391 } else { 392 if (!cap_isidentical(cred->cap_effective, 393 cred->cap_permitted)) 394 return true; 395 } 396 } 397 398 return false; 399 } 400
diff --git a/fs/open.c b/fs/open.c index 82c1a28b3308..c5bfc4e3df94 100644 --- a/fs/open.c +++ b/fs/open.c @@ -367,7 +367,37 @@ COMPAT_SYSCALL_DEFINE6(fallocate, int, fd, int, mode, compat_arg_u64_dual(offset * access() needs to use the real uid/gid, not the effective uid/gid. * We do this by temporarily clearing all FS-related capabilities and * switching the fsuid/fsgid around to the real ones. + * + * Creating new credentials is expensive, so we try to skip doing it, + * which we can if the result would match what we already got. */ +static bool access_need_override_creds(int flags) +{ + const struct cred *cred; + + if (flags & AT_EACCESS) + return false; + + cred = current->cred; + if (!uid_eq(cred->fsuid, cred->uid) || + !gid_eq(cred->fsgid, cred->gid)) + return true; + + if (!issecure(SECURE_NO_SETUID_FIXUP)) { + kuid_t root_uid = make_kuid(cred->user_ns, 0); + if (!uid_eq(cred->uid, root_uid)) { + if (!cap_isclear(cred->cap_effective)) + return true; + } else { + if (!cap_isidentical(cred->cap_effective, + cred->cap_permitted)) + return true; + } + } + + return false; +} + static const struct cred *access_override_creds(void) { const struct cred *old_cred; @@ -436,7 +466,7 @@ static long do_faccessat(int dfd, const char __user *filename, int mode, int fla if (flags & AT_EMPTY_PATH) lookup_flags |= LOOKUP_EMPTY; - if (!(flags & AT_EACCESS)) { + if (access_need_override_creds(flags)) { old_cred = access_override_creds(); if (!old_cred) return -ENOMEM;