From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-yw1-f176.google.com (mail-yw1-f176.google.com [209.85.128.176]) (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 6F9A8195B1A for ; Tue, 6 Oct 2026 00:20:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.176 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791246053; cv=none; b=iLys2dmg0nZTvxKRpveV/v0zutqVwyWqW1clzNNnh9TH29SBBzQk9q6FWgF3CimLAm5XVEgfzN85kM2W8mizni4C6Xs3dnlfye5vVabY4kz1Oj+enOp7Xx7RwyKrzJ7SaKTo28FJtIScHCGDRgNcSuWNaopvFpwPwcx7nTP0d9o= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791246053; c=relaxed/simple; bh=g+n1czrcMHPLMQpcpTgeEza8tWqqWT5DIADJOEgauhg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qV6NfekpaqINQEcBuyvmo3e5+0OeafKJssgAwuSkPfGHBQHJP99oNdSKYreNckBx10LlOujH+Sx48hxuofHmUOLOFt9WCpLlzIjkCZsn5Nrja+dJUrNfaTwlyVFgmfu8FGlm3I6VhD6DkvAotVZ7KsWFeQ2zhBgbaFy1zJJwk58= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=D4T56T7N; arc=none smtp.client-ip=209.85.128.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="D4T56T7N" Received: by mail-yw1-f176.google.com with SMTP id 00721157ae682-8ac8a2ac52bso3549437b3.0 for ; Mon, 05 Oct 2026 17:20:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1791246049; x=1791850849; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=WcPAYnp6FRhiKAh9ydZFYz6XVPrSxVL1Ud94wpG3oX4=; b=D4T56T7N+JYXwvkTfK1CmI685PRoJSJ11hOKflHGb7K/jjIHUtjAf1KshSV2zZdSgL ZkApGaPqnAPmBLhe1bN6Xv+XhSYFBudrfMk9U5EL+zjjGSU8prqfwIAV+NpgJlxEKveJ sl5YzrYCQly66AVuMBIbR7QN26da1ZRFymZQgAfiYOCnDNp3IhVgCqYWCMoBDQnszqSf OgjZNJhoFmhr3iktHrgZDACoS09hVHcA8jbdSByG5UfmDCfjTfFwyjwUyAkbQ4R6d7Vn 4ebGNTSsTZnFht9mUXggxNIg/DBSquYm7crMsDSv4GnbGMKLSQZdAYTgmvK0gjJ707ZA fG3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1791246049; x=1791850849; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=WcPAYnp6FRhiKAh9ydZFYz6XVPrSxVL1Ud94wpG3oX4=; b=E1xv+OhNMCNcGcsiJCySOM5MRvAuDzVx6MvNSvvsCxPZ87qjdHwYIRQZ5IHmwxkiQR rqcrMSxjhsXbcoJegJ2e1S8E2kMzuHshK7H3pcUQ+7uv956RBpm5bYhkZdXPdyGqIitn OKhb6rG3M7fsruB1sfE/ibK1CByzH+6E8/Yubp8VV+x8sLe7f96bUw8RHg6iyW9Q5IBF llGj6Cc6QtHJOExgb0fAn0pKrVm5RMOKwi7sz4RqPxqjQOWyrE9/c8b5Ka8mmus43d0O TD5U/qmy/T0UwQZqIWpf4U9g2qx0a9Ok+4r/Qa+V/cvzxzWT0XTyuvym/pRqYqXepF3p L4eQ== X-Forwarded-Encrypted: i=1; AKwUvBzl9GVlxB+LpEyuWIKxfezRUmSbXjkNvuQRC79Qpp9dIj+MyB+7MaOtL/Ne2BQpXvYAGdk=@vger.kernel.org X-Gm-Message-State: AFq9FYLRYlKm7nweUIBmfngcQJDTy+pCfJMEMm/AvDWbkSxNzIuhx8cf ZVr9PI0EZQFhBF+nF3Db4P6O1syv/R3ElpVdeBm8hnqo1j1pxpUdMuC6 X-Gm-Gg: AYBFou1tpIhp10GMG+Hdp+m70TK0zgsYagkEzqA3YgfUetLgCwuTwMzCMGq558qtV/5 q/UDX7L2owDIMa1dM+B2FJkSODch7XL3yD7Q4SKk+Ij+2jaTsTgPveCrxbS28SS6XHXR0oSWvZq tY85mGsToevGq6Ot4bu4mhYAMK5m7DArHYhD16VQSjnHvsiW0nv3cF1I2BzkfxPFypOFU7JRMhC qXQuynHSCs0M6Uu/pR/anaS7xPifppJtjxl0FcEm0ZYwmvxdER+v7tkGXhn+coqvDqU8OdhRGsy UKNZJ16S3baaimtPz/8gJNxGTJADjM6REXQ6MmXbrsGokPnpn2xgjke9fDlg5Qx/4y2BJfLU0j5 lFxyVpYIDjTroRtz27n1pDfJW7UrvYYvma+TDVShPngtyuwQXJPgpYBNHVSQLEv/AJKr5J1Ijqg UfDVB7BkTREwzU3v13RaXTrG6Mkrn5OC1ZeS9O5ZJHCGgGwzTSqmVzfrnk9qnKM9PmHUlVSEYrJ lA= X-Received: by 2002:a05:690c:e64b:b0:8ae:ae7a:2763 with SMTP id 00721157ae682-8af7204ed31mr3635217b3.13.1791246049148; Mon, 05 Oct 2026 17:20:49 -0700 (PDT) Received: from zenbox ([2600:1700:18fb:6011:6dc9:4ffd:1851:60b1]) by smtp.gmail.com with ESMTPSA id 00721157ae682-8ae33be0e58sm46636277b3.43.2026.10.05.17.20.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Oct 2026 17:20:48 -0700 (PDT) From: Justin Suess To: Christian Brauner , Alexander Viro , Jan Kara , NeilBrown , =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Song Liu Cc: linux-fsdevel@vger.kernel.org, bpf@vger.kernel.org, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org, =?UTF-8?q?G=C3=BCnther=20Noack?= , Paul Moore , James Morris , "Serge E . Hallyn" , Martin KaFai Lau , Eduard Zingerman , Yonghong Song , John Fastabend , Kumar Kartikeya Dwivedi , Jiri Olsa , Jeff Layton , Amir Goldstein , Mateusz Guzik , Shuah Khan , Tingmao Wang , Justin Suess Subject: [RFC PATCH bpf-next 07/12] selftests/bpf: exercise the path ancestor iterator Date: Mon, 5 Oct 2026 20:20:14 -0400 Message-ID: <20261006002020.2890858-8-utilityemal77@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20261006002020.2890858-1-utilityemal77@gmail.com> References: <20261006002020.2890858-1-utilityemal77@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Walk the ancestry of a mkdir's parent directory from a sleepable LSM program and check that the iteration reaches the root: the temporary directory, its parent and / are visited, and no position comes back flagged. Resolve the second position's pathname from the acquired position after the step that yielded it has been taken, so that the acquired reference is what the sleepable kfunc runs on rather than the walk's. Signed-off-by: Justin Suess --- .../selftests/bpf/prog_tests/path_ancestors.c | 48 ++++++++++++++++++ .../selftests/bpf/progs/path_ancestors.c | 49 +++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/path_ancestors.c create mode 100644 tools/testing/selftests/bpf/progs/path_ancestors.c diff --git a/tools/testing/selftests/bpf/prog_tests/path_ancestors.c b/tools/testing/selftests/bpf/prog_tests/path_ancestors.c new file mode 100644 index 000000000000..2de79673a13b --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/path_ancestors.c @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2026 Justin Suess */ + +#include +#include +#include +#include +#include "path_ancestors.skel.h" + +void test_path_ancestors(void) +{ + char base[] = "/tmp/path_ancestors_XXXXXX"; + struct path_ancestors *skel = NULL; + char suba[280], subb[280]; + + if (!ASSERT_OK_PTR(mkdtemp(base), "mkdtemp")) + return; + snprintf(suba, sizeof(suba), "%s/a", base); + snprintf(subb, sizeof(subb), "%s/a/b", base); + if (!ASSERT_OK(mkdir(suba, 0755), "mkdir_a")) + goto out_rm; + + skel = path_ancestors__open_and_load(); + if (!ASSERT_OK_PTR(skel, "open_and_load")) + goto out_rm; + skel->bss->monitored_pid = getpid(); + if (!ASSERT_OK(path_ancestors__attach(skel), "attach")) + goto out; + + /* mkdir b: the hook sees dir == suba, whose ancestry is walked. */ + if (!ASSERT_OK(mkdir(subb, 0755), "mkdir_b")) + goto out; + + /* suba, base, /tmp, / at least. */ + ASSERT_GE(skel->bss->ref_count, 3, "ref_count"); + ASSERT_EQ(skel->bss->ref_flags, 0, "ref_flags"); + + /* The acquired second position, used after its step was taken. */ + ASSERT_STREQ(skel->bss->second_path, base, "second_path"); + ASSERT_EQ(skel->bss->second_len, strlen(base) + 1, "second_len"); + +out: + path_ancestors__destroy(skel); +out_rm: + rmdir(subb); + rmdir(suba); + rmdir(base); +} diff --git a/tools/testing/selftests/bpf/progs/path_ancestors.c b/tools/testing/selftests/bpf/progs/path_ancestors.c new file mode 100644 index 000000000000..af6b777e8bec --- /dev/null +++ b/tools/testing/selftests/bpf/progs/path_ancestors.c @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2026 Justin Suess */ + +#include "vmlinux.h" +#include +#include +#include +#include "bpf_kfuncs.h" + +char _license[] SEC("license") = "GPL"; + +__u32 monitored_pid; + +int ref_count; /* positions seen by the pure referenced walk */ +int ref_flags; /* pos flags seen by the referenced walk */ +int second_len; /* d_path length of the walk's second position */ +char second_path[256]; + +static bool monitored(void) +{ + return (bpf_get_current_pid_tgid() >> 32) == monitored_pid; +} + +SEC("lsm.s/path_mkdir") +int BPF_PROG(walk_modes, const struct path *dir, struct dentry *dentry, + umode_t mode) +{ + struct bpf_iter_path_ancestors it; + struct path *pos; + + if (!monitored()) + return 0; + + /* + * Referenced walk: every position comes acquired, so it stays valid + * for sleepable work and past the step that yielded it. + */ + bpf_iter_path_ancestors_new(&it, (struct path *)dir, 0); + while ((pos = bpf_iter_path_ancestors_next(&it))) { + ref_count++; + ref_flags |= bpf_path_ancestors_pos_flags(&it); + if (ref_count == 2) + second_len = bpf_path_d_path(pos, second_path, + sizeof(second_path)); + bpf_path_put(pos); + } + bpf_iter_path_ancestors_destroy(&it); + return 0; +} -- 2.55.0