LCOV - code coverage report
Current view: top level - kernel/bpf - inode.c (source / functions) Hit Total Coverage
Test: gcov_data_raspi2_real_modules_combined.info Lines: 41 263 15.6 %
Date: 2020-09-30 20:25:40 Functions: 7 34 20.6 %
Branches: 9 127 7.1 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-only
       2                 :            : /*
       3                 :            :  * Minimal file system backend for holding eBPF maps and programs,
       4                 :            :  * used by bpf(2) object pinning.
       5                 :            :  *
       6                 :            :  * Authors:
       7                 :            :  *
       8                 :            :  *      Daniel Borkmann <daniel@iogearbox.net>
       9                 :            :  */
      10                 :            : 
      11                 :            : #include <linux/init.h>
      12                 :            : #include <linux/magic.h>
      13                 :            : #include <linux/major.h>
      14                 :            : #include <linux/mount.h>
      15                 :            : #include <linux/namei.h>
      16                 :            : #include <linux/fs.h>
      17                 :            : #include <linux/fs_context.h>
      18                 :            : #include <linux/fs_parser.h>
      19                 :            : #include <linux/kdev_t.h>
      20                 :            : #include <linux/filter.h>
      21                 :            : #include <linux/bpf.h>
      22                 :            : #include <linux/bpf_trace.h>
      23                 :            : 
      24                 :            : enum bpf_type {
      25                 :            :         BPF_TYPE_UNSPEC = 0,
      26                 :            :         BPF_TYPE_PROG,
      27                 :            :         BPF_TYPE_MAP,
      28                 :            : };
      29                 :            : 
      30                 :          0 : static void *bpf_any_get(void *raw, enum bpf_type type)
      31                 :            : {
      32      [ #  #  # ]:          0 :         switch (type) {
      33                 :            :         case BPF_TYPE_PROG:
      34                 :          0 :                 raw = bpf_prog_inc(raw);
      35                 :          0 :                 break;
      36                 :            :         case BPF_TYPE_MAP:
      37                 :          0 :                 raw = bpf_map_inc(raw, true);
      38                 :          0 :                 break;
      39                 :            :         default:
      40         [ #  # ]:          0 :                 WARN_ON_ONCE(1);
      41                 :            :                 break;
      42                 :            :         }
      43                 :            : 
      44                 :          0 :         return raw;
      45                 :            : }
      46                 :            : 
      47                 :          0 : static void bpf_any_put(void *raw, enum bpf_type type)
      48                 :            : {
      49      [ #  #  # ]:          0 :         switch (type) {
      50                 :            :         case BPF_TYPE_PROG:
      51                 :          0 :                 bpf_prog_put(raw);
      52                 :          0 :                 break;
      53                 :            :         case BPF_TYPE_MAP:
      54                 :          0 :                 bpf_map_put_with_uref(raw);
      55                 :          0 :                 break;
      56                 :            :         default:
      57         [ #  # ]:          0 :                 WARN_ON_ONCE(1);
      58                 :            :                 break;
      59                 :            :         }
      60                 :          0 : }
      61                 :            : 
      62                 :          0 : static void *bpf_fd_probe_obj(u32 ufd, enum bpf_type *type)
      63                 :            : {
      64                 :            :         void *raw;
      65                 :            : 
      66                 :          0 :         *type = BPF_TYPE_MAP;
      67                 :          0 :         raw = bpf_map_get_with_uref(ufd);
      68         [ #  # ]:          0 :         if (IS_ERR(raw)) {
      69                 :          0 :                 *type = BPF_TYPE_PROG;
      70                 :          0 :                 raw = bpf_prog_get(ufd);
      71                 :            :         }
      72                 :            : 
      73                 :          0 :         return raw;
      74                 :            : }
      75                 :            : 
      76                 :            : static const struct inode_operations bpf_dir_iops;
      77                 :            : 
      78                 :            : static const struct inode_operations bpf_prog_iops = { };
      79                 :            : static const struct inode_operations bpf_map_iops  = { };
      80                 :            : 
      81                 :          0 : static struct inode *bpf_get_inode(struct super_block *sb,
      82                 :            :                                    const struct inode *dir,
      83                 :            :                                    umode_t mode)
      84                 :            : {
      85                 :            :         struct inode *inode;
      86                 :            : 
      87         [ #  # ]:          0 :         switch (mode & S_IFMT) {
      88                 :            :         case S_IFDIR:
      89                 :            :         case S_IFREG:
      90                 :            :         case S_IFLNK:
      91                 :            :                 break;
      92                 :            :         default:
      93                 :            :                 return ERR_PTR(-EINVAL);
      94                 :            :         }
      95                 :            : 
      96                 :          0 :         inode = new_inode(sb);
      97         [ #  # ]:          0 :         if (!inode)
      98                 :            :                 return ERR_PTR(-ENOSPC);
      99                 :            : 
     100                 :          0 :         inode->i_ino = get_next_ino();
     101                 :          0 :         inode->i_atime = current_time(inode);
     102                 :          0 :         inode->i_mtime = inode->i_atime;
     103                 :          0 :         inode->i_ctime = inode->i_atime;
     104                 :            : 
     105                 :          0 :         inode_init_owner(inode, dir, mode);
     106                 :            : 
     107                 :          0 :         return inode;
     108                 :            : }
     109                 :            : 
     110                 :            : static int bpf_inode_type(const struct inode *inode, enum bpf_type *type)
     111                 :            : {
     112                 :          0 :         *type = BPF_TYPE_UNSPEC;
     113   [ #  #  #  # ]:          0 :         if (inode->i_op == &bpf_prog_iops)
     114                 :          0 :                 *type = BPF_TYPE_PROG;
     115   [ #  #  #  # ]:          0 :         else if (inode->i_op == &bpf_map_iops)
     116                 :          0 :                 *type = BPF_TYPE_MAP;
     117                 :            :         else
     118                 :            :                 return -EACCES;
     119                 :            : 
     120                 :            :         return 0;
     121                 :            : }
     122                 :            : 
     123                 :          0 : static void bpf_dentry_finalize(struct dentry *dentry, struct inode *inode,
     124                 :            :                                 struct inode *dir)
     125                 :            : {
     126                 :          0 :         d_instantiate(dentry, inode);
     127                 :            :         dget(dentry);
     128                 :            : 
     129                 :          0 :         dir->i_mtime = current_time(dir);
     130                 :          0 :         dir->i_ctime = dir->i_mtime;
     131                 :          0 : }
     132                 :            : 
     133                 :          0 : static int bpf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
     134                 :            : {
     135                 :            :         struct inode *inode;
     136                 :            : 
     137                 :          0 :         inode = bpf_get_inode(dir->i_sb, dir, mode | S_IFDIR);
     138         [ #  # ]:          0 :         if (IS_ERR(inode))
     139                 :          0 :                 return PTR_ERR(inode);
     140                 :            : 
     141                 :          0 :         inode->i_op = &bpf_dir_iops;
     142                 :          0 :         inode->i_fop = &simple_dir_operations;
     143                 :            : 
     144                 :          0 :         inc_nlink(inode);
     145                 :          0 :         inc_nlink(dir);
     146                 :            : 
     147                 :          0 :         bpf_dentry_finalize(dentry, inode, dir);
     148                 :          0 :         return 0;
     149                 :            : }
     150                 :            : 
     151                 :            : struct map_iter {
     152                 :            :         void *key;
     153                 :            :         bool done;
     154                 :            : };
     155                 :            : 
     156                 :            : static struct map_iter *map_iter(struct seq_file *m)
     157                 :            : {
     158                 :          0 :         return m->private;
     159                 :            : }
     160                 :            : 
     161                 :            : static struct bpf_map *seq_file_to_map(struct seq_file *m)
     162                 :            : {
     163                 :          0 :         return file_inode(m->file)->i_private;
     164                 :            : }
     165                 :            : 
     166                 :          0 : static void map_iter_free(struct map_iter *iter)
     167                 :            : {
     168         [ #  # ]:          0 :         if (iter) {
     169                 :          0 :                 kfree(iter->key);
     170                 :          0 :                 kfree(iter);
     171                 :            :         }
     172                 :          0 : }
     173                 :            : 
     174                 :          0 : static struct map_iter *map_iter_alloc(struct bpf_map *map)
     175                 :            : {
     176                 :            :         struct map_iter *iter;
     177                 :            : 
     178                 :          0 :         iter = kzalloc(sizeof(*iter), GFP_KERNEL | __GFP_NOWARN);
     179         [ #  # ]:          0 :         if (!iter)
     180                 :            :                 goto error;
     181                 :            : 
     182                 :          0 :         iter->key = kzalloc(map->key_size, GFP_KERNEL | __GFP_NOWARN);
     183         [ #  # ]:          0 :         if (!iter->key)
     184                 :            :                 goto error;
     185                 :            : 
     186                 :            :         return iter;
     187                 :            : 
     188                 :            : error:
     189                 :          0 :         map_iter_free(iter);
     190                 :          0 :         return NULL;
     191                 :            : }
     192                 :            : 
     193                 :          0 : static void *map_seq_next(struct seq_file *m, void *v, loff_t *pos)
     194                 :            : {
     195                 :            :         struct bpf_map *map = seq_file_to_map(m);
     196                 :          0 :         void *key = map_iter(m)->key;
     197                 :            :         void *prev_key;
     198                 :            : 
     199                 :          0 :         (*pos)++;
     200         [ #  # ]:          0 :         if (map_iter(m)->done)
     201                 :            :                 return NULL;
     202                 :            : 
     203         [ #  # ]:          0 :         if (unlikely(v == SEQ_START_TOKEN))
     204                 :            :                 prev_key = NULL;
     205                 :            :         else
     206                 :            :                 prev_key = key;
     207                 :            : 
     208         [ #  # ]:          0 :         if (map->ops->map_get_next_key(map, prev_key, key)) {
     209                 :          0 :                 map_iter(m)->done = true;
     210                 :          0 :                 return NULL;
     211                 :            :         }
     212                 :            :         return key;
     213                 :            : }
     214                 :            : 
     215                 :          0 : static void *map_seq_start(struct seq_file *m, loff_t *pos)
     216                 :            : {
     217         [ #  # ]:          0 :         if (map_iter(m)->done)
     218                 :            :                 return NULL;
     219                 :            : 
     220         [ #  # ]:          0 :         return *pos ? map_iter(m)->key : SEQ_START_TOKEN;
     221                 :            : }
     222                 :            : 
     223                 :          0 : static void map_seq_stop(struct seq_file *m, void *v)
     224                 :            : {
     225                 :          0 : }
     226                 :            : 
     227                 :          0 : static int map_seq_show(struct seq_file *m, void *v)
     228                 :            : {
     229                 :            :         struct bpf_map *map = seq_file_to_map(m);
     230                 :          0 :         void *key = map_iter(m)->key;
     231                 :            : 
     232         [ #  # ]:          0 :         if (unlikely(v == SEQ_START_TOKEN)) {
     233                 :          0 :                 seq_puts(m, "# WARNING!! The output is for debug purpose only\n");
     234                 :          0 :                 seq_puts(m, "# WARNING!! The output format will change\n");
     235                 :            :         } else {
     236                 :          0 :                 map->ops->map_seq_show_elem(map, key, m);
     237                 :            :         }
     238                 :            : 
     239                 :          0 :         return 0;
     240                 :            : }
     241                 :            : 
     242                 :            : static const struct seq_operations bpffs_map_seq_ops = {
     243                 :            :         .start  = map_seq_start,
     244                 :            :         .next   = map_seq_next,
     245                 :            :         .show   = map_seq_show,
     246                 :            :         .stop   = map_seq_stop,
     247                 :            : };
     248                 :            : 
     249                 :          0 : static int bpffs_map_open(struct inode *inode, struct file *file)
     250                 :            : {
     251                 :          0 :         struct bpf_map *map = inode->i_private;
     252                 :            :         struct map_iter *iter;
     253                 :            :         struct seq_file *m;
     254                 :            :         int err;
     255                 :            : 
     256                 :          0 :         iter = map_iter_alloc(map);
     257         [ #  # ]:          0 :         if (!iter)
     258                 :            :                 return -ENOMEM;
     259                 :            : 
     260                 :          0 :         err = seq_open(file, &bpffs_map_seq_ops);
     261         [ #  # ]:          0 :         if (err) {
     262                 :          0 :                 map_iter_free(iter);
     263                 :          0 :                 return err;
     264                 :            :         }
     265                 :            : 
     266                 :          0 :         m = file->private_data;
     267                 :          0 :         m->private = iter;
     268                 :            : 
     269                 :          0 :         return 0;
     270                 :            : }
     271                 :            : 
     272                 :          0 : static int bpffs_map_release(struct inode *inode, struct file *file)
     273                 :            : {
     274                 :          0 :         struct seq_file *m = file->private_data;
     275                 :            : 
     276                 :          0 :         map_iter_free(map_iter(m));
     277                 :            : 
     278                 :          0 :         return seq_release(inode, file);
     279                 :            : }
     280                 :            : 
     281                 :            : /* bpffs_map_fops should only implement the basic
     282                 :            :  * read operation for a BPF map.  The purpose is to
     283                 :            :  * provide a simple user intuitive way to do
     284                 :            :  * "cat bpffs/pathto/a-pinned-map".
     285                 :            :  *
     286                 :            :  * Other operations (e.g. write, lookup...) should be realized by
     287                 :            :  * the userspace tools (e.g. bpftool) through the
     288                 :            :  * BPF_OBJ_GET_INFO_BY_FD and the map's lookup/update
     289                 :            :  * interface.
     290                 :            :  */
     291                 :            : static const struct file_operations bpffs_map_fops = {
     292                 :            :         .open           = bpffs_map_open,
     293                 :            :         .read           = seq_read,
     294                 :            :         .release        = bpffs_map_release,
     295                 :            : };
     296                 :            : 
     297                 :          0 : static int bpffs_obj_open(struct inode *inode, struct file *file)
     298                 :            : {
     299                 :          0 :         return -EIO;
     300                 :            : }
     301                 :            : 
     302                 :            : static const struct file_operations bpffs_obj_fops = {
     303                 :            :         .open           = bpffs_obj_open,
     304                 :            : };
     305                 :            : 
     306                 :          0 : static int bpf_mkobj_ops(struct dentry *dentry, umode_t mode, void *raw,
     307                 :            :                          const struct inode_operations *iops,
     308                 :            :                          const struct file_operations *fops)
     309                 :            : {
     310                 :          0 :         struct inode *dir = dentry->d_parent->d_inode;
     311                 :          0 :         struct inode *inode = bpf_get_inode(dir->i_sb, dir, mode);
     312         [ #  # ]:          0 :         if (IS_ERR(inode))
     313                 :          0 :                 return PTR_ERR(inode);
     314                 :            : 
     315                 :          0 :         inode->i_op = iops;
     316                 :          0 :         inode->i_fop = fops;
     317                 :          0 :         inode->i_private = raw;
     318                 :            : 
     319                 :          0 :         bpf_dentry_finalize(dentry, inode, dir);
     320                 :          0 :         return 0;
     321                 :            : }
     322                 :            : 
     323                 :          0 : static int bpf_mkprog(struct dentry *dentry, umode_t mode, void *arg)
     324                 :            : {
     325                 :          0 :         return bpf_mkobj_ops(dentry, mode, arg, &bpf_prog_iops,
     326                 :            :                              &bpffs_obj_fops);
     327                 :            : }
     328                 :            : 
     329                 :          0 : static int bpf_mkmap(struct dentry *dentry, umode_t mode, void *arg)
     330                 :            : {
     331                 :            :         struct bpf_map *map = arg;
     332                 :            : 
     333         [ #  # ]:          0 :         return bpf_mkobj_ops(dentry, mode, arg, &bpf_map_iops,
     334                 :            :                              bpf_map_support_seq_show(map) ?
     335                 :            :                              &bpffs_map_fops : &bpffs_obj_fops);
     336                 :            : }
     337                 :            : 
     338                 :            : static struct dentry *
     339                 :          0 : bpf_lookup(struct inode *dir, struct dentry *dentry, unsigned flags)
     340                 :            : {
     341                 :            :         /* Dots in names (e.g. "/sys/fs/bpf/foo.bar") are reserved for future
     342                 :            :          * extensions.
     343                 :            :          */
     344         [ #  # ]:          0 :         if (strchr(dentry->d_name.name, '.'))
     345                 :            :                 return ERR_PTR(-EPERM);
     346                 :            : 
     347                 :          0 :         return simple_lookup(dir, dentry, flags);
     348                 :            : }
     349                 :            : 
     350                 :          0 : static int bpf_symlink(struct inode *dir, struct dentry *dentry,
     351                 :            :                        const char *target)
     352                 :            : {
     353                 :          0 :         char *link = kstrdup(target, GFP_USER | __GFP_NOWARN);
     354                 :            :         struct inode *inode;
     355                 :            : 
     356         [ #  # ]:          0 :         if (!link)
     357                 :            :                 return -ENOMEM;
     358                 :            : 
     359                 :          0 :         inode = bpf_get_inode(dir->i_sb, dir, S_IRWXUGO | S_IFLNK);
     360         [ #  # ]:          0 :         if (IS_ERR(inode)) {
     361                 :          0 :                 kfree(link);
     362                 :          0 :                 return PTR_ERR(inode);
     363                 :            :         }
     364                 :            : 
     365                 :          0 :         inode->i_op = &simple_symlink_inode_operations;
     366                 :          0 :         inode->i_link = link;
     367                 :            : 
     368                 :          0 :         bpf_dentry_finalize(dentry, inode, dir);
     369                 :          0 :         return 0;
     370                 :            : }
     371                 :            : 
     372                 :            : static const struct inode_operations bpf_dir_iops = {
     373                 :            :         .lookup         = bpf_lookup,
     374                 :            :         .mkdir          = bpf_mkdir,
     375                 :            :         .symlink        = bpf_symlink,
     376                 :            :         .rmdir          = simple_rmdir,
     377                 :            :         .rename         = simple_rename,
     378                 :            :         .link           = simple_link,
     379                 :            :         .unlink         = simple_unlink,
     380                 :            : };
     381                 :            : 
     382                 :          0 : static int bpf_obj_do_pin(const struct filename *pathname, void *raw,
     383                 :            :                           enum bpf_type type)
     384                 :            : {
     385                 :            :         struct dentry *dentry;
     386                 :            :         struct inode *dir;
     387                 :            :         struct path path;
     388                 :            :         umode_t mode;
     389                 :            :         int ret;
     390                 :            : 
     391                 :          0 :         dentry = kern_path_create(AT_FDCWD, pathname->name, &path, 0);
     392         [ #  # ]:          0 :         if (IS_ERR(dentry))
     393                 :          0 :                 return PTR_ERR(dentry);
     394                 :            : 
     395                 :          0 :         mode = S_IFREG | ((S_IRUSR | S_IWUSR) & ~current_umask());
     396                 :            : 
     397                 :          0 :         ret = security_path_mknod(&path, dentry, mode, 0);
     398         [ #  # ]:          0 :         if (ret)
     399                 :            :                 goto out;
     400                 :            : 
     401                 :          0 :         dir = d_inode(path.dentry);
     402         [ #  # ]:          0 :         if (dir->i_op != &bpf_dir_iops) {
     403                 :            :                 ret = -EPERM;
     404                 :            :                 goto out;
     405                 :            :         }
     406                 :            : 
     407      [ #  #  # ]:          0 :         switch (type) {
     408                 :            :         case BPF_TYPE_PROG:
     409                 :          0 :                 ret = vfs_mkobj(dentry, mode, bpf_mkprog, raw);
     410                 :          0 :                 break;
     411                 :            :         case BPF_TYPE_MAP:
     412                 :          0 :                 ret = vfs_mkobj(dentry, mode, bpf_mkmap, raw);
     413                 :          0 :                 break;
     414                 :            :         default:
     415                 :            :                 ret = -EPERM;
     416                 :            :         }
     417                 :            : out:
     418                 :          0 :         done_path_create(&path, dentry);
     419                 :          0 :         return ret;
     420                 :            : }
     421                 :            : 
     422                 :          0 : int bpf_obj_pin_user(u32 ufd, const char __user *pathname)
     423                 :            : {
     424                 :            :         struct filename *pname;
     425                 :            :         enum bpf_type type;
     426                 :            :         void *raw;
     427                 :            :         int ret;
     428                 :            : 
     429                 :          0 :         pname = getname(pathname);
     430         [ #  # ]:          0 :         if (IS_ERR(pname))
     431                 :          0 :                 return PTR_ERR(pname);
     432                 :            : 
     433                 :          0 :         raw = bpf_fd_probe_obj(ufd, &type);
     434         [ #  # ]:          0 :         if (IS_ERR(raw)) {
     435                 :            :                 ret = PTR_ERR(raw);
     436                 :          0 :                 goto out;
     437                 :            :         }
     438                 :            : 
     439                 :          0 :         ret = bpf_obj_do_pin(pname, raw, type);
     440         [ #  # ]:          0 :         if (ret != 0)
     441                 :          0 :                 bpf_any_put(raw, type);
     442                 :            : out:
     443                 :          0 :         putname(pname);
     444                 :          0 :         return ret;
     445                 :            : }
     446                 :            : 
     447                 :          0 : static void *bpf_obj_do_get(const struct filename *pathname,
     448                 :            :                             enum bpf_type *type, int flags)
     449                 :            : {
     450                 :            :         struct inode *inode;
     451                 :            :         struct path path;
     452                 :            :         void *raw;
     453                 :            :         int ret;
     454                 :            : 
     455                 :          0 :         ret = kern_path(pathname->name, LOOKUP_FOLLOW, &path);
     456         [ #  # ]:          0 :         if (ret)
     457                 :          0 :                 return ERR_PTR(ret);
     458                 :            : 
     459                 :          0 :         inode = d_backing_inode(path.dentry);
     460                 :          0 :         ret = inode_permission(inode, ACC_MODE(flags));
     461         [ #  # ]:          0 :         if (ret)
     462                 :            :                 goto out;
     463                 :            : 
     464                 :            :         ret = bpf_inode_type(inode, type);
     465         [ #  # ]:          0 :         if (ret)
     466                 :            :                 goto out;
     467                 :            : 
     468                 :          0 :         raw = bpf_any_get(inode->i_private, *type);
     469         [ #  # ]:          0 :         if (!IS_ERR(raw))
     470                 :          0 :                 touch_atime(&path);
     471                 :            : 
     472                 :          0 :         path_put(&path);
     473                 :          0 :         return raw;
     474                 :            : out:
     475                 :          0 :         path_put(&path);
     476                 :          0 :         return ERR_PTR(ret);
     477                 :            : }
     478                 :            : 
     479                 :          0 : int bpf_obj_get_user(const char __user *pathname, int flags)
     480                 :            : {
     481                 :          0 :         enum bpf_type type = BPF_TYPE_UNSPEC;
     482                 :            :         struct filename *pname;
     483                 :            :         int ret = -ENOENT;
     484                 :            :         int f_flags;
     485                 :            :         void *raw;
     486                 :            : 
     487                 :          0 :         f_flags = bpf_get_file_flag(flags);
     488         [ #  # ]:          0 :         if (f_flags < 0)
     489                 :            :                 return f_flags;
     490                 :            : 
     491                 :          0 :         pname = getname(pathname);
     492         [ #  # ]:          0 :         if (IS_ERR(pname))
     493                 :          0 :                 return PTR_ERR(pname);
     494                 :            : 
     495                 :          0 :         raw = bpf_obj_do_get(pname, &type, f_flags);
     496         [ #  # ]:          0 :         if (IS_ERR(raw)) {
     497                 :            :                 ret = PTR_ERR(raw);
     498                 :          0 :                 goto out;
     499                 :            :         }
     500                 :            : 
     501         [ #  # ]:          0 :         if (type == BPF_TYPE_PROG)
     502                 :          0 :                 ret = bpf_prog_new_fd(raw);
     503         [ #  # ]:          0 :         else if (type == BPF_TYPE_MAP)
     504                 :          0 :                 ret = bpf_map_new_fd(raw, f_flags);
     505                 :            :         else
     506                 :            :                 goto out;
     507                 :            : 
     508         [ #  # ]:          0 :         if (ret < 0)
     509                 :          0 :                 bpf_any_put(raw, type);
     510                 :            : out:
     511                 :          0 :         putname(pname);
     512                 :          0 :         return ret;
     513                 :            : }
     514                 :            : 
     515                 :          0 : static struct bpf_prog *__get_prog_inode(struct inode *inode, enum bpf_prog_type type)
     516                 :            : {
     517                 :            :         struct bpf_prog *prog;
     518                 :          0 :         int ret = inode_permission(inode, MAY_READ);
     519         [ #  # ]:          0 :         if (ret)
     520                 :          0 :                 return ERR_PTR(ret);
     521                 :            : 
     522         [ #  # ]:          0 :         if (inode->i_op == &bpf_map_iops)
     523                 :            :                 return ERR_PTR(-EINVAL);
     524         [ #  # ]:          0 :         if (inode->i_op != &bpf_prog_iops)
     525                 :            :                 return ERR_PTR(-EACCES);
     526                 :            : 
     527                 :          0 :         prog = inode->i_private;
     528                 :            : 
     529                 :          0 :         ret = security_bpf_prog(prog);
     530         [ #  # ]:          0 :         if (ret < 0)
     531                 :          0 :                 return ERR_PTR(ret);
     532                 :            : 
     533         [ #  # ]:          0 :         if (!bpf_prog_get_ok(prog, &type, false))
     534                 :            :                 return ERR_PTR(-EINVAL);
     535                 :            : 
     536                 :          0 :         return bpf_prog_inc(prog);
     537                 :            : }
     538                 :            : 
     539                 :          0 : struct bpf_prog *bpf_prog_get_type_path(const char *name, enum bpf_prog_type type)
     540                 :            : {
     541                 :            :         struct bpf_prog *prog;
     542                 :            :         struct path path;
     543                 :          0 :         int ret = kern_path(name, LOOKUP_FOLLOW, &path);
     544         [ #  # ]:          0 :         if (ret)
     545                 :          0 :                 return ERR_PTR(ret);
     546                 :          0 :         prog = __get_prog_inode(d_backing_inode(path.dentry), type);
     547         [ #  # ]:          0 :         if (!IS_ERR(prog))
     548                 :          0 :                 touch_atime(&path);
     549                 :          0 :         path_put(&path);
     550                 :          0 :         return prog;
     551                 :            : }
     552                 :            : EXPORT_SYMBOL(bpf_prog_get_type_path);
     553                 :            : 
     554                 :            : /*
     555                 :            :  * Display the mount options in /proc/mounts.
     556                 :            :  */
     557                 :      29000 : static int bpf_show_options(struct seq_file *m, struct dentry *root)
     558                 :            : {
     559                 :      29000 :         umode_t mode = d_inode(root)->i_mode & S_IALLUGO & ~S_ISVTX;
     560                 :            : 
     561         [ +  - ]:      29000 :         if (mode != S_IRWXUGO)
     562                 :      29000 :                 seq_printf(m, ",mode=%o", mode);
     563                 :      29000 :         return 0;
     564                 :            : }
     565                 :            : 
     566                 :          0 : static void bpf_free_inode(struct inode *inode)
     567                 :            : {
     568                 :            :         enum bpf_type type;
     569                 :            : 
     570         [ #  # ]:          0 :         if (S_ISLNK(inode->i_mode))
     571                 :          0 :                 kfree(inode->i_link);
     572         [ #  # ]:          0 :         if (!bpf_inode_type(inode, &type))
     573                 :          0 :                 bpf_any_put(inode->i_private, type);
     574                 :          0 :         free_inode_nonrcu(inode);
     575                 :          0 : }
     576                 :            : 
     577                 :            : static const struct super_operations bpf_super_ops = {
     578                 :            :         .statfs         = simple_statfs,
     579                 :            :         .drop_inode     = generic_delete_inode,
     580                 :            :         .show_options   = bpf_show_options,
     581                 :            :         .free_inode     = bpf_free_inode,
     582                 :            : };
     583                 :            : 
     584                 :            : enum {
     585                 :            :         OPT_MODE,
     586                 :            : };
     587                 :            : 
     588                 :            : static const struct fs_parameter_spec bpf_param_specs[] = {
     589                 :            :         fsparam_u32oct  ("mode",                      OPT_MODE),
     590                 :            :         {}
     591                 :            : };
     592                 :            : 
     593                 :            : static const struct fs_parameter_description bpf_fs_parameters = {
     594                 :            :         .name           = "bpf",
     595                 :            :         .specs          = bpf_param_specs,
     596                 :            : };
     597                 :            : 
     598                 :            : struct bpf_mount_opts {
     599                 :            :         umode_t mode;
     600                 :            : };
     601                 :            : 
     602                 :        414 : static int bpf_parse_param(struct fs_context *fc, struct fs_parameter *param)
     603                 :            : {
     604                 :        414 :         struct bpf_mount_opts *opts = fc->fs_private;
     605                 :            :         struct fs_parse_result result;
     606                 :            :         int opt;
     607                 :            : 
     608                 :        414 :         opt = fs_parse(fc, &bpf_fs_parameters, param, &result);
     609         [ +  + ]:        414 :         if (opt < 0)
     610                 :            :                 /* We might like to report bad mount options here, but
     611                 :            :                  * traditionally we've ignored all mount options, so we'd
     612                 :            :                  * better continue to ignore non-existing options for bpf.
     613                 :            :                  */
     614         [ -  + ]:        207 :                 return opt == -ENOPARAM ? 0 : opt;
     615                 :            : 
     616         [ +  - ]:        207 :         switch (opt) {
     617                 :            :         case OPT_MODE:
     618                 :        207 :                 opts->mode = result.uint_32 & S_IALLUGO;
     619                 :        207 :                 break;
     620                 :            :         }
     621                 :            : 
     622                 :            :         return 0;
     623                 :            : }
     624                 :            : 
     625                 :        207 : static int bpf_fill_super(struct super_block *sb, struct fs_context *fc)
     626                 :            : {
     627                 :            :         static const struct tree_descr bpf_rfiles[] = { { "" } };
     628                 :        207 :         struct bpf_mount_opts *opts = fc->fs_private;
     629                 :            :         struct inode *inode;
     630                 :            :         int ret;
     631                 :            : 
     632                 :        207 :         ret = simple_fill_super(sb, BPF_FS_MAGIC, bpf_rfiles);
     633         [ +  - ]:        207 :         if (ret)
     634                 :            :                 return ret;
     635                 :            : 
     636                 :        207 :         sb->s_op = &bpf_super_ops;
     637                 :            : 
     638                 :        207 :         inode = sb->s_root->d_inode;
     639                 :        207 :         inode->i_op = &bpf_dir_iops;
     640                 :        207 :         inode->i_mode &= ~S_IALLUGO;
     641                 :        207 :         inode->i_mode |= S_ISVTX | opts->mode;
     642                 :            : 
     643                 :        207 :         return 0;
     644                 :            : }
     645                 :            : 
     646                 :        207 : static int bpf_get_tree(struct fs_context *fc)
     647                 :            : {
     648                 :        207 :         return get_tree_nodev(fc, bpf_fill_super);
     649                 :            : }
     650                 :            : 
     651                 :        207 : static void bpf_free_fc(struct fs_context *fc)
     652                 :            : {
     653                 :        207 :         kfree(fc->fs_private);
     654                 :        207 : }
     655                 :            : 
     656                 :            : static const struct fs_context_operations bpf_context_ops = {
     657                 :            :         .free           = bpf_free_fc,
     658                 :            :         .parse_param    = bpf_parse_param,
     659                 :            :         .get_tree       = bpf_get_tree,
     660                 :            : };
     661                 :            : 
     662                 :            : /*
     663                 :            :  * Set up the filesystem mount context.
     664                 :            :  */
     665                 :        207 : static int bpf_init_fs_context(struct fs_context *fc)
     666                 :            : {
     667                 :            :         struct bpf_mount_opts *opts;
     668                 :            : 
     669                 :        207 :         opts = kzalloc(sizeof(struct bpf_mount_opts), GFP_KERNEL);
     670         [ +  - ]:        207 :         if (!opts)
     671                 :            :                 return -ENOMEM;
     672                 :            : 
     673                 :        207 :         opts->mode = S_IRWXUGO;
     674                 :            : 
     675                 :        207 :         fc->fs_private = opts;
     676                 :        207 :         fc->ops = &bpf_context_ops;
     677                 :        207 :         return 0;
     678                 :            : }
     679                 :            : 
     680                 :            : static struct file_system_type bpf_fs_type = {
     681                 :            :         .owner          = THIS_MODULE,
     682                 :            :         .name           = "bpf",
     683                 :            :         .init_fs_context = bpf_init_fs_context,
     684                 :            :         .parameters     = &bpf_fs_parameters,
     685                 :            :         .kill_sb        = kill_litter_super,
     686                 :            : };
     687                 :            : 
     688                 :        207 : static int __init bpf_init(void)
     689                 :            : {
     690                 :            :         int ret;
     691                 :            : 
     692                 :        207 :         ret = sysfs_create_mount_point(fs_kobj, "bpf");
     693         [ +  - ]:        207 :         if (ret)
     694                 :            :                 return ret;
     695                 :            : 
     696                 :        207 :         ret = register_filesystem(&bpf_fs_type);
     697         [ -  + ]:        207 :         if (ret)
     698                 :          0 :                 sysfs_remove_mount_point(fs_kobj, "bpf");
     699                 :            : 
     700                 :        207 :         return ret;
     701                 :            : }
     702                 :            : fs_initcall(bpf_init);

Generated by: LCOV version 1.14