File Index
Files and directories
Sign in
FILE

verifier_vfs_reject.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/bpf/progs/verifier_vfs_reject.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (c) 2024 Google LLC. */
  3
  4#include <vmlinux.h>
  5#include <errno.h>
  6#include <bpf/bpf_helpers.h>
  7#include <bpf/bpf_tracing.h>
  8#include <linux/limits.h>
  9
 10#include "bpf_misc.h"
 11#include "bpf_experimental.h"
 12
 13static char buf[PATH_MAX];
 14
 15SEC("lsm.s/file_open")
 16__failure __msg("Possibly NULL pointer passed to trusted arg0")
 17int BPF_PROG(get_task_exe_file_kfunc_null)
 18{
 19	struct file *acquired;
 20
 21	/* Can't pass a NULL pointer to bpf_get_task_exe_file(). */
 22	acquired = bpf_get_task_exe_file(NULL);
 23	if (!acquired)
 24		return 0;
 25
 26	bpf_put_file(acquired);
 27	return 0;
 28}
 29
 30SEC("lsm.s/inode_getxattr")
 31__failure __msg("arg#0 pointer type STRUCT task_struct must point to scalar, or struct with scalar")
 32int BPF_PROG(get_task_exe_file_kfunc_fp)
 33{
 34	u64 x;
 35	struct file *acquired;
 36	struct task_struct *task;
 37
 38	task = (struct task_struct *)&x;
 39	/* Can't pass random frame pointer to bpf_get_task_exe_file(). */
 40	acquired = bpf_get_task_exe_file(task);
 41	if (!acquired)
 42		return 0;
 43
 44	bpf_put_file(acquired);
 45	return 0;
 46}
 47
 48SEC("lsm.s/file_open")
 49__failure __msg("R1 must be referenced or trusted")
 50int BPF_PROG(get_task_exe_file_kfunc_untrusted)
 51{
 52	struct file *acquired;
 53	struct task_struct *parent;
 54
 55	/* Walking a trusted struct task_struct returned from
 56	 * bpf_get_current_task_btf() yields an untrusted pointer.
 57	 */
 58	parent = bpf_get_current_task_btf()->parent;
 59	/* Can't pass untrusted pointer to bpf_get_task_exe_file(). */
 60	acquired = bpf_get_task_exe_file(parent);
 61	if (!acquired)
 62		return 0;
 63
 64	bpf_put_file(acquired);
 65	return 0;
 66}
 67
 68SEC("lsm.s/file_open")
 69__failure __msg("Unreleased reference")
 70int BPF_PROG(get_task_exe_file_kfunc_unreleased)
 71{
 72	struct file *acquired;
 73
 74	acquired = bpf_get_task_exe_file(bpf_get_current_task_btf());
 75	if (!acquired)
 76		return 0;
 77
 78	/* Acquired but never released. */
 79	return 0;
 80}
 81
 82SEC("lsm.s/file_open")
 83__failure __msg("release kernel function bpf_put_file expects")
 84int BPF_PROG(put_file_kfunc_unacquired, struct file *file)
 85{
 86	/* Can't release an unacquired pointer. */
 87	bpf_put_file(file);
 88	return 0;
 89}
 90
 91SEC("lsm.s/file_open")
 92__failure __msg("Possibly NULL pointer passed to trusted arg0")
 93int BPF_PROG(path_d_path_kfunc_null)
 94{
 95	/* Can't pass NULL value to bpf_path_d_path() kfunc. */
 96	bpf_path_d_path(NULL, buf, sizeof(buf));
 97	return 0;
 98}
 99
100SEC("lsm.s/task_alloc")
101__failure __msg("R1 must be referenced or trusted")
102int BPF_PROG(path_d_path_kfunc_untrusted_from_argument, struct task_struct *task)
103{
104	struct path *root;
105
106	/* Walking a trusted argument typically yields an untrusted
107	 * pointer. This is one example of that.
108	 */
109	root = &task->fs->root;
110	bpf_path_d_path(root, buf, sizeof(buf));
111	return 0;
112}
113
114SEC("lsm.s/file_open")
115__failure __msg("R1 must be referenced or trusted")
116int BPF_PROG(path_d_path_kfunc_untrusted_from_current)
117{
118	struct path *pwd;
119	struct task_struct *current;
120
121	current = bpf_get_current_task_btf();
122	/* Walking a trusted pointer returned from bpf_get_current_task_btf()
123	 * yields an untrusted pointer.
124	 */
125	pwd = &current->fs->pwd;
126	bpf_path_d_path(pwd, buf, sizeof(buf));
127	return 0;
128}
129
130SEC("lsm.s/file_open")
131__failure __msg("kernel function bpf_path_d_path args#0 expected pointer to STRUCT path but R1 has a pointer to STRUCT file")
132int BPF_PROG(path_d_path_kfunc_type_mismatch, struct file *file)
133{
134	bpf_path_d_path((struct path *)&file->f_task_work, buf, sizeof(buf));
135	return 0;
136}
137
138SEC("lsm.s/file_open")
139__failure __msg("invalid access to map value, value_size=4096 off=0 size=8192")
140int BPF_PROG(path_d_path_kfunc_invalid_buf_sz, struct file *file)
141{
142	/* bpf_path_d_path() enforces a constraint on the buffer size supplied
143	 * by the BPF LSM program via the __sz annotation. buf here is set to
144	 * PATH_MAX, so let's ensure that the BPF verifier rejects BPF_PROG_LOAD
145	 * attempts if the supplied size and the actual size of the buffer
146	 * mismatches.
147	 */
148	bpf_path_d_path(&file->f_path, buf, PATH_MAX * 2);
149	return 0;
150}
151
152SEC("fentry/vfs_open")
153__failure __msg("calling kernel function bpf_path_d_path is not allowed")
154int BPF_PROG(path_d_path_kfunc_non_lsm, struct path *path, struct file *f)
155{
156	/* Calling bpf_path_d_path() from a non-LSM BPF program isn't permitted.
157	 */
158	bpf_path_d_path(path, buf, sizeof(buf));
159	return 0;
160}
161
162SEC("lsm.s/inode_rename")
163__failure __msg("invalid mem access 'trusted_ptr_or_null_'")
164int BPF_PROG(inode_rename, struct inode *old_dir, struct dentry *old_dentry,
165	     struct inode *new_dir, struct dentry *new_dentry,
166	     unsigned int flags)
167{
168	struct inode *inode = new_dentry->d_inode;
169	ino_t ino;
170
171	ino = inode->i_ino;
172	if (ino == 0)
173		return -EACCES;
174	return 0;
175}
176char _license[] SEC("license") = "GPL";
~/ Read-only file preview.