From patchwork Wed Mar 6 07:39:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Bobrowski X-Patchwork-Id: 13583445 Received: from mail-ej1-f46.google.com (mail-ej1-f46.google.com [209.85.218.46]) (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 635355C8F9 for ; Wed, 6 Mar 2024 07:39:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709710770; cv=none; b=NcNEaA6qA7qJfCXgRF9AWovzmNdABPTUHKAtJ8mhrMVDpukRcxjNaV1jM4W7QHNLcxJInZvnC9umn4UPjMR2lO9p6ZSxqaRH6nRjrDJvLoZ8mD84grcIchZtBbIWsznOhF4b9c0A73biVzJUq7O1Jd+n73eEWkMRZn356IYolvI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709710770; c=relaxed/simple; bh=T9wyGNUK/a5+R+4NnNzOvivl3qko5cvFamHSS6BHobU=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=NoSA460n8B7d8k6YBWqSnPwcx7aOaAXljzRtFCsxRfbb55O3wKGb3o+WMgyrmpPFHtIQ8WrdSxlsBWzs4cK1UuUVHdPxc9ekKAbMw9M2oM16jfLFQn5sT6uGoEXDaEcHosbwbO6cgylnn5pgS+p/D+9IHjWuAqZvL4jRJ9X0WVE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=IYX5Z56s; arc=none smtp.client-ip=209.85.218.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="IYX5Z56s" Received: by mail-ej1-f46.google.com with SMTP id a640c23a62f3a-a26ed1e05c7so1083138166b.2 for ; Tue, 05 Mar 2024 23:39:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709710767; x=1710315567; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=lKGhvub9+e8WLvaTITikZYN5QDAVXk4MiuBB9Y8ZHfM=; b=IYX5Z56sfNrUJZr1SUPtzFsaooQEAajkLF8knX6XCC7O3AyNfVORM4+v0GqpY57v34 b5K8M5hjbpKFB2Os9joZJnV5EQgeX8T9nNU7WHFCxZx1Jnq0Gy1v+8V6WWIQaNvklrIy 7O9JceoMuctbxkhzkkJ5PzRhd54YOIDR8aMz9QmLMOOPm9o/YbbbQXNsxdUbt6UCu4lO tZGVafEa/BA9pgPLOKjprlqc2zAjkX685oEWZeOSiwn2kE3kTrNZdQbYXUxrjhFVYZib tOG58K0xG2OO870EVgtYdeujJHcyscV5HMvHdRiw2KvOYBzMDX4YOdmLBqKEHBfMX1p2 OxCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709710767; x=1710315567; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=lKGhvub9+e8WLvaTITikZYN5QDAVXk4MiuBB9Y8ZHfM=; b=bLRtCwyM2KgyAvEydZv9X4hJDe4Cd0Ziijem/YSMtZJYmfua9zMOF+TRJxixvYjPro 1pcW6BQWbE0mvOb6bL9w/iJ4YhWBbUBg0+Q9laK8Z778U4ARzvb7xH+8WocBA+cY2GZD S1StFfDSM1lJPLDgicrL452dIuHAZIondDON7mDOAVBR3oWtXwhjg6Ha6cnZyVQIiYVv jCG2nNUtg+2AFZc39EhZGEUNjBNm0CmM8zNbAWDf+p0s3sHv5/jvAKS6F+2zA1FYCcFI cGXzXZYfK14NWxyLhb69pIItcYZPYEgExA+v2MGYbWTmkzfEfifxrHX8UXRrzQCwB7he TmsQ== X-Forwarded-Encrypted: i=1; AJvYcCXJKhnfDuB4ujkv4fSivQ3kusM5Hx6XB2QG+JZ63JlNVc/XTSYW/UEjznwO/wZgaWg19CNWHldEtRBARXH6D3pmwNX90BuIxki5a8hjKw== X-Gm-Message-State: AOJu0Yyn7ri23IrXDDpbZ3Cd0tkBV+hZJat0iimM0zz/uodJWDVqVPPf qp6U95kHRqGtUNZcSYMXJnPPcwv6I2bf6k6AS9OGDvmHQ2Qlb/RjN2P/C/pS6Q== X-Google-Smtp-Source: AGHT+IFucscsSNmNlMP+XPI0+EFS5ODgbdCNT788DnByzIdHvN/V1lhu7I+wjq6DDchyuikxQvNcYg== X-Received: by 2002:a17:906:4888:b0:a45:b1cf:42f6 with SMTP id v8-20020a170906488800b00a45b1cf42f6mr1523135ejq.9.1709710766566; Tue, 05 Mar 2024 23:39:26 -0800 (PST) Received: from google.com (12.196.204.35.bc.googleusercontent.com. [35.204.196.12]) by smtp.gmail.com with ESMTPSA id wk16-20020a170907055000b00a4532d289edsm3429198ejb.116.2024.03.05.23.39.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Mar 2024 23:39:26 -0800 (PST) Date: Wed, 6 Mar 2024 07:39:22 +0000 From: Matt Bobrowski To: bpf@vger.kernel.org Cc: ast@kernel.org, andrii@kernel.org, kpsingh@google.com, jannh@google.com, jolsa@kernel.org, daniel@iogearbox.net, brauner@kernel.org, torvalds@linux-foundation.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v2 bpf-next 1/9] bpf: rename fs_kfunc_set_ids to lsm_kfunc_set_ids Message-ID: <18b6eeea5fa3db45a7a3faba0066b5635e998585.1709675979.git.mattbobrowski@google.com> References: Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: fs_kfunc_set_ids is rather specific to a single BPF kfunc at the moment. Rename it to something a little more generic such that other future BPF kfuncs that are also restricted to BPF LSM program types can reside in the same btf_kfunc_id_set and make use of the same btf_kfunc_filter_t. Signed-off-by: Matt Bobrowski --- kernel/trace/bpf_trace.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 241ddf5e3895..f639663ac339 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -1435,7 +1435,7 @@ static int __init bpf_key_sig_kfuncs_init(void) late_initcall(bpf_key_sig_kfuncs_init); #endif /* CONFIG_KEYS */ -/* filesystem kfuncs */ +/* A set of kfuncs that may only be called from BPF LSM program types. */ __bpf_kfunc_start_defs(); /** @@ -1475,31 +1475,33 @@ __bpf_kfunc int bpf_get_file_xattr(struct file *file, const char *name__str, __bpf_kfunc_end_defs(); -BTF_KFUNCS_START(fs_kfunc_set_ids) +BTF_KFUNCS_START(lsm_kfunc_set_ids) BTF_ID_FLAGS(func, bpf_get_file_xattr, KF_SLEEPABLE | KF_TRUSTED_ARGS) -BTF_KFUNCS_END(fs_kfunc_set_ids) +BTF_KFUNCS_END(lsm_kfunc_set_ids) -static int bpf_get_file_xattr_filter(const struct bpf_prog *prog, u32 kfunc_id) +static int bpf_lsm_kfunc_filter(const struct bpf_prog *prog, u32 kfunc_id) { - if (!btf_id_set8_contains(&fs_kfunc_set_ids, kfunc_id)) + if (!btf_id_set8_contains(&lsm_kfunc_set_ids, kfunc_id)) return 0; - /* Only allow to attach from LSM hooks, to avoid recursion */ + /* To avoid recursion, only permit kfuncs included within + * lsm_kfunc_set_ids to be called from BPF LSM program types. + */ return prog->type != BPF_PROG_TYPE_LSM ? -EACCES : 0; } -static const struct btf_kfunc_id_set bpf_fs_kfunc_set = { +static const struct btf_kfunc_id_set bpf_lsm_kfunc_set = { .owner = THIS_MODULE, - .set = &fs_kfunc_set_ids, - .filter = bpf_get_file_xattr_filter, + .set = &lsm_kfunc_set_ids, + .filter = bpf_lsm_kfunc_filter, }; -static int __init bpf_fs_kfuncs_init(void) +static int __init bpf_lsm_kfuncs_init(void) { - return register_btf_kfunc_id_set(BPF_PROG_TYPE_LSM, &bpf_fs_kfunc_set); + return register_btf_kfunc_id_set(BPF_PROG_TYPE_LSM, &bpf_lsm_kfunc_set); } -late_initcall(bpf_fs_kfuncs_init); +late_initcall(bpf_lsm_kfuncs_init); static const struct bpf_func_proto * bpf_tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) From patchwork Wed Mar 6 07:39:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Bobrowski X-Patchwork-Id: 13583446 Received: from mail-ej1-f45.google.com (mail-ej1-f45.google.com [209.85.218.45]) (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 6879B52F6B for ; Wed, 6 Mar 2024 07:39:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709710779; cv=none; b=Tw6ZjY5kqTQ3BfY6DGF5SbnENaL/PuhdzUG8AnwFAp6TljL9Yc6hJ33wpVdChG3TV7utOf483mRabOBQf5eBgJ1fF9qjuNZZZriy9vCkK2XyVvrwIeuSoKx3NUAwoYN0dzp9w1odaHtVlzPd20PdN1PV8XcE6Xr95ng5e5w31KI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709710779; c=relaxed/simple; bh=SjcPFs4FSNGJVgC8/xMl+u/Ln8ryXAZgM6Iqr7AKav8=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=lzicwcepsxTmRcAYVfaydLWloIeIXOfXJxakCCpi5o0h8d2Jnj+ejF8WPxvOYKAb0inL031gMLZU24vg72C68Ht7q7jKARYR4rv2rLvCWJthQrIhJRIsxQivP8zG2iOrdncume1w97Rvehu8mmqUmfaetIpq231XrUZtlOcYdxQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=e9ONgnqH; arc=none smtp.client-ip=209.85.218.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="e9ONgnqH" Received: by mail-ej1-f45.google.com with SMTP id a640c23a62f3a-a458b6d9cfeso301606866b.2 for ; Tue, 05 Mar 2024 23:39:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709710776; x=1710315576; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=Qxd4dSDwNv99KGxLpWUkcR9yGfGt5zeMhN6bbg1OOSY=; b=e9ONgnqH1+Bcbdfc84yzWIlabT7FE0a9H11/wM8LJ1/C/+yQCgWn/7XKeAHqOTj2Ie DYBlWNWB+JNdtKjq/jimQc7k1Y8TsoPAY2aqFLlbTYjrpj+AjWodVpFpFEArHAAnRbIh iodMIaVUxA3DESanSDyn83De5e9yqxfmP/eRnnjA4PO+eh55I1A1m4KnHdqaKyb6+/Gg NiH/RNc8tcnlu6JJfm6EMoZU/qjtfOdHvsGP5Ti8JlA2UUwAQUmfWQMp8lwnnaHoFf6V ADnHxGgJxQink44oLg6wSst9/AtkIBNkRClhFv/hrmfTATUhKD426W0KQdaMD/m18k/f 1Tgw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709710776; x=1710315576; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=Qxd4dSDwNv99KGxLpWUkcR9yGfGt5zeMhN6bbg1OOSY=; b=nTgilafrtKCRnWEzfr2TX3rGf0newoj/w3N58+ZBQMVnwpuekAavMV4y0FZSaJGJJ2 RV+6CEtc6R51W26LNQMvc6kMN+pq5mHPEsxpRGP6Nef/Qop8DpO0UciRapL37Np1xnrw TW59mmADIZGK2FayYAmNsTd2gAe0fB2FaCmIar/VfGIy6LqT+lGJCAIpaa/XB/InbWlE xMyQHMNBI+BkdsFeFJOHWqYjlLK6pXaRWCjmnXVz811vk/6miQqzpQ/Zj2963siDDmL8 +ZiQ2UqnUK8TisLC8IHfCIsJfhIvh6XzfPenY1yYkUQm+2gobY4CD8GAVgVWe6WWU9wW hKtQ== X-Forwarded-Encrypted: i=1; AJvYcCWXEznRrYV+CX44CmbV0W16uoW/4wgu6vsppichsmLeXRrgJdusBP006ELFgVky+m9qE+vi05H3CT8BqxQ1Y5x212LEe3otB4YYQJZw+Q== X-Gm-Message-State: AOJu0Yz4D/pfu31xAw3dWhvdUiLQ+U2Tr1n92MEZthqAmcqf0jgcxRsK y/Urormzkgp7cwCnmnV6+M3raefma/pxEBjMMilKZcuga6RipIIGWUztft5Y+8piCl6k47hiKKA mJA== X-Google-Smtp-Source: AGHT+IFrTJ3SPPS2VPtMnyftJIZ3jaBujsED6xYduhc/AQg4M3oootOZLPE4aPQqjEP7HRt9tCujOQ== X-Received: by 2002:a17:906:7192:b0:a45:a928:8b65 with SMTP id h18-20020a170906719200b00a45a9288b65mr2845141ejk.28.1709710775587; Tue, 05 Mar 2024 23:39:35 -0800 (PST) Received: from google.com (12.196.204.35.bc.googleusercontent.com. [35.204.196.12]) by smtp.gmail.com with ESMTPSA id l18-20020a1709060e1200b00a459094cf61sm1969118eji.115.2024.03.05.23.39.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Mar 2024 23:39:35 -0800 (PST) Date: Wed, 6 Mar 2024 07:39:31 +0000 From: Matt Bobrowski To: bpf@vger.kernel.org Cc: ast@kernel.org, andrii@kernel.org, kpsingh@google.com, jannh@google.com, jolsa@kernel.org, daniel@iogearbox.net, brauner@kernel.org, torvalds@linux-foundation.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v2 bpf-next 2/9] bpf: add new acquire/release BPF kfuncs for mm_struct Message-ID: References: Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: A BPF LSM program will at times introspect the mm_struct that is nested within a given task_struct. Such introspection performed by a BPF LSM program may involve reading virtual addresses out from fields like arg_start/arg_end and env_start/env_end, or reading fields directly out from the backing exe_file. In order to perform reliable reads against fields contained within mm_struct, we need to introduce a new set of BPF kfuncs that have the ability to acquire and release references on the mm_struct that is nested within a task_struct. The following BPF kfuncs have been added in order to support this capability: struct mm_struct *bpf_task_mm_grab(struct task_struct *task); void bpf_mm_drop(struct mm_struct *mm); These new BPF kfuncs are pretty self-explanatory, but in kernel terms bpf_task_mm_grab() effectively allows you to get a reference on the mm_struct nested within a supplied task_struct. Whereas, bpf_mm_drop() allows you put a reference on a previously gotten mm_struct reference. Both BPF kfuncs are also backed by BPF's respective KF_ACQUIRE/KF_RELEASE semantics, ensuring that the BPF program behaves in accordance to the constraints enforced upon it when operating on reference counted in-kernel data structures. Notably, these newly added BPF kfuncs are simple wrappers around the mmgrab() and mmdrop() in-kernel helpers. Both mmgrab() and mmdrop() are used in favour of their somewhat similar counterparts mmget() and mmput() as they're considered to be the more lightweight variants in comparison, and there's no requirement to also pin the underlying address spaces just yet. Signed-off-by: Matt Bobrowski --- kernel/trace/bpf_trace.c | 47 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index f639663ac339..801808b6efb0 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -1473,10 +1473,57 @@ __bpf_kfunc int bpf_get_file_xattr(struct file *file, const char *name__str, return __vfs_getxattr(dentry, dentry->d_inode, name__str, value, value_len); } +/** + * bpf_task_mm_grab - get a reference on the mm_struct nested within the + * supplied task_struct + * @task: task_struct nesting the mm_struct that is to be referenced + * + * Grab a reference on the mm_struct that is nested within the supplied + * *task*. This kfunc will return NULL for threads that do not possess a valid + * mm_struct. For example, those that are flagged as PF_KTHREAD. A reference on + * a mm_struct acquired by this kfunc must be released using bpf_mm_drop(). + * + * This helper only pins the mm_struct and not necessarily the address space + * associated with the referenced mm_struct that is returned from this + * kfunc. Internally, this kfunc leans on mmgrab(), such that calling + * bpf_task_mm_grab() would be analogous to calling mmgrab() outside of BPF + * program context. + * + * Return: A referenced pointer to the mm_struct nested within the supplied + * *task*, or NULL. + */ +__bpf_kfunc struct mm_struct *bpf_task_mm_grab(struct task_struct *task) +{ + struct mm_struct *mm; + + task_lock(task); + mm = task->mm; + if (likely(mm)) + mmgrab(mm); + task_unlock(task); + + return mm; +} + +/** + * bpf_mm_drop - put a reference on the supplied mm_struct + * @mm: mm_struct of which to put a reference on + * + * Put a reference on the supplied *mm*. This kfunc internally leans on + * mmdrop(), such that calling bpf_mm_drop() would be analogous to calling + * mmdrop() outside of BPF program context. + */ +__bpf_kfunc void bpf_mm_drop(struct mm_struct *mm) +{ + mmdrop(mm); +} + __bpf_kfunc_end_defs(); BTF_KFUNCS_START(lsm_kfunc_set_ids) BTF_ID_FLAGS(func, bpf_get_file_xattr, KF_SLEEPABLE | KF_TRUSTED_ARGS) +BTF_ID_FLAGS(func, bpf_task_mm_grab, KF_ACQUIRE | KF_TRUSTED_ARGS | KF_RET_NULL); +BTF_ID_FLAGS(func, bpf_mm_drop, KF_RELEASE); BTF_KFUNCS_END(lsm_kfunc_set_ids) static int bpf_lsm_kfunc_filter(const struct bpf_prog *prog, u32 kfunc_id) From patchwork Wed Mar 6 07:39:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Bobrowski X-Patchwork-Id: 13583447 Received: from mail-ej1-f46.google.com (mail-ej1-f46.google.com [209.85.218.46]) (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 2A1405D46F for ; Wed, 6 Mar 2024 07:39:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709710791; cv=none; b=D6qu7TkdRV2Isy26Ok/tSry9yZed8dQUwNymaH09AoFu6spuYkHB+jjXpq9qCp8N/Bmbvxd/bMnbOPn1amxO60RLtkWUznzoIEHPU1gWLh9sgLS/W/JHaLQLtOE06Jx9N3d+OYFuuNnt4ji0+lScY1fRGq9U0DomAokyR4wFGdc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709710791; c=relaxed/simple; bh=j0BU+hdZp/Ekkgm4kRDElt6pVQ3Oqng2XJrJl/gH0ec=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=Ihx9TXN7pUlmLz0MWAs4Jmirue61Nc+u/kJDjo9flh9vXUby2jLCtUoDPTM2CPd0NzpG3Wtq4Um5o951l9QqGXf/g5UhE6Ly+MNgBMftjAXp+Eza92wryjopsC0OSRoMLaAlKb4xPXg1bpSX7rRy+gNBzJTiF9e1lGVQ/K9Rr04= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=TnklPJAL; arc=none smtp.client-ip=209.85.218.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="TnklPJAL" Received: by mail-ej1-f46.google.com with SMTP id a640c23a62f3a-a458eb7db13so75629266b.2 for ; Tue, 05 Mar 2024 23:39:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709710787; x=1710315587; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=EfIYbSjn/LFCJX5yYTnie0A0VZaeiLz17KaDnMsDNwk=; b=TnklPJALs6vNjzjwHvQEZjhVjEYR4eV1HuBmzpk3Q76Nu3rtK6Jwqjhg0pZnIXkQB8 TfoEYF+wBgl46heLTC7mmIgZbfl38NoMJQcgYXekCkZr8bsJnfohDJt5mMu77AEN7ALB 3mUO0zLcfEf/N487A2b0sOIE+9jM06AUgFc5tCchqFQNbvp18wQ0RMpO3ftL1Xbv1PDX jBfM2kZcvk9wV2JxKi06psf0Uccf3ou9nL+JcFIA3iNiB0LLfXIEgLEvO7BjlADQ5YlZ 3B44MaaVUapfHLhq9onuak3kj9ZjtVanzO0S3fl99ZNPSnArO6vCKf5EDXdWPBjlBeJi yK0w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709710787; x=1710315587; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=EfIYbSjn/LFCJX5yYTnie0A0VZaeiLz17KaDnMsDNwk=; b=noOlaBEdCZ69rKEsXKEhV+Qsj0bCqX3FCARNP/i7dVs8aQR8tcfdDIx9Jb+yBqWgFG h8M3HjmDzpEccMoL6mO2Qok06JIJCQib3jmwTIIdnQKJ10kSUoSkXA3qLhSHHE0XDv4q YFP+yJf+98OrbCk8OeUKsci+XcANKClH7xaadZ5gLUGY/MiUe+CdHTCOjeB8QKzySyJR 6LFyU3nLRsO3QD6BelxtSa5+kLonDiP6Q7ZhPmk7y1JApC8ARD8e0UBGqwq/Qmzbi/2S SMPcR8O3b6bT6T4cYAF+0hSax01DYnqASFpm9rLiCY1CtCVVEVqoh5ILMGSYRilTHa1r 4reg== X-Forwarded-Encrypted: i=1; AJvYcCWNJbGgIqh/kRvjC2da6GjYWGRxqBNjQHg3DETRa1uEhFBjTvTKaGRnZ7IzM8fmjudhKkQOrLbLzkQ5VQA5j5uiBGrGcCMmp22fnABoQw== X-Gm-Message-State: AOJu0YzKTJ8SEqzXWAKSByertR65l+Xi+S/iADUPUGpcdrRulb1JBwMz Dt3/4PZg4tUbrgsgRaLWLoTIBkYvInQPxND9v+VY3GMSChVOHW1nqkQQIx09EA== X-Google-Smtp-Source: AGHT+IEGm8Yg+W/a57m3eOInaBG+TLKqaXf+oNU0QTYTrMYCDZOVdkycqurZRK7OmHpVAX/4OSlN2A== X-Received: by 2002:a17:906:f108:b0:a43:e63b:2ecc with SMTP id gv8-20020a170906f10800b00a43e63b2eccmr9777081ejb.67.1709710787504; Tue, 05 Mar 2024 23:39:47 -0800 (PST) Received: from google.com (12.196.204.35.bc.googleusercontent.com. [35.204.196.12]) by smtp.gmail.com with ESMTPSA id k23-20020a1709063e1700b00a42f6d48c72sm6909943eji.145.2024.03.05.23.39.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Mar 2024 23:39:47 -0800 (PST) Date: Wed, 6 Mar 2024 07:39:43 +0000 From: Matt Bobrowski To: bpf@vger.kernel.org Cc: ast@kernel.org, andrii@kernel.org, kpsingh@google.com, jannh@google.com, jolsa@kernel.org, daniel@iogearbox.net, brauner@kernel.org, torvalds@linux-foundation.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v2 bpf-next 3/9] bpf/selftests: add selftests for mm_struct acquire/release BPF kfuncs Message-ID: <84fc8c3698b4ee83eece7ecef902a1a9a416eafb.1709675979.git.mattbobrowski@google.com> References: Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Add a new mm_kfunc test suite that is responsible for verifying the behaviour of the newly added mm_struct based BPF kfuncs. As of now, these selftests cover the operability of the following: struct mm_struct *bpf_task_mm_grab(struct task_struct *task); void bpf_mm_drop(struct mm_struct *mm); Signed-off-by: Matt Bobrowski --- .../selftests/bpf/prog_tests/mm_kfunc.c | 48 ++++++++ .../selftests/bpf/progs/mm_kfunc_common.h | 19 ++++ .../selftests/bpf/progs/mm_kfunc_failure.c | 103 ++++++++++++++++++ .../selftests/bpf/progs/mm_kfunc_success.c | 30 +++++ 4 files changed, 200 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/mm_kfunc.c create mode 100644 tools/testing/selftests/bpf/progs/mm_kfunc_common.h create mode 100644 tools/testing/selftests/bpf/progs/mm_kfunc_failure.c create mode 100644 tools/testing/selftests/bpf/progs/mm_kfunc_success.c diff --git a/tools/testing/selftests/bpf/prog_tests/mm_kfunc.c b/tools/testing/selftests/bpf/prog_tests/mm_kfunc.c new file mode 100644 index 000000000000..aece5c25486d --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/mm_kfunc.c @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2024 Google LLC. */ + +#define _GNU_SOURCE +#include + +#include "mm_kfunc_failure.skel.h" +#include "mm_kfunc_success.skel.h" + +static void run_test(const char *prog_name) +{ + struct bpf_link *link; + struct bpf_program *prog; + struct mm_kfunc_success *skel; + + skel = mm_kfunc_success__open_and_load(); + if (!ASSERT_OK_PTR(skel, "mm_kfunc_success__open_and_load")) + return; + + link = NULL; + prog = bpf_object__find_program_by_name(skel->obj, prog_name); + if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name")) + goto cleanup; + + link = bpf_program__attach(prog); + ASSERT_OK_PTR(link, "bpf_program__attach"); +cleanup: + bpf_link__destroy(link); + mm_kfunc_success__destroy(skel); +} + +static const char * const success_tests[] = { + "task_mm_grab_drop_from_argument", + "task_mm_acquire_release_from_current", +}; + +void test_mm_kfunc(void) +{ + int i = 0; + + for (; i < ARRAY_SIZE(success_tests); i++) { + if (!test__start_subtest(success_tests[i])) + continue; + run_test(success_tests[i]); + } + + RUN_TESTS(mm_kfunc_failure); +} diff --git a/tools/testing/selftests/bpf/progs/mm_kfunc_common.h b/tools/testing/selftests/bpf/progs/mm_kfunc_common.h new file mode 100644 index 000000000000..043d74d4148b --- /dev/null +++ b/tools/testing/selftests/bpf/progs/mm_kfunc_common.h @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2024 Google LLC. */ + +#ifndef _MM_KFUNC_COMMON_H +#define _MM_KFUNC_COMMON_H + +#include +#include +#include +#include + +#include "bpf_misc.h" + +struct mm_struct *bpf_task_mm_grab(struct task_struct *task) __ksym; +void bpf_mm_drop(struct mm_struct *mm) __ksym; + +char _license[] SEC("license") = "GPL"; + +#endif /* _MM_KFUNC_COMMON_H */ diff --git a/tools/testing/selftests/bpf/progs/mm_kfunc_failure.c b/tools/testing/selftests/bpf/progs/mm_kfunc_failure.c new file mode 100644 index 000000000000..d818dfcab20e --- /dev/null +++ b/tools/testing/selftests/bpf/progs/mm_kfunc_failure.c @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2024 Google LLC. */ + +#include "mm_kfunc_common.h" + +SEC("lsm.s/file_open") +__failure __msg("Possibly NULL pointer passed to trusted arg0") +int BPF_PROG(task_mm_grab_null_kfunc) +{ + struct mm_struct *acquired; + + /* Can't pass a NULL pointer to bpf_task_mm_grab(). */ + acquired = bpf_task_mm_grab(NULL); + if (!acquired) + return 0; + bpf_mm_drop(acquired); + + return 0; +} + +SEC("lsm/task_free") +__failure __msg("R1 must be referenced or trusted") +int BPF_PROG(task_mm_grab_from_lsm_task_free_kfunc, struct task_struct *task) +{ + struct mm_struct *acquired; + + /* The task_struct supplied to this LSM hook isn't trusted. */ + acquired = bpf_task_mm_grab(task); + if (!acquired) + return 0; + bpf_mm_drop(acquired); + + return 0; +} + +SEC("lsm.s/task_alloc") +__failure __msg("arg#0 pointer type STRUCT task_struct must point") +int BPF_PROG(task_mm_grab_fp_kfunc, struct task_struct *task, u64 clone_flags) +{ + struct task_struct *fp; + struct mm_struct *acquired; + + fp = (struct task_struct *)&clone_flags; + /* Can't pass random frame pointer to bpf_task_mm_grab(). */ + acquired = bpf_task_mm_grab(fp); + if (!acquired) + return 0; + bpf_mm_drop(acquired); + + return 0; +} + +SEC("lsm.s/task_alloc") +__failure __msg("Unreleased reference") +int BPF_PROG(task_mm_grab_unreleased_kfunc, struct task_struct *task) +{ + struct mm_struct *acquired; + + acquired = bpf_task_mm_grab(task); + __sink(acquired); + + /* Acquired but never released. */ + return 0; +} + +SEC("lsm.s/task_alloc") +__failure __msg("R1 must be referenced or trusted") +int BPF_PROG(task_mm_drop_untrusted_kfunc, struct task_struct *task) +{ + struct mm_struct *acquired; + + /* task->mm from struct task_struct yields an untrusted pointer. */ + acquired = task->mm; + if (!acquired) + return 0; + bpf_mm_drop(acquired); + + return 0; +} + +SEC("lsm/vm_enough_memory") +__failure __msg("release kernel function bpf_mm_drop expects") +int BPF_PROG(mm_drop_unacquired_kfunc, struct mm_struct *mm) +{ + /* Can't release an unacquired pointer. */ + bpf_mm_drop(mm); + + return 0; +} + +SEC("lsm/vm_enough_memory") +__failure __msg("arg#0 pointer type STRUCT mm_struct must point") +int BPF_PROG(mm_drop_fp_kfunc, struct mm_struct *mm, long pages) +{ + struct mm_struct *fp; + + fp = (struct mm_struct *)&pages; + + /* Can't release random frame pointer. */ + bpf_mm_drop(fp); + + return 0; +} diff --git a/tools/testing/selftests/bpf/progs/mm_kfunc_success.c b/tools/testing/selftests/bpf/progs/mm_kfunc_success.c new file mode 100644 index 000000000000..5400abd2ee2d --- /dev/null +++ b/tools/testing/selftests/bpf/progs/mm_kfunc_success.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2024 Google LLC. */ + +#include "mm_kfunc_common.h" + +SEC("lsm.s/task_alloc") +int BPF_PROG(task_mm_grab_drop_from_argument, struct task_struct *task) +{ + struct mm_struct *acquired; + + acquired = bpf_task_mm_grab(task); + if (!acquired) + return 0; + bpf_mm_drop(acquired); + + return 0; +} + +SEC("lsm.s/file_open") +int BPF_PROG(task_mm_acquire_release_from_current) +{ + struct mm_struct *acquired; + + acquired = bpf_task_mm_grab(bpf_get_current_task_btf()); + if (!acquired) + return 0; + bpf_mm_drop(acquired); + + return 0; +} From patchwork Wed Mar 6 07:40:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Bobrowski X-Patchwork-Id: 13583448 Received: from mail-ej1-f44.google.com (mail-ej1-f44.google.com [209.85.218.44]) (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 236EF5CDC6 for ; Wed, 6 Mar 2024 07:40:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709710807; cv=none; b=jkkeNIz2lj4xA+4QIoQxk8+IWtGXmvx9igyrUeCXz5qcU8rcNcF9DNr6JYmAEOzsjeWIfTbjLGQ5PigNoJemI2BYMV1cI/ZocpP+647cIi+NQ/BGmjVuLOpqglMq8t42TU4zVsGpd6Cp4irfhKmhNz/zT+qZZgjLOMwrJo/76rc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709710807; c=relaxed/simple; bh=jq60zMaSYvap6aAng0em1/G5L7a9DGNMvLjFXCU8hFM=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=pP3WmNt75GYBy0F4wGQ3u5HSBkkWtmdpueTaZ8fyIwLGpQWARaza/Mc3aD0oEzF2ytRGorg/LFwSbs6/lDymSgBiVB7e/U89FB+iiSep8mU8VGwn9DNZpkR1PZdhelt+C3Q5bCHqHasJRYVigY0ht1NGAR0bAX7g1SL/qHLLvKw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=kNsxmjIx; arc=none smtp.client-ip=209.85.218.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="kNsxmjIx" Received: by mail-ej1-f44.google.com with SMTP id a640c23a62f3a-a3ed9cae56fso94223266b.1 for ; Tue, 05 Mar 2024 23:40:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709710804; x=1710315604; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=Wl6HqlXoH1hydmZl0rJB+QoZZFFcJVSr7o6LR8kaTiY=; b=kNsxmjIxX2ZkCluWMUeh/p9pPheAYrBy1i9LubydwTvMQosDHOmNhVOnRer0wqDO3x BlFxIz1rCJgYH4xehHGrALP824oiuQVVnwFE4ySQQVCX6EaVP0a3XScdn2WGZUHpJJWj zx4DxBcNxVY7SQKh0PhHJPGKcgVpNbDioc1XWOTX45aS30T+dB1D1uhZZffXxdNSc3vn FnGyNQUNqfl2ft8K9oRkDjrxbWlphISNsM20kRHnAtgVTQTEgZ6ytjxOYb/Q5hMUk7OA Acvx0ZyhMvUH4E5fBkb4UCnglB9Tc774xUKPIFVkCgxkYnW/qag41LPr8mGrEqlGMZdk tPsQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709710804; x=1710315604; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=Wl6HqlXoH1hydmZl0rJB+QoZZFFcJVSr7o6LR8kaTiY=; b=UK9IaKe2/r6KtVSPOwQ6bS05LU30bCzCpDslnGd8F17+ONT5jqZwLUS251ARE2r3xn SUmUoGx1f8wEVDytGmoLB1RUUblgGR5CIfnLdZLRZ5nfXzPHCEL451+BFzZ3fCtraFWQ MlI1LGEXMtjTvDsblIN17nwDl+PNXepEREKeYDVS0gk3s/9ZuP+0RBOnpI4x1K3GmU4I R+xjFlghrizxZ90gUG0rkV7Onu3y5WZA7U2eglv7HHUCCO5pjFIT5YkSh4znaoXvAcVc OMvgyQE5oaJPvrLXzA2BhBPXhD73s9doso/kjnAHSACSwF8gIMs3K/piAwiu2WLeKFZx A/GQ== X-Forwarded-Encrypted: i=1; AJvYcCWkif5a+m9SB+n8IdHLBa5K8/2EmdhOytR6yp4X5vFZi8xDdbWTLJVFS+zrGELy8WwVJhcNSkCizjerCLI79w+9AgOJcUoei3zQfjPt0w== X-Gm-Message-State: AOJu0YzQL70FoncF/16IfzQ6Py8vTayR7xmdBaNUxRi+sPBWcDNIz/IW 6CQ4vincVTsh4Q6q22iySmZt3IMtvZvIAxxNu3uX3Jnw9alhn6VDQFO60u4lMw== X-Google-Smtp-Source: AGHT+IE7EqIFnAfKo/zl9xpP/NOjjZB5tY1XzeNM14K5O13PxAr4oa3MO7A59bxR5uAUg0vqJWfa8g== X-Received: by 2002:a17:906:b85a:b0:a43:fd2c:663b with SMTP id ga26-20020a170906b85a00b00a43fd2c663bmr4938275ejb.33.1709710804538; Tue, 05 Mar 2024 23:40:04 -0800 (PST) Received: from google.com (12.196.204.35.bc.googleusercontent.com. [35.204.196.12]) by smtp.gmail.com with ESMTPSA id gq13-20020a170906e24d00b00a45621ded4bsm2851865ejb.146.2024.03.05.23.40.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Mar 2024 23:40:04 -0800 (PST) Date: Wed, 6 Mar 2024 07:40:00 +0000 From: Matt Bobrowski To: bpf@vger.kernel.org Cc: ast@kernel.org, andrii@kernel.org, kpsingh@google.com, jannh@google.com, jolsa@kernel.org, daniel@iogearbox.net, brauner@kernel.org, torvalds@linux-foundation.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v2 bpf-next 4/9] bpf: add new acquire/release based BPF kfuncs for exe_file Message-ID: <6a5d425e52eb4d8f7539e841494eac36688ab0da.1709675979.git.mattbobrowski@google.com> References: Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: It is rather common for BPF LSM program types to perform the struct walk current->mm->exe_file and subsequently operate on fields of the backing file. At times, some of these operations involve passing a exe_file's field on to BPF helpers and such i.e. bpf_d_path(¤t->mm->exe_file->f_path). However, doing so isn't necessarily always reliable as the backing file that exe_file is pointing to may be in the midst of being torn down and handing anything contained within this file to BPF helpers and such can lead to memory corruption issues [0]. To alleviate possibly operating on semi-torn down instances of current->mm->exe_file we introduce a set of BPF kfuncs that posses KF_ACQUIRE/KF_RELEASE based semantics. Such BPF kfuncs will allow BPF LSM program types to reliably get/put a reference on a current->mm->exe_file. The following new BPF kfuncs have been added: struct file *bpf_get_task_exe_file(struct task_struct *task); struct file *bpf_get_mm_exe_file(struct mm_struct *mm); void bpf_put_file(struct file *f); Internally, these new BPF kfuncs simply call the preexisting in-kernel functions get_task_exe_file(), get_mm_exe_file(), and fput() accordingly. From a technical standpoint, there's absolutely no need to re-implement such helpers just for BPF as they're currently scoped to BPF LSM program types. Note that we explicitly do not explicitly rely on the use of very low level in-kernel functions like get_file_rcu() and get_file_active() to acquire a reference on current->mm->exe_file and such. This is super subtle code and we probably want to avoid exposing any such subtleties to BPF in the form of BPF kfuncs. Additionally, the usage of a double pointer i.e. struct file **, isn't something that the BPF verifier currently recognizes nor has any intention to recognize for the foreseeable future. [0] https://lore.kernel.org/bpf/CAG48ez0ppjcT=QxU-jtCUfb5xQb3mLr=5FcwddF_VKfEBPs_Dg@mail.gmail.com/ Signed-off-by: Matt Bobrowski --- kernel/trace/bpf_trace.c | 56 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 801808b6efb0..539c58db74d7 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -1518,12 +1518,68 @@ __bpf_kfunc void bpf_mm_drop(struct mm_struct *mm) mmdrop(mm); } +/** + * bpf_get_task_exe_file - get a reference on the exe_file associated with the + * mm_struct that is nested within the supplied + * task_struct + * @task: task_struct of which the nested mm_struct's exe_file is to be + * referenced + * + * Get a reference on the exe_file that is associated with the mm_struct nested + * within the supplied *task*. A reference on a file pointer acquired by this + * kfunc must be released using bpf_put_file(). Internally, this kfunc leans on + * get_task_exe_file(), such that calling bpf_get_task_exe_file() would be + * analogous to calling get_task_exe_file() outside of BPF program context. + * + * Return: A referenced pointer to the exe_file associated with the mm_struct + * nested in the supplied *task*, or NULL. + */ +__bpf_kfunc struct file *bpf_get_task_exe_file(struct task_struct *task) +{ + return get_task_exe_file(task); +} + +/** + * bpf_get_mm_exe_file - get a reference on the exe_file for the supplied + * mm_struct. + * @mm: mm_struct of which the exe_file to get a reference on + * + * Get a reference on the exe_file associated with the supplied *mm*. A + * reference on a file pointer acquired by this kfunc must be released using + * bpf_put_file(). Internally, this kfunc leans on get_mm_exe_file(), such that + * calling bpf_get_mm_exe_file() would be analogous to calling get_mm_exe_file() + * outside of BPF program context. + * + * Return: A referenced file pointer to the exe_file for the supplied *mm*, or + * NULL. + */ +__bpf_kfunc struct file *bpf_get_mm_exe_file(struct mm_struct *mm) +{ + return get_mm_exe_file(mm); +} + +/** + * bpf_put_file - put a reference on the supplied file + * @f: file of which to put a reference on + * + * Put a reference on the supplied *f*. + */ +__bpf_kfunc void bpf_put_file(struct file *f) +{ + fput(f); +} + __bpf_kfunc_end_defs(); BTF_KFUNCS_START(lsm_kfunc_set_ids) BTF_ID_FLAGS(func, bpf_get_file_xattr, KF_SLEEPABLE | KF_TRUSTED_ARGS) BTF_ID_FLAGS(func, bpf_task_mm_grab, KF_ACQUIRE | KF_TRUSTED_ARGS | KF_RET_NULL); BTF_ID_FLAGS(func, bpf_mm_drop, KF_RELEASE); +BTF_ID_FLAGS(func, bpf_get_task_exe_file, + KF_ACQUIRE | KF_TRUSTED_ARGS | KF_RET_NULL) +BTF_ID_FLAGS(func, bpf_get_mm_exe_file, + KF_ACQUIRE | KF_TRUSTED_ARGS | KF_RET_NULL) +BTF_ID_FLAGS(func, bpf_put_file, KF_RELEASE | KF_SLEEPABLE) BTF_KFUNCS_END(lsm_kfunc_set_ids) static int bpf_lsm_kfunc_filter(const struct bpf_prog *prog, u32 kfunc_id) From patchwork Wed Mar 6 07:40:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Bobrowski X-Patchwork-Id: 13583449 Received: from mail-ed1-f50.google.com (mail-ed1-f50.google.com [209.85.208.50]) (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 6E1B35C907 for ; Wed, 6 Mar 2024 07:40:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709710814; cv=none; b=QgrLQbMJLCJp8S1xWW6Zp1QtJC+bka86L2G7w+La0RxFGoQt9O7Ri2F3WQcNwIOhFKq0skshD7THr69V1WZJbdOcNuBqEOawhfjaEsvFGtEInPrDuYWD2NWJUEO6d3ukVVmspIubOAVSkuFTmv06JR7fWGewYKmRBsI+ro4Lnas= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709710814; c=relaxed/simple; bh=nWQLHiPbnXEnGTDf/+TEtdNmum1UyFfr09ckYAnfdxk=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=OwfStoVagClpmMBrsyUA93hJYe+q2m/qna4L7xmgXkfyVfL2HwjxDKv0YsKUe3vH+5g87Es12EZ5KcYvn+uXGdsAuhnV+6dol75F8MdH8j/FHwWb1zdXsxt0KAT7jYEdlme6mbWIDWmeW4VlFDzvbULZMG9RwVs2Dek+1JhEDLk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=KnnULtZN; arc=none smtp.client-ip=209.85.208.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="KnnULtZN" Received: by mail-ed1-f50.google.com with SMTP id 4fb4d7f45d1cf-566adfeced4so6922996a12.1 for ; Tue, 05 Mar 2024 23:40:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709710811; x=1710315611; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=rljFKl8ue5u0Qxh8hXuWfy8iHr7ecePt00Q5/9obMrs=; b=KnnULtZNCKHVECbmCem2h3PkcWCYRXHodlQrL6f3BF8DfnSu7UWGhJAIfG0rsZpuwW P0NrM+xc3YztPi/6eYfl/7Keyrpv3JTQ7wLcDDGXm1iBVRHEeckPcQ7CDF9ce3/upVcO hHaNdsgDdvnf9XPbzebPh7/JbNgHwEBHrwET6RW3eYbWDEEQqiWmNKT87m0PnY6HYCpG IUaBRARR7hlEVqx3E22xMML87oTWzBt6XdWF5lRckVu6/TOhHl+fpDDA52+Zum5I4In4 CfCiZUo9SmWKgLx4wXx0Evt7YKHc1DTgaU4ApN8VSEJCnB3CD6FbqO6JG0kHmO0wN22F dvUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709710811; x=1710315611; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=rljFKl8ue5u0Qxh8hXuWfy8iHr7ecePt00Q5/9obMrs=; b=PAWqIgBSMkg9/D6QIH0s/PohaSzX3v5EsqJVV7XR+TL0OaDGN2qKzy7W0R8b0nWK4a QQT1Dq3pvaNzpNiEaiGHILCODHgcfjwM8HQCHJmaC6pp2zOuVIdvVU/ypJIBuUVX0dC+ 9WOuKVhutpZfZixf6SajmAT8KYyEahM6hP/m1SUUk1Q7GvHSmh/Pnm5tWCQUgBcoV4s1 zIVCV+5yzEOX3SRbYZyhwZhNYII7JBGRr4DSY+6m2gsuCCxiJk/XA+LmTDnwNJzSMXBw sGpFAZdI8BL8DSxL6PgvKJWIn5fuf7/JeZritSbOM6gsQCxux9ybqTAMy5IAWxly1wkL IlgA== X-Forwarded-Encrypted: i=1; AJvYcCVOL9ByhhdiU9wPp4+Tq54kWae3Ldq1ygUmoG0phWmK8XRtFjXMveGusfGhSMYRlTFApLYxj6OuHYgiTw7lx/yLMxkq28ZbcuY+kwZrqw== X-Gm-Message-State: AOJu0YyJL0zj1pRPAxoSXKmzQguMNr8z351HrX0BPD2xUmZPA//k3nb+ +9w0OnhXjY1bHhUcHpQMCefI1PC+VeQVUbguJs6yXOlp00Mx1G2kMgmosVKtjg== X-Google-Smtp-Source: AGHT+IHcz3ExqTFeTnEFmHSWRdYzDZyhuqU88ooD/ZKl4Jnz3VkgtVgt/N8SeENAomI8plBbvipaDw== X-Received: by 2002:a05:6402:35cc:b0:566:f851:f53b with SMTP id z12-20020a05640235cc00b00566f851f53bmr11632189edc.35.1709710810715; Tue, 05 Mar 2024 23:40:10 -0800 (PST) Received: from google.com (12.196.204.35.bc.googleusercontent.com. [35.204.196.12]) by smtp.gmail.com with ESMTPSA id z6-20020a05640240c600b005670d2c253csm4462526edb.13.2024.03.05.23.40.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Mar 2024 23:40:10 -0800 (PST) Date: Wed, 6 Mar 2024 07:40:06 +0000 From: Matt Bobrowski To: bpf@vger.kernel.org Cc: ast@kernel.org, andrii@kernel.org, kpsingh@google.com, jannh@google.com, jolsa@kernel.org, daniel@iogearbox.net, brauner@kernel.org, torvalds@linux-foundation.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v2 bpf-next 5/9] bpf/selftests: add selftests for exe_file acquire/release BPF kfuncs Message-ID: <9c9a652a26671ce5d1278148e63bb8903024031e.1709675979.git.mattbobrowski@google.com> References: Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Add a new exe_file_kfunc test suite that is responsible for verifying the behaviour of the newly added exe_file based BPF kfuncs. For now, this new exe_file_kfunc test suite covers the following BPF kfuncs: struct file *bpf_get_task_exe_file(struct task_struct *task); struct file *bpf_get_mm_exe_file(struct mm_struct *mm); void bpf_put_file(struct file *f); Signed-off-by: Matt Bobrowski --- .../selftests/bpf/prog_tests/exe_file_kfunc.c | 49 +++++ .../bpf/progs/exe_file_kfunc_common.h | 23 +++ .../bpf/progs/exe_file_kfunc_failure.c | 181 ++++++++++++++++++ .../bpf/progs/exe_file_kfunc_success.c | 52 +++++ 4 files changed, 305 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/exe_file_kfunc.c create mode 100644 tools/testing/selftests/bpf/progs/exe_file_kfunc_common.h create mode 100644 tools/testing/selftests/bpf/progs/exe_file_kfunc_failure.c create mode 100644 tools/testing/selftests/bpf/progs/exe_file_kfunc_success.c diff --git a/tools/testing/selftests/bpf/prog_tests/exe_file_kfunc.c b/tools/testing/selftests/bpf/prog_tests/exe_file_kfunc.c new file mode 100644 index 000000000000..5900c1d4e820 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/exe_file_kfunc.c @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2024 Google LLC. */ + +#define _GNU_SOURCE +#include + +#include "exe_file_kfunc_failure.skel.h" +#include "exe_file_kfunc_success.skel.h" + +static void run_test(const char *prog_name) +{ + struct bpf_link *link; + struct bpf_program *prog; + struct exe_file_kfunc_success *skel; + + skel = exe_file_kfunc_success__open_and_load(); + if (!ASSERT_OK_PTR(skel, "file_kfunc_success__open_and_load")) + return; + + link = NULL; + prog = bpf_object__find_program_by_name(skel->obj, prog_name); + if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name")) + goto cleanup; + + link = bpf_program__attach(prog); + ASSERT_OK_PTR(link, "bpf_program__attach"); +cleanup: + bpf_link__destroy(link); + exe_file_kfunc_success__destroy(skel); +} + +static const char * const success_tests[] = { + "get_task_exe_file_and_put_kfunc_from_current", + "get_task_exe_file_and_put_kfunc_from_argument", + "get_mm_exe_file_and_put_kfunc_from_current", +}; + +void test_exe_file_kfunc(void) +{ + int i = 0; + + for (; i < ARRAY_SIZE(success_tests); i++) { + if (!test__start_subtest(success_tests[i])) + continue; + run_test(success_tests[i]); + } + + RUN_TESTS(exe_file_kfunc_failure); +} diff --git a/tools/testing/selftests/bpf/progs/exe_file_kfunc_common.h b/tools/testing/selftests/bpf/progs/exe_file_kfunc_common.h new file mode 100644 index 000000000000..6623bcc130c3 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/exe_file_kfunc_common.h @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2024 Google LLC. */ + +#ifndef _FILE_KFUNC_COMMON_H +#define _FILE_KFUNC_COMMON_H + +#include +#include +#include +#include + +#include "bpf_misc.h" + +struct mm_struct *bpf_task_mm_grab(struct task_struct *task) __ksym; +void bpf_mm_drop(struct mm_struct *mm) __ksym; + +struct file *bpf_get_task_exe_file(struct task_struct *task) __ksym; +struct file *bpf_get_mm_exe_file(struct mm_struct *mm) __ksym; +void bpf_put_file(struct file *f) __ksym; + +char _license[] SEC("license") = "GPL"; + +#endif /* _FILE_KFUNC_COMMON_H */ diff --git a/tools/testing/selftests/bpf/progs/exe_file_kfunc_failure.c b/tools/testing/selftests/bpf/progs/exe_file_kfunc_failure.c new file mode 100644 index 000000000000..8a4464481531 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/exe_file_kfunc_failure.c @@ -0,0 +1,181 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2024 Google LLC. */ + +#include "exe_file_kfunc_common.h" + +SEC("lsm.s/file_open") +__failure __msg("Possibly NULL pointer passed to trusted arg0") +int BPF_PROG(get_task_exe_file_kfunc_null) +{ + struct file *acquired; + + /* Can't pass a NULL pointer to bpf_get_task_exe_file(). */ + acquired = bpf_get_task_exe_file(NULL); + bpf_put_file(acquired); + + return 0; +} + +SEC("lsm.s/file_open") +__failure __msg("Possibly NULL pointer passed to trusted arg0") +int BPF_PROG(get_mm_exe_file_kfunc_null) +{ + struct file *acquired; + + /* Can't pass a NULL pointer to bpf_get_mm_exe_file(). */ + acquired = bpf_get_mm_exe_file(NULL); + bpf_put_file(acquired); + + return 0; +} + +SEC("lsm.s/inode_getxattr") +__failure __msg("arg#0 pointer type STRUCT task_struct must point to scalar, or struct with scalar") +int BPF_PROG(get_task_exe_file_kfunc_fp) +{ + u64 x; + struct file *acquired; + struct task_struct *fp; + + fp = (struct task_struct *)&x; + /* Can't pass random frame pointer to bpf_get_task_exe_file(). */ + acquired = bpf_get_task_exe_file(fp); + bpf_put_file(acquired); + + return 0; +} + +SEC("lsm.s/inode_getxattr") +__failure __msg("arg#0 pointer type STRUCT mm_struct must point to scalar, or struct with scalar") +int BPF_PROG(get_mm_exe_file_kfunc_fp) +{ + int x; + struct file *acquired; + struct mm_struct *fp; + + fp = (struct mm_struct *)&x; + /* Can't pass random frame pointer to bpf_get_mm_exe_file(). */ + acquired = bpf_get_mm_exe_file(fp); + if (!acquired) + return 0; + bpf_put_file(acquired); + + return 0; +} + +SEC("lsm.s/file_open") +__failure __msg("R1 must be referenced or trusted") +int BPF_PROG(get_task_exe_file_kfunc_untrusted) +{ + struct file *acquired; + struct task_struct *parent; + + /* Walking a trusted struct task_struct returned from + * bpf_get_current_task_btf() yields an untrusted pointer. */ + parent = bpf_get_current_task_btf()->parent; + /* Can't pass untrusted pointer to bpf_get_task_exe_file(). */ + acquired = bpf_get_task_exe_file(parent); + if (!acquired) + return 0; + bpf_put_file(acquired); + + return 0; +} + +SEC("lsm.s/file_open") +__failure __msg("R1 must be referenced or trusted") +int BPF_PROG(get_mm_exe_file_kfunc_untrusted) +{ + struct file *acquired; + struct mm_struct *mm; + + /* Walking a struct task_struct obtained from bpf_get_current_task_btf() + * yields an untrusted pointer. */ + mm = bpf_get_current_task_btf()->mm; + /* Can't pass untrusted pointer to bpf_get_mm_exe_file(). */ + acquired = bpf_get_mm_exe_file(mm); + if (!acquired) + return 0; + bpf_put_file(acquired); + + return 0; +} + +SEC("lsm.s/file_open") +__failure __msg("Unreleased reference") +int BPF_PROG(get_task_exe_file_kfunc_unreleased) +{ + struct file *acquired; + + acquired = bpf_get_task_exe_file(bpf_get_current_task_btf()); + if (!acquired) + return 0; + __sink(acquired); + + /* Acquired but never released. */ + return 0; +} + +SEC("lsm.s/file_open") +__failure __msg("Unreleased reference") +int BPF_PROG(get_mm_exe_file_kfunc_unreleased) +{ + struct file *acquired; + struct mm_struct *mm; + + mm = bpf_task_mm_grab(bpf_get_current_task_btf()); + if (!mm) + return 0; + + acquired = bpf_get_mm_exe_file(mm); + if (!acquired) { + bpf_mm_drop(mm); + return 0; + } + __sink(acquired); + bpf_mm_drop(mm); + + /* Acquired but never released. */ + return 0; +} + +SEC("lsm/file_open") +__failure __msg("program must be sleepable to call sleepable kfunc bpf_put_file") +int BPF_PROG(put_file_kfunc_not_sleepable, struct file *f) +{ + struct file *acquired; + + acquired = bpf_get_task_exe_file(bpf_get_current_task_btf()); + if (!acquired) + return 0; + + /* Can't call bpf_put_file() from non-sleepable BPF program. */ + bpf_put_file(acquired); + + return 0; +} + +SEC("lsm.s/file_open") +__failure __msg("release kernel function bpf_put_file expects") +int BPF_PROG(put_file_kfunc_unacquired, struct file *f) +{ + /* Can't release an unacquired pointer. */ + bpf_put_file(f); + + return 0; +} + +SEC("tp_btf/task_newtask") +__failure __msg("calling kernel function bpf_get_task_exe_file is not allowed") +int BPF_PROG(get_task_exe_file_kfunc_not_lsm_prog, struct task_struct *task) +{ + struct file *acquired; + + /* bpf_get_task_exe_file() can only be called from BPF LSM program. */ + acquired = bpf_get_task_exe_file(bpf_get_current_task_btf()); + if (!acquired) + return 0; + bpf_put_file(acquired); + + return 0; +} diff --git a/tools/testing/selftests/bpf/progs/exe_file_kfunc_success.c b/tools/testing/selftests/bpf/progs/exe_file_kfunc_success.c new file mode 100644 index 000000000000..ae789cb0a9ae --- /dev/null +++ b/tools/testing/selftests/bpf/progs/exe_file_kfunc_success.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2024 Google LLC. */ + +#include "exe_file_kfunc_common.h" + +SEC("lsm.s/file_open") +int BPF_PROG(get_task_exe_file_and_put_kfunc_from_current) +{ + struct file *acquired; + + acquired = bpf_get_task_exe_file(bpf_get_current_task_btf()); + if (!acquired) + return 0; + bpf_put_file(acquired); + + return 0; +} + +SEC("lsm.s/task_alloc") +int BPF_PROG(get_task_exe_file_and_put_kfunc_from_argument, + struct task_struct *task) +{ + struct file *acquired; + + acquired = bpf_get_task_exe_file(task); + if (!acquired) + return 0; + bpf_put_file(acquired); + + return 0; +} + +SEC("lsm.s/file_open") +int BPF_PROG(get_mm_exe_file_and_put_kfunc_from_current) +{ + struct file *acquired; + struct mm_struct *mm; + + mm = bpf_task_mm_grab(bpf_get_current_task_btf()); + if (!mm) + return 0; + + acquired = bpf_get_mm_exe_file(mm); + if (!acquired) { + bpf_mm_drop(mm); + return 0; + } + bpf_put_file(acquired); + bpf_mm_drop(mm); + + return 0; +} From patchwork Wed Mar 6 07:40:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Bobrowski X-Patchwork-Id: 13583450 Received: from mail-oo1-f49.google.com (mail-oo1-f49.google.com [209.85.161.49]) (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 2AD9D5C907 for ; Wed, 6 Mar 2024 07:40:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709710821; cv=none; b=GiBZxKKM43ZItveUsazS79MW+/IOxwdedJHAD+kA302IqlCNUBvf8ORaSHKq3FDBQyzaRprMR1MpAlmYPPa7bsXUniubn3JPn8Xe/Fs9AXznU9VtHgoht977aAJxIyEz0+0M9bs+Sp5d8BJX8DAp1RW2JBzZD+eQsWT3OXxJ07Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709710821; c=relaxed/simple; bh=U4vPSgjo1MPCWnJXUOvvXXEqOMay8Ii8QfHFiSKW29s=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=skYbofTassFeIJuvopEHGfOZTf/yMvjOJJR0KMmDGARDnCSyJuuzSjmBU5p3DZogJ8JSWWO2zMsUWP+hDMxfDukrJLdMEyAY+gynG/H/S6oJ4w/XVr+tIWO83AY/jxvdHd4iTI1p+7e9ECsDgyLI3+8g4m/A4a/cJhO/Cd6TTTQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=TaMSQed7; arc=none smtp.client-ip=209.85.161.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="TaMSQed7" Received: by mail-oo1-f49.google.com with SMTP id 006d021491bc7-5a0b1936400so3005474eaf.2 for ; Tue, 05 Mar 2024 23:40:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709710819; x=1710315619; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=Sm//KmoxbXbcsWPglbMLVIS1Px1eJWCW4kUeYbyxn5U=; b=TaMSQed7tiLHZyrBlIazF8lhqDqw49F7ifTFDbVNEv7+Seqsw/i0yFKBj0myqTnc9O I7vs9Q4PNyj4sLMqG1ZeZWS+dZhSGR8oDH6M3wMgdbI9zQ3ggkdgAFvIJrUg6qq6dZVR v1nqyLj4sEYgxx3xnim0snw07/0g3C9sZ5b5CPmmplNk/Ow/SqBVnMxe3l+kyf25a34v TQGPMumOXFtyOeicxzevF75amXdAItCLLPK57xqFjnSH4n0DhX12gPRGlvmY2/tXBLXA bumuhKqVEd7/B+g3um+mD5TmK+u22jqbIq9oaP7sAUzdoTXMt8PyRBrRqS5pJ1o9HmPF 3LBg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709710819; x=1710315619; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=Sm//KmoxbXbcsWPglbMLVIS1Px1eJWCW4kUeYbyxn5U=; b=fviaJnCubS9bO4S9lhC4V0ROPNhI/VnLv8Fb90EpmYkjMUWaItB4ebdb8R7HD9vUKZ vWzyZmU3gIyDshkJU3N+qaccy7emEdMsgb6o0jHDbX7jl8ZS7zaP0fqarqnig/4RXkEl mXFowoW8n/VPioOj+N83zlf4BMks6Q/D4D/tnkveSKtvrQSK+Uph3+onuqxOftwZ2dkP 0YOWSdWdppt4AD3NE8ohIaVvxjkl6VJetQPtPXyd+w578SGo7fW7Xr3U5j1nHA8NFw74 ZGuTQoWSe2V5Osd1m2h6Oi3M+zMF121DaD7t2jm8npRbJWAy1UnaIDIOrSpb9FqY37z1 eLAg== X-Forwarded-Encrypted: i=1; AJvYcCWhaHanbCFvoKIvsf10jfyUySVeMG9C6y9+xSg2iwprtuvSjX+IT0YYy5X85DTdRQiwwyNkeEOx7SGvpvJZQoegG0j/iW+zQvJWb6C2og== X-Gm-Message-State: AOJu0Yys+yJwB/1Xb6uxkTInFqN7b5dLa2Qr/7rKkk+8LPsBB7yJYWSm JpgjDe3yDzT6W8bGjfuwSkJt1oexBamsm/DWxbGrmBO0g57pipdhsWcNEakW/w== X-Google-Smtp-Source: AGHT+IHmnIO9igbiizDOpzZIlfa7wqIYlpixrrFhSdvfq8QmXqsdRfEMPj7zalWSN0v34SoSWoRlvg== X-Received: by 2002:a4a:354d:0:b0:5a0:ea46:ffe9 with SMTP id w13-20020a4a354d000000b005a0ea46ffe9mr3948384oog.7.1709710818904; Tue, 05 Mar 2024 23:40:18 -0800 (PST) Received: from google.com (12.196.204.35.bc.googleusercontent.com. [35.204.196.12]) by smtp.gmail.com with ESMTPSA id e18-20020a9d6e12000000b006e4cd29aecbsm749390otr.47.2024.03.05.23.40.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Mar 2024 23:40:18 -0800 (PST) Date: Wed, 6 Mar 2024 07:40:12 +0000 From: Matt Bobrowski To: bpf@vger.kernel.org Cc: ast@kernel.org, andrii@kernel.org, kpsingh@google.com, jannh@google.com, jolsa@kernel.org, daniel@iogearbox.net, brauner@kernel.org, torvalds@linux-foundation.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v2 bpf-next 6/9] bpf: add acquire/release based BPF kfuncs for fs_struct's paths Message-ID: <458617e6f11863ecf8b3f83710a6606977c4c9cd.1709675979.git.mattbobrowski@google.com> References: Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Add the ability to obtain a reference on the root and pwd paths which are nested within the fs_struct associated with a supplied task_struct. Both fs_struct's root and pwd are commonly operated on in BPF LSM program types and at times are further handed off to BPF helpers and such. There needs to be a mechanism that supports BPF LSM program types the ability to obtain stable handles to such paths in order to avoid possible memory corruption bugs [0]. We provide this mechanism through the introduction of the following new KF_ACQUIRE/KF_RELEASE BPF kfuncs: struct path *bpf_get_task_fs_root(struct task_struct *task); struct path *bpf_get_task_fs_pwd(struct task_struct *task); void bpf_put_path(struct path *path); Note that bpf_get_task_fs_root() and bpf_get_task_fs_pwd() are effectively open-coded variants of the in-kernel helpers get_fs_root() and get_fs_pwd(). We don't lean on these in-kernel helpers directly within the newly introduced BPF kfuncs as leaning on them would be rather awkward as we're wanting to return referenced path pointers directly BPF LSM program types. [0] https://lore.kernel.org/bpf/CAG48ez0ppjcT=QxU-jtCUfb5xQb3mLr=5FcwddF_VKfEBPs_Dg@mail.gmail.com/ Signed-off-by: Matt Bobrowski --- kernel/trace/bpf_trace.c | 83 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 539c58db74d7..84fd87ead20c 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -1569,6 +1570,83 @@ __bpf_kfunc void bpf_put_file(struct file *f) fput(f); } +/** + * bpf_get_task_fs_root - get a reference on the fs_struct's root path for the + * supplied task_struct + * @Task: task_struct of which the fs_struct's root path to get a reference on + * + * Get a reference on the root path nested within the fs_struct of the + * associated *task*. The referenced path retruned from this kfunc must be + * released using bpf_put_path(). + * + * Return: A referenced path pointer to the root path nested within the + * fs_struct of the supplied *task*, or NULL. + */ +__bpf_kfunc struct path *bpf_get_task_fs_root(struct task_struct *task) +{ + struct path *root; + struct fs_struct *fs; + + task_lock(task); + fs = task->fs; + if (unlikely(fs)) { + task_unlock(task); + return NULL; + } + + spin_lock(&fs->lock); + root = &fs->root; + path_get(root); + spin_unlock(&fs->lock); + task_unlock(task); + + return root; +} + +/** + * bpf_get_task_fs_pwd - get a reference on the fs_struct's pwd path for the + * supplied task_struct + * @task: task_struct of which the fs_struct's pwd path to get a reference on + * + * Get a reference on the pwd path nested within the fs_struct of the associated + * *task*. The referenced path retruned from this kfunc must be released using + * bpf_put_path(). + * + * Return: A referenced path pointer to the root path nested within the + * fs_struct of the supplied *task*, or NULL. + */ +__bpf_kfunc struct path *bpf_get_task_fs_pwd(struct task_struct *task) +{ + struct path *pwd; + struct fs_struct *fs; + + task_lock(task); + fs = task->fs; + if (unlikely(fs)) { + task_unlock(task); + return NULL; + } + + spin_lock(&fs->lock); + pwd = &fs->pwd; + path_get(pwd); + spin_unlock(&fs->lock); + task_unlock(task); + + return pwd; +} + +/** + * bpf_put_path - put a reference on the supplied path + * @path: path of which to put a reference on + * + * Put a reference on the supplied *path*. + */ +__bpf_kfunc void bpf_put_path(struct path *path) +{ + path_put(path); +} + __bpf_kfunc_end_defs(); BTF_KFUNCS_START(lsm_kfunc_set_ids) @@ -1580,6 +1658,11 @@ BTF_ID_FLAGS(func, bpf_get_task_exe_file, BTF_ID_FLAGS(func, bpf_get_mm_exe_file, KF_ACQUIRE | KF_TRUSTED_ARGS | KF_RET_NULL) BTF_ID_FLAGS(func, bpf_put_file, KF_RELEASE | KF_SLEEPABLE) +BTF_ID_FLAGS(func, bpf_get_task_fs_root, + KF_ACQUIRE | KF_TRUSTED_ARGS | KF_RET_NULL) +BTF_ID_FLAGS(func, bpf_get_task_fs_pwd, + KF_ACQUIRE | KF_TRUSTED_ARGS | KF_RET_NULL) +BTF_ID_FLAGS(func, bpf_put_path, KF_RELEASE | KF_SLEEPABLE) BTF_KFUNCS_END(lsm_kfunc_set_ids) static int bpf_lsm_kfunc_filter(const struct bpf_prog *prog, u32 kfunc_id) From patchwork Wed Mar 6 07:40:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Bobrowski X-Patchwork-Id: 13583451 Received: from mail-oi1-f179.google.com (mail-oi1-f179.google.com [209.85.167.179]) (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 15F065C60F for ; Wed, 6 Mar 2024 07:40:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709710829; cv=none; b=BOzCcvd91O9BJ94N2xo0k7SKL31lr1dQjv6ZXfDXXK96b8Xfd56z0uEnqpHsyYjNHZvV90jIbkMLptGVqejBt8jQqv7r7ONgOKcHlsPnjC9B6/+wEpvQNYkvw5dbUAQzrERCTJeoGDuwZ+aLq0YwWsKe2EfTCwvlmI73KpZxybs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709710829; c=relaxed/simple; bh=iLwHbf1oA5JxBnipUArq42l7X5KO0sj3Xs/LCM1ozFQ=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=kGEbyO0XvV2EdPBLT1aYB6FpScdKKUGXeQGA/4KY/scInAalmz02WMQ2e1OIRx4URPVWSMukQrxImG5NDWFa+4kkhyLIBfPZZhfbFFQCiI26t5llmsozqKjzFzXED09Wn4YQ0z0mPtm/68/S+cJpqhT9Cn+Hw7m8caian4UZdwo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=B3U7IjL4; arc=none smtp.client-ip=209.85.167.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="B3U7IjL4" Received: by mail-oi1-f179.google.com with SMTP id 5614622812f47-3c1e992f060so1957029b6e.0 for ; Tue, 05 Mar 2024 23:40:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709710827; x=1710315627; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=4298WmfQQE8gZH7rXnLK/a7brfP51MJX0hKZlrVvaHE=; b=B3U7IjL4ZRu4xEROnDLt1qZdriNC1IS6TKGWioMXq8AsDJ9WOS/rAd2Iudvu5amDmc uHW1tPqNCC6vMTHL/j5W81O2OUsLEggF4useMqR9nuoijbaD2sqvoHcXgro+3L9wmlI4 ppKmE6sH2+WRqWL0bPnZIai9zanGnYzmwy6IfLt4SIq/7XyIsp8zMYfBQmiiCd+nskQq 7PNg4py/ufAKFukAO7rnUkT75lG3MtzmEXonYVJD2/AY562+KBKCCAyWUYklY1lGEb4e 2HENmACGfq5pFmNKOd0MNc7eahVF9lYcAunGXrt9mjPCxe/5iXL1VAUtfM5GIab+Hs+E qVCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709710827; x=1710315627; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=4298WmfQQE8gZH7rXnLK/a7brfP51MJX0hKZlrVvaHE=; b=VDh4dg6hVdHMcwqqJanDA4L8RDv8CS5KVZACT7bWbvEcbjPR2ol042sgjc1I4HowVc Z7y3/XDuu5hae6xAIa2ieWTEvLxRmvCutzu91CFr6xcNmYZfen/KzGmJuKF4mDYQYHaN GF/w3orfLJIA3FiHfgiav1LfrF+jBcv0LE1gnsZ0PKkfq0AH3zICHdX87+7A5PYKkJaB v7pmcynNe5/jHv1qRbo049NCu3J5Kn9aG7wYopjk2Q/JT/5XY9yrEIfwFOPGLmrxeF3t 9sZXWez/1eMuRcrXdC+jim4MfzWq5QbVUcx0IuIfWqirk/bKi4OY5+y2uQ+pzBGm8d44 2rwQ== X-Forwarded-Encrypted: i=1; AJvYcCXL1ElMs3qEnbSWB6m/9jWCvxmQyeHpac7rrBYwlbU3jB0xWi7BpuaKKNCJC6r+C81kvUGCY8Fn3rO13Ao3BPczyVUOUgVHCNjsqw3XYA== X-Gm-Message-State: AOJu0Yy09eLFtTaVVNVHFW9WQsQnW1j8i+uNR1N6ApxRiEoBfGBdr3bI c6U0cNKGl1a9w9d/Dlr+EGVdqUu8KaB0hVvZGcg+22vw3WrVjg659A5RatxAAA== X-Google-Smtp-Source: AGHT+IH1U4Q9kPYH7jD7X3wue28RHo6quR1tW4i0OCfLWlq2VwwtJ4Wz34z03CLCwuJbGB3bvEGeKg== X-Received: by 2002:a05:6808:1a91:b0:3c1:f46c:e71f with SMTP id bm17-20020a0568081a9100b003c1f46ce71fmr3586316oib.46.1709710827080; Tue, 05 Mar 2024 23:40:27 -0800 (PST) Received: from google.com (12.196.204.35.bc.googleusercontent.com. [35.204.196.12]) by smtp.gmail.com with ESMTPSA id n30-20020a0568080a1e00b003c1973dbca6sm1317273oij.2.2024.03.05.23.40.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Mar 2024 23:40:26 -0800 (PST) Date: Wed, 6 Mar 2024 07:40:21 +0000 From: Matt Bobrowski To: bpf@vger.kernel.org Cc: ast@kernel.org, andrii@kernel.org, kpsingh@google.com, jannh@google.com, jolsa@kernel.org, daniel@iogearbox.net, brauner@kernel.org, torvalds@linux-foundation.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v2 bpf-next 7/9] bpf/selftests: add selftests for root/pwd path based BPF kfuncs Message-ID: <1c7cdcb02209b99b92b1b006bad452c11d7ddd53.1709675979.git.mattbobrowski@google.com> References: Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Add a new path_kfunc test suite that is responsible for verifiying the operability of the newly added root/pwd path based BPF kfuncs. This test suite covers the following BPF kfuncs: struct path *bpf_get_task_fs_root(struct task_struct *task); struct path *bpf_get_task_fs_pwd(struct task_struct *task); void bpf_put_path(struct path *path); Signed-off-by: Matt Bobrowski --- .../selftests/bpf/prog_tests/path_kfunc.c | 48 ++++++++ .../selftests/bpf/progs/path_kfunc_common.h | 20 +++ .../selftests/bpf/progs/path_kfunc_failure.c | 114 ++++++++++++++++++ .../selftests/bpf/progs/path_kfunc_success.c | 30 +++++ 4 files changed, 212 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/path_kfunc.c create mode 100644 tools/testing/selftests/bpf/progs/path_kfunc_common.h create mode 100644 tools/testing/selftests/bpf/progs/path_kfunc_failure.c create mode 100644 tools/testing/selftests/bpf/progs/path_kfunc_success.c diff --git a/tools/testing/selftests/bpf/prog_tests/path_kfunc.c b/tools/testing/selftests/bpf/prog_tests/path_kfunc.c new file mode 100644 index 000000000000..9a8701a7999c --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/path_kfunc.c @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2024 Google LLC. */ + +#define _GNU_SOURCE +#include + +#include "path_kfunc_failure.skel.h" +#include "path_kfunc_success.skel.h" + +static void run_test(const char *prog_name) +{ + struct bpf_link *link; + struct bpf_program *prog; + struct path_kfunc_success *skel; + + skel = path_kfunc_success__open_and_load(); + if (!ASSERT_OK_PTR(skel, "path_kfunc_success__open_and_load")) + return; + + link = NULL; + prog = bpf_object__find_program_by_name(skel->obj, prog_name); + if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name")) + goto cleanup; + + link = bpf_program__attach(prog); + ASSERT_OK_PTR(link, "bpf_program__attach"); +cleanup: + bpf_link__destroy(link); + path_kfunc_success__destroy(skel); +} + +static const char * const success_tests[] = { + "get_task_fs_root_and_put_from_current", + "get_task_fs_pwd_and_put_from_current", +}; + +void test_path_kfunc(void) +{ + int i = 0; + + for (; i < ARRAY_SIZE(success_tests); i++) { + if (!test__start_subtest(success_tests[i])) + continue; + run_test(success_tests[i]); + } + + RUN_TESTS(path_kfunc_failure); +} diff --git a/tools/testing/selftests/bpf/progs/path_kfunc_common.h b/tools/testing/selftests/bpf/progs/path_kfunc_common.h new file mode 100644 index 000000000000..837dc03c136d --- /dev/null +++ b/tools/testing/selftests/bpf/progs/path_kfunc_common.h @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2024 Google LLC. */ + +#ifndef _PATH_KFUNC_COMMON_H +#define _PATH_KFUNC_COMMON_H + +#include +#include +#include +#include + +#include "bpf_misc.h" + +char _license[] SEC("license") = "GPL"; + +struct path *bpf_get_task_fs_root(struct task_struct *task) __ksym; +struct path *bpf_get_task_fs_pwd(struct task_struct *task) __ksym; +void bpf_put_path(struct path *path) __ksym; + +#endif /* _PATH_KFUNC_COMMON_H */ diff --git a/tools/testing/selftests/bpf/progs/path_kfunc_failure.c b/tools/testing/selftests/bpf/progs/path_kfunc_failure.c new file mode 100644 index 000000000000..a28797e245e3 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/path_kfunc_failure.c @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2024 Google LLC. */ + +#include "path_kfunc_common.h" + +SEC("lsm.s/file_open") +__failure __msg("Possibly NULL pointer passed to trusted arg0") +int BPF_PROG(get_task_fs_root_kfunc_null) +{ + struct path *acquired; + + /* Can't pass a NULL pointer to bpf_get_task_fs_root(). */ + acquired = bpf_get_task_fs_root(NULL); + if (!acquired) + return 0; + bpf_put_path(acquired); + + return 0; +} + +SEC("lsm.s/file_open") +__failure __msg("Possibly NULL pointer passed to trusted arg0") +int BPF_PROG(get_task_fs_pwd_kfunc_null) +{ + struct path *acquired; + + /* Can't pass a NULL pointer to bpf_get_task_fs_pwd(). */ + acquired = bpf_get_task_fs_pwd(NULL); + if (!acquired) + return 0; + bpf_put_path(acquired); + + return 0; +} + +SEC("lsm.s/task_alloc") +__failure __msg("R1 must be referenced or trusted") +int BPF_PROG(get_task_fs_root_kfunc_untrusted, struct task_struct *task) +{ + struct path *acquired; + struct task_struct *parent; + + /* Walking the struct task_struct will yield an untrusted pointer. */ + parent = task->parent; + if (!parent) + return 0; + + acquired = bpf_get_task_fs_root(parent); + if (!acquired) + return 0; + bpf_put_path(acquired); + + return 0; +} + +SEC("lsm.s/task_alloc") +__failure __msg("R1 must be referenced or trusted") +int BPF_PROG(get_task_fs_pwd_kfunc_untrusted, struct task_struct *task) +{ + struct path *acquired; + struct task_struct *parent; + + /* Walking the struct task_struct will yield an untrusted pointer. */ + parent = task->parent; + if (!parent) + return 0; + + acquired = bpf_get_task_fs_pwd(parent); + if (!acquired) + return 0; + bpf_put_path(acquired); + + return 0; +} + +SEC("lsm.s/file_open") +__failure __msg("Unreleased reference") +int BPF_PROG(get_task_fs_root_kfunc_unreleased) +{ + struct path *acquired; + + acquired = bpf_get_task_fs_root(bpf_get_current_task_btf()); + if (!acquired) + return 0; + __sink(acquired); + + /* Acquired but never released. */ + return 0; +} + +SEC("lsm.s/file_open") +__failure __msg("Unreleased reference") +int BPF_PROG(get_task_fs_pwd_kfunc_unreleased) +{ + struct path *acquired; + + acquired = bpf_get_task_fs_pwd(bpf_get_current_task_btf()); + if (!acquired) + return 0; + __sink(acquired); + + /* Acquired but never released. */ + return 0; +} + +SEC("lsm.s/inode_getattr") +__failure __msg("release kernel function bpf_put_path expects refcounted PTR_TO_BTF_ID") +int BPF_PROG(put_path_kfunc_unacquired, struct path *path) +{ + /* Can't release an unacquired pointer. */ + bpf_put_path(path); + + return 0; +} diff --git a/tools/testing/selftests/bpf/progs/path_kfunc_success.c b/tools/testing/selftests/bpf/progs/path_kfunc_success.c new file mode 100644 index 000000000000..8fc8e3c51405 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/path_kfunc_success.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2024 Google LLC. */ + +#include "path_kfunc_common.h" + +SEC("lsm.s/file_open") +int BPF_PROG(get_task_fs_root_and_put_from_current) +{ + struct path *acquired; + + acquired = bpf_get_task_fs_root(bpf_get_current_task_btf()); + if (!acquired) + return 0; + bpf_put_path(acquired); + + return 0; +} + +SEC("lsm.s/file_open") +int BPF_PROG(get_task_fs_pwd_and_put_from_current) +{ + struct path *acquired; + + acquired = bpf_get_task_fs_pwd(bpf_get_current_task_btf()); + if (!acquired) + return 0; + bpf_put_path(acquired); + + return 0; +} From patchwork Wed Mar 6 07:40:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Bobrowski X-Patchwork-Id: 13583453 Received: from mail-ot1-f45.google.com (mail-ot1-f45.google.com [209.85.210.45]) (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 B1D4A5BAF0 for ; Wed, 6 Mar 2024 07:40:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709710837; cv=none; b=fQZd2x0I+XsilIzGRmxtlESVwf9veowIpk/qFgEmxnN83aB+QS69ZVlwBWhRtHNJIJYxB23k13zup32qOhq51KPeXA06FQ+TZ9O0PnOEIQyfvpSmvzsKi1hqlLUISybjlwFBpuV42Mh5etGU2wWJD4CQICGMUBbYtaA2I88OpyQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709710837; c=relaxed/simple; bh=ddtC+uKArv7UdiqQfjewNtYRkzLuCLfgVvW+TGa7IBM=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=pcMSe+u418kOT2Tdroyni9cV9503L2YqdfkTXav1vjXQAK3vtaxn2oMWYhljR/N0yyQPsVtz7VeWaWC9OaWneqgHbSo7LY/RopNn2loplwiaGHVUK/lVLIx+zX+NYJtp8+OKPv3XIU5dHOFWUhfxItLu7rJ1XcObGoh3JRNIfa4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=xyeBSyxq; arc=none smtp.client-ip=209.85.210.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="xyeBSyxq" Received: by mail-ot1-f45.google.com with SMTP id 46e09a7af769-6e4efdf31c9so216062a34.1 for ; Tue, 05 Mar 2024 23:40:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709710835; x=1710315635; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=dNwfyies9fK4BVkN1qpRBwPdhTsOnQT/qyn6MGfjNFo=; b=xyeBSyxqnFnYSu96xjr+jh7LR1kANzKZclTL/89+Mq9eiLWbe+6VR1ub4GupusB+eW Oa1IT7A1R5nckYfRqq6XFdNfdDAS8lPjXCGzbHgkqPz0ZvBbbgSM1Opwr3JF/aJ9Xf3z PIcLZnbiXQvVdqhSo3ScBWhwH0udkKt0gcnFpu/ihs5Iuyi6EWJOsmKNrqZ/Y5z1sYGr MUcOs6lJUsSz0rTwTK95G43LJHtvkW2nmiwCMVNpevCmL81fC684BNnHcpqe4vreRjgJ YpEnruTud1zsYtskWYceqXelRcUBmxhiJHtlX7Zcc5ULsQecp059JiPxDz2ywUpPSEDv IyVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709710835; x=1710315635; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=dNwfyies9fK4BVkN1qpRBwPdhTsOnQT/qyn6MGfjNFo=; b=BSqNbUca96VKa4aT2+lRQoax1UZ01N66VHT7QWwnUIh+IyJ3JTowvawzmpHRmDqTvI IegzLRgp/Ojmo6N0otTXLEXIjNjCFbIhHxZ/wdLcqe8CUY8nn+pkesWgqQW7nWLeUmOL pkiQatt8j0pKCN/I2/8tHKz3JOD8zrSOp9ptCj74Krf99qvQ2tQFrReW2D25BaFg8av+ JALkv+lOl2xGFBKmbv3Pp2P8wtvdFXTAwSSAv3/TIxFBt+7ugiOjA1kHRtCKfxW5WZXZ w8SmKncpRS9WwKeUJE3pfZM2RY1pNd1fbV0YJm1wiIX+UNvGBja04b65XsG2iCnMt1s5 egFw== X-Forwarded-Encrypted: i=1; AJvYcCXttobMemeS9Vd9UuIs+SfxJO4P64yJvtQwi15dRx5MYxSuErHBKuhP0CSQyhbbxLqPDzrX0GGAzrQ6ILqAs9NbIA3BMPpcJo/xZ1XYxQ== X-Gm-Message-State: AOJu0YxJp72BLNkKMSYjZ4Y/9Wsl3isPUrnPop89yCJtCG3beTFKmYNQ ImyHRKKrkanOx8nFs2GHjqll6o6GaWXHXnuf+90hTuaZoGBkMb8GHW2JTJGhdQ== X-Google-Smtp-Source: AGHT+IHSF6r7pWyah8Vo6aI+WZxk3Tmzs3eaCRP+IhPTHK+o4locRRAwnyg28TbdpJHarx1oGzZZ5Q== X-Received: by 2002:a9d:6d94:0:b0:6e4:ae29:d77f with SMTP id x20-20020a9d6d94000000b006e4ae29d77fmr1908819otp.6.1709710834670; Tue, 05 Mar 2024 23:40:34 -0800 (PST) Received: from google.com (12.196.204.35.bc.googleusercontent.com. [35.204.196.12]) by smtp.gmail.com with ESMTPSA id z9-20020a9d7a49000000b006e4b6013ab2sm2183069otm.15.2024.03.05.23.40.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Mar 2024 23:40:34 -0800 (PST) Date: Wed, 6 Mar 2024 07:40:27 +0000 From: Matt Bobrowski To: bpf@vger.kernel.org Cc: ast@kernel.org, andrii@kernel.org, kpsingh@google.com, jannh@google.com, jolsa@kernel.org, daniel@iogearbox.net, brauner@kernel.org, torvalds@linux-foundation.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v2 bpf-next 8/9] bpf: add trusted d_path() based BPF kfunc bpf_path_d_path() Message-ID: References: Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: The legacy bpf_d_path() helper did not operate on trusted pointer arguments, therefore under certain circumstances was susceptible to memory corruption issues [0]. This new d_path() based BPF kfunc bpf_path_d_path() makes use of the trusted pointer argument constraint KF_TRUSTED_ARGS. Making use of the KF_TRUSTED_ARGS constraint will ensure that d_path() may only be called when and underlying BPF program holds a stable handle for a given path. For now, we restrict bpf_path_d_path() to BPF LSM program types, but this may be relaxed in the future. Notably, we are consciously not retroactively enforcing the KF_TRUSTED_ARGS constraint onto the legacy bpf_d_path() helper, as that would lead to wide-scale BPF program breakage. [0] https://lore.kernel.org/bpf/CAG48ez0ppjcT=QxU-jtCUfb5xQb3mLr=5FcwddF_VKfEBPs_Dg@mail.gmail.com/ Signed-off-by: Matt Bobrowski --- kernel/trace/bpf_trace.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 84fd87ead20c..4989639153cd 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -1647,6 +1647,37 @@ __bpf_kfunc void bpf_put_path(struct path *path) path_put(path); } +/** + * bpf_path_d_path - resolve the pathname for a given path + * @path: path to resolve the pathname for + * @buf: buffer to return the resolved path value in + * @buflen: length of the supplied buffer + * + * Resolve the pathname for the supplied trusted *path* in *buf*. This kfunc is + * the trusted/safer variant of the legacy bpf_d_path() helper and should be + * used in place of bpf_d_path() whenever possible. + * + * Return: A strictly positive integer corresponding to the length of the string + * representing the resolved pathname, including the NUL termination + * character. On error, a negative integer is returned. + */ +__bpf_kfunc int bpf_path_d_path(struct path *path, char *buf, int buflen) +{ + int len; + char *ret; + + if (buflen <= 0) + return -EINVAL; + + ret = d_path(path, buf, buflen); + if (IS_ERR(ret)) + return PTR_ERR(ret); + + len = buf + buflen - ret; + memmove(buf, ret, len); + return len; +} + __bpf_kfunc_end_defs(); BTF_KFUNCS_START(lsm_kfunc_set_ids) @@ -1663,6 +1694,7 @@ BTF_ID_FLAGS(func, bpf_get_task_fs_root, BTF_ID_FLAGS(func, bpf_get_task_fs_pwd, KF_ACQUIRE | KF_TRUSTED_ARGS | KF_RET_NULL) BTF_ID_FLAGS(func, bpf_put_path, KF_RELEASE | KF_SLEEPABLE) +BTF_ID_FLAGS(func, bpf_path_d_path, KF_TRUSTED_ARGS | KF_SLEEPABLE) BTF_KFUNCS_END(lsm_kfunc_set_ids) static int bpf_lsm_kfunc_filter(const struct bpf_prog *prog, u32 kfunc_id) From patchwork Wed Mar 6 07:40:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Bobrowski X-Patchwork-Id: 13583452 Received: from mail-oo1-f45.google.com (mail-oo1-f45.google.com [209.85.161.45]) (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 DCCBC5BAF0 for ; Wed, 6 Mar 2024 07:40:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709710834; cv=none; b=JUg8txfE9r2cS/CAw+OhdN1IBGDDj+LKXBzE3ofL9c1a3zV3bn2OWnwQmibg1LJElSD1X9Mv12cLBeVjjmV7ul4f6i4G4XUjITawsg2kYdKc/c9qQFHOraUFYFQCDKNIycJAGlyMi4BJIB4vzuS4xZ0OSJnb90PqO4f/U80C73k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709710834; c=relaxed/simple; bh=Pj+o0wUiDrAZvuk8PrK4QBMqMvi5OoqumxrZvD4Kl9M=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=uQ10rNmT2ycm3h5IYOvBWtVL/b+ordLyHJ5B3YbooJJkc24ykoradz8k0AHljeSHRYOh/8ly7QXL5siKST5T35u1u5IG+BORG9NVQHScPKXg2oKO0x4Voa77xLIUlWXUpl027E7ZapTZSjfVyg+KlrMgzal1jXJplJGhB7y5RD0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=e5Z7Hivw; arc=none smtp.client-ip=209.85.161.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="e5Z7Hivw" Received: by mail-oo1-f45.google.com with SMTP id 006d021491bc7-5a197570d45so20704eaf.0 for ; Tue, 05 Mar 2024 23:40:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1709710832; x=1710315632; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=fH1k+SV/f0vvM8HD0mhAGfqzECUsbN8zTP2gm81qF5A=; b=e5Z7Hivw0M/ShryHD9fAt+sc97/QEoSKlPIAmS83+Z8nVaFogO8/38ipy41+1hNjrm SvfuHVP6vd8LhyoRU+H/wxRmcQFWyCwgwAgiS1U7bwHL5yXQE+wat15NUnZF4+dUPOW1 cEwO0G2dxjHPxo06y9lKTXLFnIrETIwflqNrGhzfqq9glp7pISZaAnEF+MWCqdDxUUnN eSuUaTGD880aF5Xc4QVX7rkrNle7FSm5em3OWV1h+0QSgCGTIhL3BMxppFb5LBkJ5Y0E BhKHV2cAknYdotlGsaFR38QXCRNcuUdGtbNyxlaz8XFSXuZF8IL3kWyvPlsCHbB2heM4 G8MA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709710832; x=1710315632; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=fH1k+SV/f0vvM8HD0mhAGfqzECUsbN8zTP2gm81qF5A=; b=WJYlRpsMCARrF6g+/2AMQzCV73r6/nZ77ghbiIMtOmCKOEseEzE8cHuljGypzSWPMq irgz77TNJfG+NG/SH0oesA6D2soyPTfgB9cqwD/VQU3Yi2k+UOrxH2NHSirIFNCURcLy m6gzv2ivQLbViZlfY7PTgkT4bBVGV0NlvZOjw3Js2JhYtrILZf12VbiGEgweadnQyaCM lnjZEMeSHxcHDEcJQ9X9AKzveExm3fiWX90XYBXSeh9XdJmjJ+nvP2tgSSl8v35rlT25 qlmVcTAha8tKmPTEbDuLSec96L80vtv9ZHBJOxoFm9BH3oH/WVBTqGzflXZhZDWfjDpI rUSQ== X-Forwarded-Encrypted: i=1; AJvYcCUEeKbbGzGw8B/RTz0ycfk3L9oZ01uDNqKDY1q8NuQK20V0+UwlCsqfgFZ6Y29A2Z9nToSvY4w5RTZunOBzG8UZbmvuTa+7Ky7qbmYD+A== X-Gm-Message-State: AOJu0YzHPWAh9x4ksXdZTsXlvtaPJ8n3MZKhP9ADqJsP2llxY4j19kap Bl1UzN8wol+Cam+RSyHoEQJfpmSSc3U6kOP+92Et/eHo8bfaZwbESBCdWix6fA== X-Google-Smtp-Source: AGHT+IFslANPT783zPiQEmQCglAKToxQEC4ZXx0rG+iPYroD1+COb5i4MmK62W2unVaTgUg6mCsULw== X-Received: by 2002:a05:6870:471f:b0:21f:a11a:e251 with SMTP id b31-20020a056870471f00b0021fa11ae251mr4336889oaq.5.1709710831768; Tue, 05 Mar 2024 23:40:31 -0800 (PST) Received: from google.com (12.196.204.35.bc.googleusercontent.com. [35.204.196.12]) by smtp.gmail.com with ESMTPSA id gb8-20020a056870670800b00220db41819bsm2152952oab.2.2024.03.05.23.40.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Mar 2024 23:40:31 -0800 (PST) Date: Wed, 6 Mar 2024 07:40:25 +0000 From: Matt Bobrowski To: bpf@vger.kernel.org Cc: ast@kernel.org, andrii@kernel.org, kpsingh@google.com, jannh@google.com, jolsa@kernel.org, daniel@iogearbox.net, brauner@kernel.org, torvalds@linux-foundation.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v2 bpf-next 9/9] bpf/selftests: adapt selftests test_d_path for BPF kfunc bpf_path_d_path() Message-ID: <9cf1f10d6f6f16095b8cea1d4291a54469542090.1709675979.git.mattbobrowski@google.com> References: Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Adapt the existing test_d_path test suite to cover the operability of the newly introduced trusted d_path() based BPF kfunc bpf_path_d_path(). This new BPF kfunc is functionally identical with regards to its path reconstruction based capabilities to that of its predecessor bpf_d_path(), so it makes sense to recycle the existing test_d_path suite. Signed-off-by: Matt Bobrowski --- .../testing/selftests/bpf/prog_tests/d_path.c | 80 +++++++++++++++++++ .../selftests/bpf/progs/d_path_common.h | 35 ++++++++ .../bpf/progs/d_path_kfunc_failure.c | 66 +++++++++++++++ .../bpf/progs/d_path_kfunc_success.c | 25 ++++++ .../testing/selftests/bpf/progs/test_d_path.c | 20 +---- .../bpf/progs/test_d_path_check_rdonly_mem.c | 8 +- .../bpf/progs/test_d_path_check_types.c | 8 +- 7 files changed, 209 insertions(+), 33 deletions(-) create mode 100644 tools/testing/selftests/bpf/progs/d_path_common.h create mode 100644 tools/testing/selftests/bpf/progs/d_path_kfunc_failure.c create mode 100644 tools/testing/selftests/bpf/progs/d_path_kfunc_success.c diff --git a/tools/testing/selftests/bpf/prog_tests/d_path.c b/tools/testing/selftests/bpf/prog_tests/d_path.c index ccc768592e66..cc5c886fe59b 100644 --- a/tools/testing/selftests/bpf/prog_tests/d_path.c +++ b/tools/testing/selftests/bpf/prog_tests/d_path.c @@ -11,6 +11,8 @@ #include "test_d_path.skel.h" #include "test_d_path_check_rdonly_mem.skel.h" #include "test_d_path_check_types.skel.h" +#include "d_path_kfunc_failure.skel.h" +#include "d_path_kfunc_success.skel.h" /* sys_close_range is not around for long time, so let's * make sure we can call it on systems with older glibc @@ -124,6 +126,13 @@ static void test_d_path_basic(void) struct test_d_path *skel; int err; + /* + * Carrying global state across test function invocations is super + * gross, but it was late and I was tired and I just wanted to get the + * darn test working. Zero'ing this out was a simple no brainer. + */ + memset(&src, 0, sizeof(src)); + skel = test_d_path__open_and_load(); if (CHECK(!skel, "setup", "d_path skeleton failed\n")) goto cleanup; @@ -195,8 +204,72 @@ static void test_d_path_check_types(void) test_d_path_check_types__destroy(skel); } +static struct bpf_path_d_path_t { + const char *prog_name; +} success_test_cases[] = { + { + .prog_name = "path_d_path_from_path_argument", + }, +}; + +static void test_bpf_path_d_path(struct bpf_path_d_path_t *t) +{ + int i, ret; + struct bpf_link *link; + struct bpf_program *prog; + struct d_path_kfunc_success__bss *bss; + struct d_path_kfunc_success *skel; + + /* + * Carrying global state across function invocations is super gross, but + * it was late and I was tired and I just wanted to get the darn test + * working. Zero'ing this out was a simple no brainer. + */ + memset(&src, 0, sizeof(src)); + + skel = d_path_kfunc_success__open(); + if (!ASSERT_OK_PTR(skel, "d_path_kfunc_success__open")) + return; + + bss = skel->bss; + bss->my_pid = getpid(); + + ret = d_path_kfunc_success__load(skel); + if (CHECK(ret, "setup", "d_path_kfunc_success__load\n")) + goto cleanup; + + link = NULL; + prog = bpf_object__find_program_by_name(skel->obj, t->prog_name); + if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name")) + goto cleanup; + + link = bpf_program__attach(prog); + if (!ASSERT_OK_PTR(link, "bpf_program__attach")) + goto cleanup; + + ret = trigger_fstat_events(bss->my_pid); + if (ret < 0) + goto cleanup; + + for (i = 0; i < MAX_FILES; i++) { + CHECK(strncmp(src.paths[i], bss->paths_stat[i], MAX_PATH_LEN), + "check", "failed to get stat path[%d]: %s vs %s\n", i, + src.paths[i], bss->paths_stat[i]); + CHECK(bss->rets_stat[i] != strlen(bss->paths_stat[i]) + 1, + "check", + "failed to match stat return [%d]: %d vs %zd [%s]\n", i, + bss->rets_stat[i], strlen(bss->paths_stat[i]) + 1, + bss->paths_stat[i]); + } +cleanup: + bpf_link__destroy(link); + d_path_kfunc_success__destroy(skel); +} + void test_d_path(void) { + int i = 0; + if (test__start_subtest("basic")) test_d_path_basic(); @@ -205,4 +278,11 @@ void test_d_path(void) if (test__start_subtest("check_alloc_mem")) test_d_path_check_types(); + + for (; i < ARRAY_SIZE(success_test_cases); i++) { + if (!test__start_subtest(success_test_cases[i].prog_name)) + continue; + test_bpf_path_d_path(&success_test_cases[i]); + } + RUN_TESTS(d_path_kfunc_failure); } diff --git a/tools/testing/selftests/bpf/progs/d_path_common.h b/tools/testing/selftests/bpf/progs/d_path_common.h new file mode 100644 index 000000000000..276331b5ff9f --- /dev/null +++ b/tools/testing/selftests/bpf/progs/d_path_common.h @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2024 Google LLC. */ + +#ifndef _D_PATH_COMMON_H +#define _D_PATH_COMMON_H + +#include +#include +#include + +#include "bpf_misc.h" + +#define MAX_PATH_LEN 128 +#define MAX_FILES 7 + +extern const int bpf_prog_active __ksym; +int bpf_path_d_path(struct path *path, char *buf, int buflen) __ksym; + +pid_t my_pid = 0; + +__u32 cnt_stat = 0; +__u32 cnt_close = 0; + +char paths_stat[MAX_FILES][MAX_PATH_LEN] = {}; +char paths_close[MAX_FILES][MAX_PATH_LEN] = {}; + +int rets_stat[MAX_FILES] = {}; +int rets_close[MAX_FILES] = {}; + +int called_stat = 0; +int called_close = 0; + +char _license[] SEC("license") = "GPL"; + +#endif /* _D_PATH_COMMON_H */ diff --git a/tools/testing/selftests/bpf/progs/d_path_kfunc_failure.c b/tools/testing/selftests/bpf/progs/d_path_kfunc_failure.c new file mode 100644 index 000000000000..9da5f0d395c9 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/d_path_kfunc_failure.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2024 Google LLC. */ + +#include "d_path_common.h" + +char buf[MAX_PATH_LEN] = {}; + +SEC("lsm.s/file_open") +__failure __msg("Possibly NULL pointer passed to trusted arg0") +int BPF_PROG(path_d_path_kfunc_null) +{ + /* Can't pass NULL value to bpf_path_d_path() kfunc. */ + bpf_path_d_path(NULL, buf, sizeof(buf)); + return 0; +} + +SEC("fentry/vfs_open") +__failure __msg("calling kernel function bpf_path_d_path is not allowed") +int BPF_PROG(path_d_path_kfunc_non_lsm, struct path *path, struct file *f) +{ + /* Calling bpf_path_d_path() kfunc from a non-sleepable and non-LSM + * based program isn't permitted. + */ + bpf_path_d_path(path, buf, sizeof(buf)); + return 0; +} + +SEC("lsm.s/task_alloc") +__failure __msg("R1 must be referenced or trusted") +int BPF_PROG(path_d_path_kfunc_untrusted_from_argument, struct task_struct *task) +{ + struct path *root; + + /* Walking a trusted argument yields an untrusted pointer. */ + root = &task->fs->root; + bpf_path_d_path(root, buf, sizeof(buf)); + return 0; +} + +SEC("lsm.s/file_open") +__failure __msg("R1 must be referenced or trusted") +int BPF_PROG(path_d_path_kfunc_untrusted_from_current) +{ + struct path *pwd; + struct task_struct *current; + + current = bpf_get_current_task_btf(); + /* Walking a trusted pointer returned from bpf_get_current_task_btf() + * yields and untrusted pointer. */ + pwd = ¤t->fs->pwd; + bpf_path_d_path(pwd, buf, sizeof(buf)); + return 0; +} + +SEC("lsm.s/file_open") +__failure __msg("R1 must have zero offset when passed to release func or trusted arg to kfunc") +int BPF_PROG(path_d_path_kfunc_trusted_variable_offset, struct file *file) +{ + /* Passing variable offsets from a trusted aren't supported just yet, + * despite being perfectly OK i.e. file->f_path. Once the BPF verifier + * has been updated to handle this case, this test can be removed. For + * now, ensure we reject the BPF program upon load if this is attempted. + */ + bpf_path_d_path(&file->f_path, buf, sizeof(buf)); + return 0; +} diff --git a/tools/testing/selftests/bpf/progs/d_path_kfunc_success.c b/tools/testing/selftests/bpf/progs/d_path_kfunc_success.c new file mode 100644 index 000000000000..72d1a64618d1 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/d_path_kfunc_success.c @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2024 Google LLC. */ + +#include "d_path_common.h" + +SEC("lsm.s/inode_getattr") +int BPF_PROG(path_d_path_from_path_argument, struct path *path) +{ + u32 cnt = cnt_stat; + int ret; + pid_t pid; + + pid = bpf_get_current_pid_tgid() >> 32; + if (pid != my_pid) + return 0; + + if (cnt >= MAX_FILES) + return 0; + + ret = bpf_path_d_path(path, paths_stat[cnt], MAX_PATH_LEN); + rets_stat[cnt] = ret; + cnt_stat++; + + return 0; +} diff --git a/tools/testing/selftests/bpf/progs/test_d_path.c b/tools/testing/selftests/bpf/progs/test_d_path.c index 84e1f883f97b..5bdfa4abb5f6 100644 --- a/tools/testing/selftests/bpf/progs/test_d_path.c +++ b/tools/testing/selftests/bpf/progs/test_d_path.c @@ -1,22 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 -#include "vmlinux.h" -#include -#include - -#define MAX_PATH_LEN 128 -#define MAX_FILES 7 - -pid_t my_pid = 0; -__u32 cnt_stat = 0; -__u32 cnt_close = 0; -char paths_stat[MAX_FILES][MAX_PATH_LEN] = {}; -char paths_close[MAX_FILES][MAX_PATH_LEN] = {}; -int rets_stat[MAX_FILES] = {}; -int rets_close[MAX_FILES] = {}; - -int called_stat = 0; -int called_close = 0; +#include "d_path_common.h" SEC("fentry/security_inode_getattr") int BPF_PROG(prog_stat, struct path *path, struct kstat *stat, @@ -61,5 +45,3 @@ int BPF_PROG(prog_close, struct file *file, void *id) cnt_close++; return 0; } - -char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/progs/test_d_path_check_rdonly_mem.c b/tools/testing/selftests/bpf/progs/test_d_path_check_rdonly_mem.c index 27c27cff6a3a..6094a58321a4 100644 --- a/tools/testing/selftests/bpf/progs/test_d_path_check_rdonly_mem.c +++ b/tools/testing/selftests/bpf/progs/test_d_path_check_rdonly_mem.c @@ -1,11 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2022 Google */ -#include "vmlinux.h" -#include -#include - -extern const int bpf_prog_active __ksym; +#include "d_path_common.h" SEC("fentry/security_inode_getattr") int BPF_PROG(d_path_check_rdonly_mem, struct path *path, struct kstat *stat, @@ -24,5 +20,3 @@ int BPF_PROG(d_path_check_rdonly_mem, struct path *path, struct kstat *stat, } return 0; } - -char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/progs/test_d_path_check_types.c b/tools/testing/selftests/bpf/progs/test_d_path_check_types.c index 7e02b7361307..6d4204136489 100644 --- a/tools/testing/selftests/bpf/progs/test_d_path_check_types.c +++ b/tools/testing/selftests/bpf/progs/test_d_path_check_types.c @@ -1,10 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 -#include "vmlinux.h" -#include -#include - -extern const int bpf_prog_active __ksym; +#include "d_path_common.h" struct { __uint(type, BPF_MAP_TYPE_RINGBUF); @@ -28,5 +24,3 @@ int BPF_PROG(d_path_check_rdonly_mem, struct path *path, struct kstat *stat, } return 0; } - -char _license[] SEC("license") = "GPL";