From nobody Tue Dec 2 02:43:46 2025 Received: from mail-pj1-f42.google.com (mail-pj1-f42.google.com [209.85.216.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B88823093B2 for ; Tue, 18 Nov 2025 08:49:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763455743; cv=none; b=TGmwf7W6kvcT3d90Mf7CpYuGgCZ+m6OwhCF0UcULbWaUuzZPp1WXnIJOjH0n7CD/lSWCb6bJxbzA/OM9GCXKzET5njKW2F14gIEMBcWLsZiTr7Sjbxcyt3wzWiX75LAptwQ/aEY+z3xg938IvYIV7EqZTx7worB+FBDdNSc+2X4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763455743; c=relaxed/simple; bh=RuTyOcTIQsIa1VQF+wrIemSx1Hn8e8BwIKHEiQA93sc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=f/pGjI1lnx1g4sj97faWC8rv3gn7wRtPeAJjje1F+liVA1XA82QimNa2ouXNb63Daj7ZA4QBCLIaxJq0Lt3M/GKSFUd7ko/BNyNmFGVOr/J/DrrzX3cPmGk0nMeKzWp+rIpuXqekW4Kzh60aOg+NXAV2ASMEn9xkhg+9abXAiL0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=N0dVckqG; arc=none smtp.client-ip=209.85.216.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="N0dVckqG" Received: by mail-pj1-f42.google.com with SMTP id 98e67ed59e1d1-3418ad69672so3623551a91.3 for ; Tue, 18 Nov 2025 00:49:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1763455740; x=1764060540; darn=vger.kernel.org; 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=vp0MpNZH1XSmnkdi/mlOHPVzzuRzZWUK9O/KMKN+QwY=; b=N0dVckqGlw0GL37+tAN7TF9F4J3CDoyUYi8q3zi0QYddyhu7Og9G/xvhGhAHEmmkI/ xKX/qf/1oNI1WjELrF4q7i1udQQojyXoOTCwfgC6VDa2bPTQ97fz9t+N2pNQsvd0nW0M SAO3p42fv/Cv6PKZ7TvS5Xr/GbWlVd/B2rjlX7f1eAnnvZ657aJp71LM5YtCELDdjXGY 0VS7RIk4WXjR8RRMI7FRiCoNBHq7On+tYDYpqZpax4DWP5Rr1wRiIQPkDaAJsu6zzd49 rNJntq+yYY23LWc2k5cTh2h5fm8Ns475bN1SlA5i3Tl6IsPvieqTPUJ0I0ClmcWoMhiF qpNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763455740; x=1764060540; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=vp0MpNZH1XSmnkdi/mlOHPVzzuRzZWUK9O/KMKN+QwY=; b=sfHNjm+SMFl8GpMKnKtOOznEc8d/cqzHSI0d6Az8H4RgXKqYb9wQoq8T/X+8yg3gpC Gxd5qr7BtMzarWvlrzzlW9XdsMCAtPZHdT22qSJ1N3xJzfvBmNkqedmLaJi6KvXRrO3a t/FSgui/cBkXlU7MRGrIDHal8f4pOCMuPMIM/h0U/MZRuux4dz7vNIFqq063Mc5t3f1v RTRRcuuSTjFpwZEo6QzWJNjLQgezJXQHQdCRlpEWKlZC0ujkG3BY8fHMR8HoCgCmkNZu UlIWu6FCHreJeUJFvuBY7b10gUoADX04IOOnfHcW9YtnlgXqoLcRkq2fQo5DT5bqv4W+ bLXQ== X-Forwarded-Encrypted: i=1; AJvYcCUI05UeElZQ22wajCjnq9+OBCb3Qi+P3x/cwjMvDSzzzxGt2olZMj3E100o5vis6aZIALoSQU4u3HFx6WY=@vger.kernel.org X-Gm-Message-State: AOJu0YyumKdlLwLgZtpZf+LRo6pn8RJbTPUxr2NgaZFn3EQ+gc1fggL2 v+hzPdygXpKp9cKI5bDw+oho4HCVlUy32h47o1C1cbmCGah1vydUST2K X-Gm-Gg: ASbGnctJRzSOONXpfiIyOYXG5768FyY8ACe7yb6IAv01bby2L4v2cnxM8139GGQWsbX 7N8Ynmkba984q213wTBCk07YOVe2jXNNoqVqDvL5MWi1475/glpNppwPwXuTaeKkxNHy4GCIoME GxRoKDpFkS8WEcLO1xRx4MTi7wwEoL/DdZxD59rgWrGipU3sKKQME5XWyFhFRjzBoYvMo3YsHtP 8MRKukOgGVY1UQP90ZvYoS6EFutd92O/r8yItrME05Bqf0iqOh8VKv9AtzZ/zlvZlvHeIaKV+jf OxUnzVyIP/JnLX0iZmLnlC/oiHgKJobPfw74JoOYTFKALJRNQxe7D5pffOYtZP3eZaJ02X6F2YA 2hFhRHr2amsHMYhSUA4QC48vNlChv6Uz2SfPWYN6u/nKJSJ9KpnNfUcdPQbX5U1qcrX21ZoXMPX XW X-Google-Smtp-Source: AGHT+IG+GRClDMkEK2hjiVfmJtVo3DrOWbGJbOp09mNb0w4tfFqhDJXjtqwFu7hlYuGncAjBckJb8A== X-Received: by 2002:a17:90b:2d85:b0:340:bc27:97b8 with SMTP id 98e67ed59e1d1-343f9e9fed3mr17027369a91.10.1763455740049; Tue, 18 Nov 2025 00:49:00 -0800 (PST) Received: from fedora ([2405:201:3017:184:2d1c:8c4c:2945:3f7c]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-345b01d934csm964041a91.1.2025.11.18.00.48.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Nov 2025 00:48:59 -0800 (PST) From: Bhavik Sachdev To: Alexander Viro , Christian Brauner Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, criu@lists.linux.dev, Aleksa Sarai , Bhavik Sachdev , Pavel Tikhomirov , Jan Kara , John Garry , Arnaldo Carvalho de Melo , "Darrick J . Wong" , Namhyung Kim , Ingo Molnar , Andrei Vagin , Alexander Mikhalitsyn , Miklos Szeredi Subject: [PATCH v6 1/2] statmount: permission check should return EPERM Date: Tue, 18 Nov 2025 14:16:41 +0530 Message-ID: <20251118084836.2114503-2-b.sachdev1904@gmail.com> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20251118084836.2114503-1-b.sachdev1904@gmail.com> References: <20251118084836.2114503-1-b.sachdev1904@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Currently, statmount() returns ENOENT when caller is not CAP_SYS_ADMIN in the current user namespace. This should be EPERM instead. Suggested-by: Miklos Szeredi Signed-off-by: Bhavik Sachdev --- fs/namespace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/namespace.c b/fs/namespace.c index 2bad25709b2c..ee36d67f1ac2 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -5795,7 +5795,7 @@ SYSCALL_DEFINE4(statmount, const struct mnt_id_req __= user *, req, =20 if (kreq.mnt_ns_id && (ns !=3D current->nsproxy->mnt_ns) && !ns_capable_noaudit(ns->user_ns, CAP_SYS_ADMIN)) - return -ENOENT; + return -EPERM; =20 ks =3D kmalloc(sizeof(*ks), GFP_KERNEL_ACCOUNT); if (!ks) --=20 2.51.1 From nobody Tue Dec 2 02:43:46 2025 Received: from mail-pj1-f41.google.com (mail-pj1-f41.google.com [209.85.216.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8656230DD2F for ; Tue, 18 Nov 2025 08:49:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763455749; cv=none; b=uKcJwtcZlp2qDdXABxk73bqNlaHNUHgCKm1Pcmaz/vgeWPq2q6wON0ICe0Fr38Gi65yJOzuUJsWzIwVSLYfkAkKMkgennUSvDIOPW2n6HYE32OkiQyu2TycWpKzluxHZcNB4yB3zc4a1ri5PL3SIEUlAwk+fx46R64EbmMTcJKI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763455749; c=relaxed/simple; bh=W3x1PTmtZ3Z/D0FhN+NbR9sOC5qsrgt2Qb/qnCIsgHs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dkAs7h9CMKM4TWmfvbrcjsI9twy6mEzosiOCS6zzqvUmANneNZYnPDepVjORhlkpXc8J3L6XJ8p98OQGTebNhAlBg2qYKJbMf9yKlnB2zrp92PWO1QyhJZohfTWel1Gk2kh0ruY+QcJGao56luKrpenKHvTZlwmIppR50HnThrA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=gqaCJ54N; arc=none smtp.client-ip=209.85.216.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="gqaCJ54N" Received: by mail-pj1-f41.google.com with SMTP id 98e67ed59e1d1-343684a06b2so4754676a91.1 for ; Tue, 18 Nov 2025 00:49:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1763455747; x=1764060547; darn=vger.kernel.org; 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=fd67JIqjBnffJd56/mtC8XiwZ8ONmUWOMWGf8uhbslw=; b=gqaCJ54Nu69D0CEMX9Wd9ZopYcC5yrsP2dVRt3pcLWwYFnCyF8NznSsOQp1vGpiraM XckG4/sa1QrEMEm80xvDseGsMJCoH7VTjUtcDqa9V4LhTKTbc/VmlDBImqGInZUTeqOK x+JiV9OS3GFQ95ys+Gqh6It1IKKvXwUWOHBFBVi+UWt0MvlW/96wD4eJNYVRbbNys/uk DFe+KlixZOpLXM+ZK021maKgAPuYa2q7YcYY6ozXMNQvdb68Qf4hUACYRV/DDH/QtnOU 9X6XrCDeLYntKONjTyi61O1b5UE0FkskWqTHGdR52ylnwnkU5+qFe/THSA22YCGkmExW fsrA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763455747; x=1764060547; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=fd67JIqjBnffJd56/mtC8XiwZ8ONmUWOMWGf8uhbslw=; b=rUrv3Y2kk8lrcsTe1pEqrDR/gt64WYUamN1Kx83ou0pnaP7kCvndHJOXlshcaHoJFy JE6JeH8kx/IUNCNYSvM9+jrgXxgqwK5iaSzSwQe8uiq8QDIgLkJearFoUB2ap6xmNBRU O1FyKc3RiD1ago1kKgeu6+xJyh3Oftu0ZpQ0irs9oe1D/Mol5iIggmH2o1kMiOaXf+oj 95Xkm0iF0U4gLxpNf60060UbCAyVaKiTPZsUaKY0A5inFVniWhXqvqFWJOyM201OzWCK AeWEPnCFKeiqQWo3339IlYJiTa4xC7mpyx6CKwFEk31RqXQTRggvzDZPtcELnxgcD90e zm1g== X-Forwarded-Encrypted: i=1; AJvYcCVV6CGrK2Mk65y9rGSrL62RL4pcDUtwV7doRdjogJUskNCmI7WjAW2xaECkUuRGEDjCHFFoXizlF+lv07g=@vger.kernel.org X-Gm-Message-State: AOJu0YwLnfYZt/BloaJPO3aLdDeCzAAWhL3WO77AUoESzTZFrGD73cei QUs8ED4aKI2DMDysWbEcW/eLPslzOG3mB20+nl/20Sk4BdsCa9Evg2HV X-Gm-Gg: ASbGncvLi0qsSnhVEEohQlT8k6MF+w/iQxTeR/sqD8YiZ4YG2GorvW8SOV9ndNQ0RF0 eWxR3ogclxIqCFDQbMGQTYI+gTP0vf+vLQRPIaaQxEgQ9fLNbh9VXk7VC4GE4YZXLP1QcpLgWYA KSl45VrEp5P1+aezY8JOMoBiQ7zkn31WVHcntFQiphrZWjlmULH0hoFmdf0EmjCncCzm1+RB47G Gi5d8sdccLwITsY4veSrD49lcGhqw+IiciL4Q/EPWSMKEOE4ui+oWLoiB8RUPIcmwJnpVhwTwy4 eHOMRGZLVz1Cw9J9rRp8rJrQ0LKUeRFVMmG0UFe+BpRZWcpe8JhnPFTn4oLjATPvtoaRSkGsbj9 Y3vE+OcVPiuDFA5lVQlfoxqvKiGBNDmXHZ78xNxK7cInyLQ894JHmtNf2qFMXVIxReyWT03doHy Nw1HZZqG9ndfU= X-Google-Smtp-Source: AGHT+IEgBwuS1DJAsmgPcY9fauxnHgEWvKncpN2aql5DMZ9kFcZP+AJ8w+3vmDc0Q8yljTSaUfNvQw== X-Received: by 2002:a17:90b:4d0d:b0:343:688e:3252 with SMTP id 98e67ed59e1d1-343f9ebca28mr17752724a91.12.1763455746633; Tue, 18 Nov 2025 00:49:06 -0800 (PST) Received: from fedora ([2405:201:3017:184:2d1c:8c4c:2945:3f7c]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-345b01d934csm964041a91.1.2025.11.18.00.49.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Nov 2025 00:49:06 -0800 (PST) From: Bhavik Sachdev To: Alexander Viro , Christian Brauner Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, criu@lists.linux.dev, Aleksa Sarai , Bhavik Sachdev , Pavel Tikhomirov , Jan Kara , John Garry , Arnaldo Carvalho de Melo , "Darrick J . Wong" , Namhyung Kim , Ingo Molnar , Andrei Vagin , Alexander Mikhalitsyn , Miklos Szeredi Subject: [PATCH v6 2/2] statmount: accept fd as a parameter Date: Tue, 18 Nov 2025 14:16:42 +0530 Message-ID: <20251118084836.2114503-3-b.sachdev1904@gmail.com> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20251118084836.2114503-1-b.sachdev1904@gmail.com> References: <20251118084836.2114503-1-b.sachdev1904@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Extend `struct mnt_id_req` to take in a fd and introduce STATMOUNT_BY_FD flag. When a valid fd is provided and STATMOUNT_BY_FD is set, statmount will return mountinfo about the mount the fd is on. This even works for "unmounted" mounts (mounts that have been umounted using umount2(mnt, MNT_DETACH)), if you have access to a file descriptor on that mount. These "umounted" mounts will have no mountpoint and no valid mount namespace. Hence, we unset the STATMOUNT_MNT_POINT and STATMOUNT_MNT_NS_ID in statmount.mask for "unmounted" mounts. In case of STATMOUNT_BY_FD, given that we already have access to an fd on the mount, accessing mount information without a capability check seems fine because of the following reasons: - All fs related information is available via fstatfs() without any capability check. - Mount information is also available via /proc/pid/mountinfo (without any capability check). - Given that we have access to a fd on the mount which tells us that we had access to the mount at some point (or someone that had access gave us the fd). So, we should be able to access mount info. Co-developed-by: Pavel Tikhomirov Signed-off-by: Pavel Tikhomirov Signed-off-by: Bhavik Sachdev --- fs/namespace.c | 99 ++++++++++++++++++++++++++------------ include/uapi/linux/mount.h | 7 ++- 2 files changed, 74 insertions(+), 32 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index ee36d67f1ac2..1c41c6e2304a 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -5563,29 +5563,41 @@ static int grab_requested_root(struct mnt_namespace= *ns, struct path *root) =20 /* locks: namespace_shared */ static int do_statmount(struct kstatmount *s, u64 mnt_id, u64 mnt_ns_id, - struct mnt_namespace *ns) + struct mnt_namespace *ns, unsigned int flags) { struct mount *m; int err; =20 - /* Has the namespace already been emptied? */ - if (mnt_ns_id && mnt_ns_empty(ns)) - return -ENOENT; + /* caller sets s->mnt in case of STATMOUNT_BY_FD */ + if (!(flags & STATMOUNT_BY_FD)) { + /* Has the namespace already been emptied? */ + if (mnt_ns_id && mnt_ns_empty(ns)) + return -ENOENT; =20 - s->mnt =3D lookup_mnt_in_ns(mnt_id, ns); - if (!s->mnt) - return -ENOENT; + s->mnt =3D lookup_mnt_in_ns(mnt_id, ns); + if (!s->mnt) + return -ENOENT; + } =20 - err =3D grab_requested_root(ns, &s->root); - if (err) - return err; + if (ns) { + err =3D grab_requested_root(ns, &s->root); + if (err) + return err; + } else { + /* + * We can't set mount point and mnt_ns_id since we don't have a + * ns for the mount. This can happen if the mount is unmounted + * with MNT_DETACH. + */ + s->mask &=3D ~(STATMOUNT_MNT_POINT | STATMOUNT_MNT_NS_ID); + } =20 /* * Don't trigger audit denials. We just want to determine what * mounts to show users. */ m =3D real_mount(s->mnt); - if (!is_path_reachable(m, m->mnt.mnt_root, &s->root) && + if (ns && !is_path_reachable(m, m->mnt.mnt_root, &s->root) && !ns_capable_noaudit(ns->user_ns, CAP_SYS_ADMIN)) return -EPERM; =20 @@ -5709,7 +5721,7 @@ static int prepare_kstatmount(struct kstatmount *ks, = struct mnt_id_req *kreq, } =20 static int copy_mnt_id_req(const struct mnt_id_req __user *req, - struct mnt_id_req *kreq) + struct mnt_id_req *kreq, unsigned int flags) { int ret; size_t usize; @@ -5727,11 +5739,18 @@ static int copy_mnt_id_req(const struct mnt_id_req = __user *req, ret =3D copy_struct_from_user(kreq, sizeof(*kreq), req, usize); if (ret) return ret; - if (kreq->mnt_ns_fd !=3D 0 && kreq->mnt_ns_id) - return -EINVAL; - /* The first valid unique mount id is MNT_UNIQUE_ID_OFFSET + 1. */ - if (kreq->mnt_id <=3D MNT_UNIQUE_ID_OFFSET) - return -EINVAL; + + if (flags & STATMOUNT_BY_FD) { + if (kreq->mnt_id || kreq->mnt_ns_id) + return -EINVAL; + } else { + if (kreq->fd !=3D 0 && kreq->mnt_ns_id) + return -EINVAL; + + /* The first valid unique mount id is MNT_UNIQUE_ID_OFFSET + 1. */ + if (kreq->mnt_id <=3D MNT_UNIQUE_ID_OFFSET) + return -EINVAL; + } return 0; } =20 @@ -5740,16 +5759,18 @@ static int copy_mnt_id_req(const struct mnt_id_req = __user *req, * that, or if not simply grab a passive reference on our mount namespace = and * return that. */ -static struct mnt_namespace *grab_requested_mnt_ns(const struct mnt_id_req= *kreq) +static struct mnt_namespace *grab_requested_mnt_ns(const struct mnt_id_req= *kreq, + unsigned int flags) { struct mnt_namespace *mnt_ns; =20 if (kreq->mnt_ns_id) { mnt_ns =3D lookup_mnt_ns(kreq->mnt_ns_id); - } else if (kreq->mnt_ns_fd) { + /* caller sets mnt_ns in case of STATMOUNT_BY_FD */ + } else if (!(flags & STATMOUNT_BY_FD) && kreq->fd) { struct ns_common *ns; =20 - CLASS(fd, f)(kreq->mnt_ns_fd); + CLASS(fd, f)(kreq->fd); if (fd_empty(f)) return ERR_PTR(-EBADF); =20 @@ -5777,25 +5798,38 @@ SYSCALL_DEFINE4(statmount, const struct mnt_id_req = __user *, req, { struct mnt_namespace *ns __free(mnt_ns_release) =3D NULL; struct kstatmount *ks __free(kfree) =3D NULL; + struct file *file_from_fd __free(fput) =3D NULL; + struct vfsmount *fd_mnt; struct mnt_id_req kreq; /* We currently support retrieval of 3 strings. */ size_t seq_size =3D 3 * PATH_MAX; int ret; =20 - if (flags) + if (flags & ~STATMOUNT_BY_FD) return -EINVAL; =20 - ret =3D copy_mnt_id_req(req, &kreq); + ret =3D copy_mnt_id_req(req, &kreq, flags); if (ret) return ret; =20 - ns =3D grab_requested_mnt_ns(&kreq); - if (IS_ERR(ns)) - return PTR_ERR(ns); + if (flags & STATMOUNT_BY_FD) { + file_from_fd =3D fget_raw(kreq.fd); + if (!file_from_fd) + return -EBADF; =20 - if (kreq.mnt_ns_id && (ns !=3D current->nsproxy->mnt_ns) && - !ns_capable_noaudit(ns->user_ns, CAP_SYS_ADMIN)) - return -EPERM; + fd_mnt =3D file_from_fd->f_path.mnt; + ns =3D real_mount(fd_mnt)->mnt_ns; + if (ns) + refcount_inc(&ns->passive); + } else { + ns =3D grab_requested_mnt_ns(&kreq, 0); + if (IS_ERR(ns)) + return PTR_ERR(ns); + + if (kreq.mnt_ns_id && (ns !=3D current->nsproxy->mnt_ns) && + !ns_capable_noaudit(ns->user_ns, CAP_SYS_ADMIN)) + return -EPERM; + } =20 ks =3D kmalloc(sizeof(*ks), GFP_KERNEL_ACCOUNT); if (!ks) @@ -5806,8 +5840,11 @@ SYSCALL_DEFINE4(statmount, const struct mnt_id_req _= _user *, req, if (ret) return ret; =20 + if (flags & STATMOUNT_BY_FD) + ks->mnt =3D fd_mnt; + scoped_guard(namespace_shared) - ret =3D do_statmount(ks, kreq.mnt_id, kreq.mnt_ns_id, ns); + ret =3D do_statmount(ks, kreq.mnt_id, kreq.mnt_ns_id, ns, flags); =20 if (!ret) ret =3D copy_statmount_to_user(ks); @@ -5916,7 +5953,7 @@ static inline int prepare_klistmount(struct klistmoun= t *kls, struct mnt_id_req * if (!kls->kmnt_ids) return -ENOMEM; =20 - ns =3D grab_requested_mnt_ns(kreq); + ns =3D grab_requested_mnt_ns(kreq, 0); if (IS_ERR(ns)) return PTR_ERR(ns); kls->ns =3D ns; @@ -5947,7 +5984,7 @@ SYSCALL_DEFINE4(listmount, const struct mnt_id_req __= user *, req, if (!access_ok(mnt_ids, nr_mnt_ids * sizeof(*mnt_ids))) return -EFAULT; =20 - ret =3D copy_mnt_id_req(req, &kreq); + ret =3D copy_mnt_id_req(req, &kreq, 0); if (ret) return ret; =20 diff --git a/include/uapi/linux/mount.h b/include/uapi/linux/mount.h index 5d3f8c9e3a62..a2156599ddc6 100644 --- a/include/uapi/linux/mount.h +++ b/include/uapi/linux/mount.h @@ -197,7 +197,7 @@ struct statmount { */ struct mnt_id_req { __u32 size; - __u32 mnt_ns_fd; + __u32 fd; __u64 mnt_id; __u64 param; __u64 mnt_ns_id; @@ -232,4 +232,9 @@ struct mnt_id_req { #define LSMT_ROOT 0xffffffffffffffff /* root mount */ #define LISTMOUNT_REVERSE (1 << 0) /* List later mounts first */ =20 +/* + * @flag bits for statmount(2) + */ +#define STATMOUNT_BY_FD 0x00000001U /* want mountinfo for given fd */ + #endif /* _UAPI_LINUX_MOUNT_H */ --=20 2.51.1