~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/bpf_fs_kfuncs.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /fs/bpf_fs_kfuncs.c (Architecture i386) and /fs/bpf_fs_kfuncs.c (Architecture sparc64)


  1 // SPDX-License-Identifier: GPL-2.0                 1 // SPDX-License-Identifier: GPL-2.0
  2 /* Copyright (c) 2024 Google LLC. */                2 /* Copyright (c) 2024 Google LLC. */
  3                                                     3 
  4 #include <linux/bpf.h>                              4 #include <linux/bpf.h>
  5 #include <linux/btf.h>                              5 #include <linux/btf.h>
  6 #include <linux/btf_ids.h>                          6 #include <linux/btf_ids.h>
  7 #include <linux/dcache.h>                           7 #include <linux/dcache.h>
  8 #include <linux/fs.h>                               8 #include <linux/fs.h>
  9 #include <linux/file.h>                             9 #include <linux/file.h>
 10 #include <linux/mm.h>                              10 #include <linux/mm.h>
 11 #include <linux/xattr.h>                           11 #include <linux/xattr.h>
 12                                                    12 
 13 __bpf_kfunc_start_defs();                          13 __bpf_kfunc_start_defs();
 14                                                    14 
 15 /**                                                15 /**
 16  * bpf_get_task_exe_file - get a reference on      16  * bpf_get_task_exe_file - get a reference on the exe_file struct file member of
 17  *                         the mm_struct that      17  *                         the mm_struct that is nested within the supplied
 18  *                         task_struct             18  *                         task_struct
 19  * @task: task_struct of which the nested mm_s     19  * @task: task_struct of which the nested mm_struct exe_file member to get a
 20  * reference on                                    20  * reference on
 21  *                                                 21  *
 22  * Get a reference on the exe_file struct file     22  * Get a reference on the exe_file struct file member field of the mm_struct
 23  * nested within the supplied *task*. The refe     23  * nested within the supplied *task*. The referenced file pointer acquired by
 24  * this BPF kfunc must be released using bpf_p     24  * this BPF kfunc must be released using bpf_put_file(). Failing to call
 25  * bpf_put_file() on the returned referenced s     25  * bpf_put_file() on the returned referenced struct file pointer that has been
 26  * acquired by this BPF kfunc will result in t     26  * acquired by this BPF kfunc will result in the BPF program being rejected by
 27  * the BPF verifier.                               27  * the BPF verifier.
 28  *                                                 28  *
 29  * This BPF kfunc may only be called from BPF      29  * This BPF kfunc may only be called from BPF LSM programs.
 30  *                                                 30  *
 31  * Internally, this BPF kfunc leans on get_tas     31  * Internally, this BPF kfunc leans on get_task_exe_file(), such that calling
 32  * bpf_get_task_exe_file() would be analogous      32  * bpf_get_task_exe_file() would be analogous to calling get_task_exe_file()
 33  * directly in kernel context.                     33  * directly in kernel context.
 34  *                                                 34  *
 35  * Return: A referenced struct file pointer to     35  * Return: A referenced struct file pointer to the exe_file member of the
 36  * mm_struct that is nested within the supplie     36  * mm_struct that is nested within the supplied *task*. On error, NULL is
 37  * returned.                                       37  * returned.
 38  */                                                38  */
 39 __bpf_kfunc struct file *bpf_get_task_exe_file     39 __bpf_kfunc struct file *bpf_get_task_exe_file(struct task_struct *task)
 40 {                                                  40 {
 41         return get_task_exe_file(task);            41         return get_task_exe_file(task);
 42 }                                                  42 }
 43                                                    43 
 44 /**                                                44 /**
 45  * bpf_put_file - put a reference on the suppl     45  * bpf_put_file - put a reference on the supplied file
 46  * @file: file to put a reference on               46  * @file: file to put a reference on
 47  *                                                 47  *
 48  * Put a reference on the supplied *file*. Onl     48  * Put a reference on the supplied *file*. Only referenced file pointers may be
 49  * passed to this BPF kfunc. Attempting to pas     49  * passed to this BPF kfunc. Attempting to pass an unreferenced file pointer, or
 50  * any other arbitrary pointer for that matter     50  * any other arbitrary pointer for that matter, will result in the BPF program
 51  * being rejected by the BPF verifier.             51  * being rejected by the BPF verifier.
 52  *                                                 52  *
 53  * This BPF kfunc may only be called from BPF      53  * This BPF kfunc may only be called from BPF LSM programs.
 54  */                                                54  */
 55 __bpf_kfunc void bpf_put_file(struct file *fil     55 __bpf_kfunc void bpf_put_file(struct file *file)
 56 {                                                  56 {
 57         fput(file);                                57         fput(file);
 58 }                                                  58 }
 59                                                    59 
 60 /**                                                60 /**
 61  * bpf_path_d_path - resolve the pathname for      61  * bpf_path_d_path - resolve the pathname for the supplied path
 62  * @path: path to resolve the pathname for         62  * @path: path to resolve the pathname for
 63  * @buf: buffer to return the resolved pathnam     63  * @buf: buffer to return the resolved pathname in
 64  * @buf__sz: length of the supplied buffer         64  * @buf__sz: length of the supplied buffer
 65  *                                                 65  *
 66  * Resolve the pathname for the supplied *path     66  * Resolve the pathname for the supplied *path* and store it in *buf*. This BPF
 67  * kfunc is the safer variant of the legacy bp     67  * kfunc is the safer variant of the legacy bpf_d_path() helper and should be
 68  * used in place of bpf_d_path() whenever poss     68  * used in place of bpf_d_path() whenever possible. It enforces KF_TRUSTED_ARGS
 69  * semantics, meaning that the supplied *path*     69  * semantics, meaning that the supplied *path* must itself hold a valid
 70  * reference, or else the BPF program will be      70  * reference, or else the BPF program will be outright rejected by the BPF
 71  * verifier.                                       71  * verifier.
 72  *                                                 72  *
 73  * This BPF kfunc may only be called from BPF      73  * This BPF kfunc may only be called from BPF LSM programs.
 74  *                                                 74  *
 75  * Return: A positive integer corresponding to     75  * Return: A positive integer corresponding to the length of the resolved
 76  * pathname in *buf*, including the NUL termin     76  * pathname in *buf*, including the NUL termination character. On error, a
 77  * negative integer is returned.                   77  * negative integer is returned.
 78  */                                                78  */
 79 __bpf_kfunc int bpf_path_d_path(struct path *p     79 __bpf_kfunc int bpf_path_d_path(struct path *path, char *buf, size_t buf__sz)
 80 {                                                  80 {
 81         int len;                                   81         int len;
 82         char *ret;                                 82         char *ret;
 83                                                    83 
 84         if (!buf__sz)                              84         if (!buf__sz)
 85                 return -EINVAL;                    85                 return -EINVAL;
 86                                                    86 
 87         ret = d_path(path, buf, buf__sz);          87         ret = d_path(path, buf, buf__sz);
 88         if (IS_ERR(ret))                           88         if (IS_ERR(ret))
 89                 return PTR_ERR(ret);               89                 return PTR_ERR(ret);
 90                                                    90 
 91         len = buf + buf__sz - ret;                 91         len = buf + buf__sz - ret;
 92         memmove(buf, ret, len);                    92         memmove(buf, ret, len);
 93         return len;                                93         return len;
 94 }                                                  94 }
 95                                                    95 
 96 /**                                                96 /**
 97  * bpf_get_dentry_xattr - get xattr of a dentr     97  * bpf_get_dentry_xattr - get xattr of a dentry
 98  * @dentry: dentry to get xattr from               98  * @dentry: dentry to get xattr from
 99  * @name__str: name of the xattr                   99  * @name__str: name of the xattr
100  * @value_p: output buffer of the xattr value     100  * @value_p: output buffer of the xattr value
101  *                                                101  *
102  * Get xattr *name__str* of *dentry* and store    102  * Get xattr *name__str* of *dentry* and store the output in *value_ptr*.
103  *                                                103  *
104  * For security reasons, only *name__str* with    104  * For security reasons, only *name__str* with prefix "user." is allowed.
105  *                                                105  *
106  * Return: 0 on success, a negative value on e    106  * Return: 0 on success, a negative value on error.
107  */                                               107  */
108 __bpf_kfunc int bpf_get_dentry_xattr(struct de    108 __bpf_kfunc int bpf_get_dentry_xattr(struct dentry *dentry, const char *name__str,
109                                      struct bp    109                                      struct bpf_dynptr *value_p)
110 {                                                 110 {
111         struct bpf_dynptr_kern *value_ptr = (s    111         struct bpf_dynptr_kern *value_ptr = (struct bpf_dynptr_kern *)value_p;
112         struct inode *inode = d_inode(dentry);    112         struct inode *inode = d_inode(dentry);
113         u32 value_len;                            113         u32 value_len;
114         void *value;                              114         void *value;
115         int ret;                                  115         int ret;
116                                                   116 
117         if (WARN_ON(!inode))                      117         if (WARN_ON(!inode))
118                 return -EINVAL;                   118                 return -EINVAL;
119                                                   119 
120         if (strncmp(name__str, XATTR_USER_PREF    120         if (strncmp(name__str, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
121                 return -EPERM;                    121                 return -EPERM;
122                                                   122 
123         value_len = __bpf_dynptr_size(value_pt    123         value_len = __bpf_dynptr_size(value_ptr);
124         value = __bpf_dynptr_data_rw(value_ptr    124         value = __bpf_dynptr_data_rw(value_ptr, value_len);
125         if (!value)                               125         if (!value)
126                 return -EINVAL;                   126                 return -EINVAL;
127                                                   127 
128         ret = inode_permission(&nop_mnt_idmap,    128         ret = inode_permission(&nop_mnt_idmap, inode, MAY_READ);
129         if (ret)                                  129         if (ret)
130                 return ret;                       130                 return ret;
131         return __vfs_getxattr(dentry, inode, n    131         return __vfs_getxattr(dentry, inode, name__str, value, value_len);
132 }                                                 132 }
133                                                   133 
134 /**                                               134 /**
135  * bpf_get_file_xattr - get xattr of a file       135  * bpf_get_file_xattr - get xattr of a file
136  * @file: file to get xattr from                  136  * @file: file to get xattr from
137  * @name__str: name of the xattr                  137  * @name__str: name of the xattr
138  * @value_p: output buffer of the xattr value     138  * @value_p: output buffer of the xattr value
139  *                                                139  *
140  * Get xattr *name__str* of *file* and store t    140  * Get xattr *name__str* of *file* and store the output in *value_ptr*.
141  *                                                141  *
142  * For security reasons, only *name__str* with    142  * For security reasons, only *name__str* with prefix "user." is allowed.
143  *                                                143  *
144  * Return: 0 on success, a negative value on e    144  * Return: 0 on success, a negative value on error.
145  */                                               145  */
146 __bpf_kfunc int bpf_get_file_xattr(struct file    146 __bpf_kfunc int bpf_get_file_xattr(struct file *file, const char *name__str,
147                                    struct bpf_    147                                    struct bpf_dynptr *value_p)
148 {                                                 148 {
149         struct dentry *dentry;                    149         struct dentry *dentry;
150                                                   150 
151         dentry = file_dentry(file);               151         dentry = file_dentry(file);
152         return bpf_get_dentry_xattr(dentry, na    152         return bpf_get_dentry_xattr(dentry, name__str, value_p);
153 }                                                 153 }
154                                                   154 
155 __bpf_kfunc_end_defs();                           155 __bpf_kfunc_end_defs();
156                                                   156 
157 BTF_KFUNCS_START(bpf_fs_kfunc_set_ids)            157 BTF_KFUNCS_START(bpf_fs_kfunc_set_ids)
158 BTF_ID_FLAGS(func, bpf_get_task_exe_file,         158 BTF_ID_FLAGS(func, bpf_get_task_exe_file,
159              KF_ACQUIRE | KF_TRUSTED_ARGS | KF    159              KF_ACQUIRE | KF_TRUSTED_ARGS | KF_RET_NULL)
160 BTF_ID_FLAGS(func, bpf_put_file, KF_RELEASE)      160 BTF_ID_FLAGS(func, bpf_put_file, KF_RELEASE)
161 BTF_ID_FLAGS(func, bpf_path_d_path, KF_TRUSTED    161 BTF_ID_FLAGS(func, bpf_path_d_path, KF_TRUSTED_ARGS)
162 BTF_ID_FLAGS(func, bpf_get_dentry_xattr, KF_SL    162 BTF_ID_FLAGS(func, bpf_get_dentry_xattr, KF_SLEEPABLE | KF_TRUSTED_ARGS)
163 BTF_ID_FLAGS(func, bpf_get_file_xattr, KF_SLEE    163 BTF_ID_FLAGS(func, bpf_get_file_xattr, KF_SLEEPABLE | KF_TRUSTED_ARGS)
164 BTF_KFUNCS_END(bpf_fs_kfunc_set_ids)              164 BTF_KFUNCS_END(bpf_fs_kfunc_set_ids)
165                                                   165 
166 static int bpf_fs_kfuncs_filter(const struct b    166 static int bpf_fs_kfuncs_filter(const struct bpf_prog *prog, u32 kfunc_id)
167 {                                                 167 {
168         if (!btf_id_set8_contains(&bpf_fs_kfun    168         if (!btf_id_set8_contains(&bpf_fs_kfunc_set_ids, kfunc_id) ||
169             prog->type == BPF_PROG_TYPE_LSM)      169             prog->type == BPF_PROG_TYPE_LSM)
170                 return 0;                         170                 return 0;
171         return -EACCES;                           171         return -EACCES;
172 }                                                 172 }
173                                                   173 
174 static const struct btf_kfunc_id_set bpf_fs_kf    174 static const struct btf_kfunc_id_set bpf_fs_kfunc_set = {
175         .owner = THIS_MODULE,                     175         .owner = THIS_MODULE,
176         .set = &bpf_fs_kfunc_set_ids,             176         .set = &bpf_fs_kfunc_set_ids,
177         .filter = bpf_fs_kfuncs_filter,           177         .filter = bpf_fs_kfuncs_filter,
178 };                                                178 };
179                                                   179 
180 static int __init bpf_fs_kfuncs_init(void)        180 static int __init bpf_fs_kfuncs_init(void)
181 {                                                 181 {
182         return register_btf_kfunc_id_set(BPF_P    182         return register_btf_kfunc_id_set(BPF_PROG_TYPE_LSM, &bpf_fs_kfunc_set);
183 }                                                 183 }
184                                                   184 
185 late_initcall(bpf_fs_kfuncs_init);                185 late_initcall(bpf_fs_kfuncs_init);
186                                                   186 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php