LCOV - code coverage report
Current view: top level - security/apparmor - apparmorfs.c (source / functions) Hit Total Coverage
Test: Real Lines: 2 820 0.2 %
Date: 2020-10-17 15:46:43 Functions: 0 98 0.0 %
Legend: Neither, QEMU, Real, Both Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-only
       2                 :            : /*
       3                 :            :  * AppArmor security module
       4                 :            :  *
       5                 :            :  * This file contains AppArmor /sys/kernel/security/apparmor interface functions
       6                 :            :  *
       7                 :            :  * Copyright (C) 1998-2008 Novell/SUSE
       8                 :            :  * Copyright 2009-2010 Canonical Ltd.
       9                 :            :  */
      10                 :            : 
      11                 :            : #include <linux/ctype.h>
      12                 :            : #include <linux/security.h>
      13                 :            : #include <linux/vmalloc.h>
      14                 :            : #include <linux/init.h>
      15                 :            : #include <linux/seq_file.h>
      16                 :            : #include <linux/uaccess.h>
      17                 :            : #include <linux/mount.h>
      18                 :            : #include <linux/namei.h>
      19                 :            : #include <linux/capability.h>
      20                 :            : #include <linux/rcupdate.h>
      21                 :            : #include <linux/fs.h>
      22                 :            : #include <linux/fs_context.h>
      23                 :            : #include <linux/poll.h>
      24                 :            : #include <uapi/linux/major.h>
      25                 :            : #include <uapi/linux/magic.h>
      26                 :            : 
      27                 :            : #include "include/apparmor.h"
      28                 :            : #include "include/apparmorfs.h"
      29                 :            : #include "include/audit.h"
      30                 :            : #include "include/cred.h"
      31                 :            : #include "include/crypto.h"
      32                 :            : #include "include/ipc.h"
      33                 :            : #include "include/label.h"
      34                 :            : #include "include/policy.h"
      35                 :            : #include "include/policy_ns.h"
      36                 :            : #include "include/resource.h"
      37                 :            : #include "include/policy_unpack.h"
      38                 :            : 
      39                 :            : /*
      40                 :            :  * The apparmor filesystem interface used for policy load and introspection
      41                 :            :  * The interface is split into two main components based on their function
      42                 :            :  * a securityfs component:
      43                 :            :  *   used for static files that are always available, and which allows
      44                 :            :  *   userspace to specificy the location of the security filesystem.
      45                 :            :  *
      46                 :            :  *   fns and data are prefixed with
      47                 :            :  *      aa_sfs_
      48                 :            :  *
      49                 :            :  * an apparmorfs component:
      50                 :            :  *   used loaded policy content and introspection. It is not part of  a
      51                 :            :  *   regular mounted filesystem and is available only through the magic
      52                 :            :  *   policy symlink in the root of the securityfs apparmor/ directory.
      53                 :            :  *   Tasks queries will be magically redirected to the correct portion
      54                 :            :  *   of the policy tree based on their confinement.
      55                 :            :  *
      56                 :            :  *   fns and data are prefixed with
      57                 :            :  *      aafs_
      58                 :            :  *
      59                 :            :  * The aa_fs_ prefix is used to indicate the fn is used by both the
      60                 :            :  * securityfs and apparmorfs filesystems.
      61                 :            :  */
      62                 :            : 
      63                 :            : 
      64                 :            : /*
      65                 :            :  * support fns
      66                 :            :  */
      67                 :            : 
      68                 :            : /**
      69                 :            :  * aa_mangle_name - mangle a profile name to std profile layout form
      70                 :            :  * @name: profile name to mangle  (NOT NULL)
      71                 :            :  * @target: buffer to store mangled name, same length as @name (MAYBE NULL)
      72                 :            :  *
      73                 :            :  * Returns: length of mangled name
      74                 :            :  */
      75                 :          0 : static int mangle_name(const char *name, char *target)
      76                 :            : {
      77                 :            :         char *t = target;
      78                 :            : 
      79                 :          0 :         while (*name == '/' || *name == '.')
      80                 :          0 :                 name++;
      81                 :            : 
      82                 :          0 :         if (target) {
      83                 :          0 :                 for (; *name; name++) {
      84                 :          0 :                         if (*name == '/')
      85                 :          0 :                                 *(t)++ = '.';
      86                 :          0 :                         else if (isspace(*name))
      87                 :          0 :                                 *(t)++ = '_';
      88                 :          0 :                         else if (isalnum(*name) || strchr("._-", *name))
      89                 :          0 :                                 *(t)++ = *name;
      90                 :            :                 }
      91                 :            : 
      92                 :          0 :                 *t = 0;
      93                 :            :         } else {
      94                 :            :                 int len = 0;
      95                 :          0 :                 for (; *name; name++) {
      96                 :          0 :                         if (isalnum(*name) || isspace(*name) ||
      97                 :          0 :                             strchr("/._-", *name))
      98                 :          0 :                                 len++;
      99                 :            :                 }
     100                 :            : 
     101                 :          0 :                 return len;
     102                 :            :         }
     103                 :            : 
     104                 :          0 :         return t - target;
     105                 :            : }
     106                 :            : 
     107                 :            : 
     108                 :            : /*
     109                 :            :  * aafs - core fns and data for the policy tree
     110                 :            :  */
     111                 :            : 
     112                 :            : #define AAFS_NAME               "apparmorfs"
     113                 :            : static struct vfsmount *aafs_mnt;
     114                 :            : static int aafs_count;
     115                 :            : 
     116                 :            : 
     117                 :          0 : static int aafs_show_path(struct seq_file *seq, struct dentry *dentry)
     118                 :            : {
     119                 :          0 :         seq_printf(seq, "%s:[%lu]", AAFS_NAME, d_inode(dentry)->i_ino);
     120                 :          0 :         return 0;
     121                 :            : }
     122                 :            : 
     123                 :          0 : static void aafs_free_inode(struct inode *inode)
     124                 :            : {
     125                 :          0 :         if (S_ISLNK(inode->i_mode))
     126                 :          0 :                 kfree(inode->i_link);
     127                 :          0 :         free_inode_nonrcu(inode);
     128                 :          0 : }
     129                 :            : 
     130                 :            : static const struct super_operations aafs_super_ops = {
     131                 :            :         .statfs = simple_statfs,
     132                 :            :         .free_inode = aafs_free_inode,
     133                 :            :         .show_path = aafs_show_path,
     134                 :            : };
     135                 :            : 
     136                 :          0 : static int apparmorfs_fill_super(struct super_block *sb, struct fs_context *fc)
     137                 :            : {
     138                 :            :         static struct tree_descr files[] = { {""} };
     139                 :            :         int error;
     140                 :            : 
     141                 :          0 :         error = simple_fill_super(sb, AAFS_MAGIC, files);
     142                 :          0 :         if (error)
     143                 :            :                 return error;
     144                 :          0 :         sb->s_op = &aafs_super_ops;
     145                 :            : 
     146                 :          0 :         return 0;
     147                 :            : }
     148                 :            : 
     149                 :          0 : static int apparmorfs_get_tree(struct fs_context *fc)
     150                 :            : {
     151                 :          0 :         return get_tree_single(fc, apparmorfs_fill_super);
     152                 :            : }
     153                 :            : 
     154                 :            : static const struct fs_context_operations apparmorfs_context_ops = {
     155                 :            :         .get_tree       = apparmorfs_get_tree,
     156                 :            : };
     157                 :            : 
     158                 :          0 : static int apparmorfs_init_fs_context(struct fs_context *fc)
     159                 :            : {
     160                 :          0 :         fc->ops = &apparmorfs_context_ops;
     161                 :          0 :         return 0;
     162                 :            : }
     163                 :            : 
     164                 :            : static struct file_system_type aafs_ops = {
     165                 :            :         .owner = THIS_MODULE,
     166                 :            :         .name = AAFS_NAME,
     167                 :            :         .init_fs_context = apparmorfs_init_fs_context,
     168                 :            :         .kill_sb = kill_anon_super,
     169                 :            : };
     170                 :            : 
     171                 :            : /**
     172                 :            :  * __aafs_setup_d_inode - basic inode setup for apparmorfs
     173                 :            :  * @dir: parent directory for the dentry
     174                 :            :  * @dentry: dentry we are seting the inode up for
     175                 :            :  * @mode: permissions the file should have
     176                 :            :  * @data: data to store on inode.i_private, available in open()
     177                 :            :  * @link: if symlink, symlink target string
     178                 :            :  * @fops: struct file_operations that should be used
     179                 :            :  * @iops: struct of inode_operations that should be used
     180                 :            :  */
     181                 :          0 : static int __aafs_setup_d_inode(struct inode *dir, struct dentry *dentry,
     182                 :            :                                umode_t mode, void *data, char *link,
     183                 :            :                                const struct file_operations *fops,
     184                 :            :                                const struct inode_operations *iops)
     185                 :            : {
     186                 :          0 :         struct inode *inode = new_inode(dir->i_sb);
     187                 :            : 
     188                 :            :         AA_BUG(!dir);
     189                 :            :         AA_BUG(!dentry);
     190                 :            : 
     191                 :          0 :         if (!inode)
     192                 :            :                 return -ENOMEM;
     193                 :            : 
     194                 :          0 :         inode->i_ino = get_next_ino();
     195                 :          0 :         inode->i_mode = mode;
     196                 :          0 :         inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
     197                 :          0 :         inode->i_private = data;
     198                 :          0 :         if (S_ISDIR(mode)) {
     199                 :          0 :                 inode->i_op = iops ? iops : &simple_dir_inode_operations;
     200                 :          0 :                 inode->i_fop = &simple_dir_operations;
     201                 :          0 :                 inc_nlink(inode);
     202                 :          0 :                 inc_nlink(dir);
     203                 :          0 :         } else if (S_ISLNK(mode)) {
     204                 :          0 :                 inode->i_op = iops ? iops : &simple_symlink_inode_operations;
     205                 :          0 :                 inode->i_link = link;
     206                 :            :         } else {
     207                 :          0 :                 inode->i_fop = fops;
     208                 :            :         }
     209                 :          0 :         d_instantiate(dentry, inode);
     210                 :            :         dget(dentry);
     211                 :            : 
     212                 :            :         return 0;
     213                 :            : }
     214                 :            : 
     215                 :            : /**
     216                 :            :  * aafs_create - create a dentry in the apparmorfs filesystem
     217                 :            :  *
     218                 :            :  * @name: name of dentry to create
     219                 :            :  * @mode: permissions the file should have
     220                 :            :  * @parent: parent directory for this dentry
     221                 :            :  * @data: data to store on inode.i_private, available in open()
     222                 :            :  * @link: if symlink, symlink target string
     223                 :            :  * @fops: struct file_operations that should be used for
     224                 :            :  * @iops: struct of inode_operations that should be used
     225                 :            :  *
     226                 :            :  * This is the basic "create a xxx" function for apparmorfs.
     227                 :            :  *
     228                 :            :  * Returns a pointer to a dentry if it succeeds, that must be free with
     229                 :            :  * aafs_remove(). Will return ERR_PTR on failure.
     230                 :            :  */
     231                 :          0 : static struct dentry *aafs_create(const char *name, umode_t mode,
     232                 :            :                                   struct dentry *parent, void *data, void *link,
     233                 :            :                                   const struct file_operations *fops,
     234                 :            :                                   const struct inode_operations *iops)
     235                 :            : {
     236                 :            :         struct dentry *dentry;
     237                 :            :         struct inode *dir;
     238                 :            :         int error;
     239                 :            : 
     240                 :            :         AA_BUG(!name);
     241                 :            :         AA_BUG(!parent);
     242                 :            : 
     243                 :          0 :         if (!(mode & S_IFMT))
     244                 :          0 :                 mode = (mode & S_IALLUGO) | S_IFREG;
     245                 :            : 
     246                 :          0 :         error = simple_pin_fs(&aafs_ops, &aafs_mnt, &aafs_count);
     247                 :          0 :         if (error)
     248                 :          0 :                 return ERR_PTR(error);
     249                 :            : 
     250                 :            :         dir = d_inode(parent);
     251                 :            : 
     252                 :            :         inode_lock(dir);
     253                 :          0 :         dentry = lookup_one_len(name, parent, strlen(name));
     254                 :          0 :         if (IS_ERR(dentry)) {
     255                 :            :                 error = PTR_ERR(dentry);
     256                 :          0 :                 goto fail_lock;
     257                 :            :         }
     258                 :            : 
     259                 :          0 :         if (d_really_is_positive(dentry)) {
     260                 :            :                 error = -EEXIST;
     261                 :            :                 goto fail_dentry;
     262                 :            :         }
     263                 :            : 
     264                 :          0 :         error = __aafs_setup_d_inode(dir, dentry, mode, data, link, fops, iops);
     265                 :          0 :         if (error)
     266                 :            :                 goto fail_dentry;
     267                 :            :         inode_unlock(dir);
     268                 :            : 
     269                 :          0 :         return dentry;
     270                 :            : 
     271                 :            : fail_dentry:
     272                 :          0 :         dput(dentry);
     273                 :            : 
     274                 :            : fail_lock:
     275                 :            :         inode_unlock(dir);
     276                 :          0 :         simple_release_fs(&aafs_mnt, &aafs_count);
     277                 :            : 
     278                 :          0 :         return ERR_PTR(error);
     279                 :            : }
     280                 :            : 
     281                 :            : /**
     282                 :            :  * aafs_create_file - create a file in the apparmorfs filesystem
     283                 :            :  *
     284                 :            :  * @name: name of dentry to create
     285                 :            :  * @mode: permissions the file should have
     286                 :            :  * @parent: parent directory for this dentry
     287                 :            :  * @data: data to store on inode.i_private, available in open()
     288                 :            :  * @fops: struct file_operations that should be used for
     289                 :            :  *
     290                 :            :  * see aafs_create
     291                 :            :  */
     292                 :            : static struct dentry *aafs_create_file(const char *name, umode_t mode,
     293                 :            :                                        struct dentry *parent, void *data,
     294                 :            :                                        const struct file_operations *fops)
     295                 :            : {
     296                 :          0 :         return aafs_create(name, mode, parent, data, NULL, fops, NULL);
     297                 :            : }
     298                 :            : 
     299                 :            : /**
     300                 :            :  * aafs_create_dir - create a directory in the apparmorfs filesystem
     301                 :            :  *
     302                 :            :  * @name: name of dentry to create
     303                 :            :  * @parent: parent directory for this dentry
     304                 :            :  *
     305                 :            :  * see aafs_create
     306                 :            :  */
     307                 :            : static struct dentry *aafs_create_dir(const char *name, struct dentry *parent)
     308                 :            : {
     309                 :          0 :         return aafs_create(name, S_IFDIR | 0755, parent, NULL, NULL, NULL,
     310                 :            :                            NULL);
     311                 :            : }
     312                 :            : 
     313                 :            : /**
     314                 :            :  * aafs_create_symlink - create a symlink in the apparmorfs filesystem
     315                 :            :  * @name: name of dentry to create
     316                 :            :  * @parent: parent directory for this dentry
     317                 :            :  * @target: if symlink, symlink target string
     318                 :            :  * @private: private data
     319                 :            :  * @iops: struct of inode_operations that should be used
     320                 :            :  *
     321                 :            :  * If @target parameter is %NULL, then the @iops parameter needs to be
     322                 :            :  * setup to handle .readlink and .get_link inode_operations.
     323                 :            :  */
     324                 :          0 : static struct dentry *aafs_create_symlink(const char *name,
     325                 :            :                                           struct dentry *parent,
     326                 :            :                                           const char *target,
     327                 :            :                                           void *private,
     328                 :            :                                           const struct inode_operations *iops)
     329                 :            : {
     330                 :            :         struct dentry *dent;
     331                 :            :         char *link = NULL;
     332                 :            : 
     333                 :          0 :         if (target) {
     334                 :            :                 if (!link)
     335                 :            :                         return ERR_PTR(-ENOMEM);
     336                 :            :         }
     337                 :          0 :         dent = aafs_create(name, S_IFLNK | 0444, parent, private, link, NULL,
     338                 :            :                            iops);
     339                 :          0 :         if (IS_ERR(dent))
     340                 :          0 :                 kfree(link);
     341                 :            : 
     342                 :          0 :         return dent;
     343                 :            : }
     344                 :            : 
     345                 :            : /**
     346                 :            :  * aafs_remove - removes a file or directory from the apparmorfs filesystem
     347                 :            :  *
     348                 :            :  * @dentry: dentry of the file/directory/symlink to removed.
     349                 :            :  */
     350                 :          0 : static void aafs_remove(struct dentry *dentry)
     351                 :            : {
     352                 :            :         struct inode *dir;
     353                 :            : 
     354                 :          0 :         if (!dentry || IS_ERR(dentry))
     355                 :          0 :                 return;
     356                 :            : 
     357                 :          0 :         dir = d_inode(dentry->d_parent);
     358                 :            :         inode_lock(dir);
     359                 :          0 :         if (simple_positive(dentry)) {
     360                 :          0 :                 if (d_is_dir(dentry))
     361                 :          0 :                         simple_rmdir(dir, dentry);
     362                 :            :                 else
     363                 :          0 :                         simple_unlink(dir, dentry);
     364                 :          0 :                 d_delete(dentry);
     365                 :          0 :                 dput(dentry);
     366                 :            :         }
     367                 :            :         inode_unlock(dir);
     368                 :          0 :         simple_release_fs(&aafs_mnt, &aafs_count);
     369                 :            : }
     370                 :            : 
     371                 :            : 
     372                 :            : /*
     373                 :            :  * aa_fs - policy load/replace/remove
     374                 :            :  */
     375                 :            : 
     376                 :            : /**
     377                 :            :  * aa_simple_write_to_buffer - common routine for getting policy from user
     378                 :            :  * @userbuf: user buffer to copy data from  (NOT NULL)
     379                 :            :  * @alloc_size: size of user buffer (REQUIRES: @alloc_size >= @copy_size)
     380                 :            :  * @copy_size: size of data to copy from user buffer
     381                 :            :  * @pos: position write is at in the file (NOT NULL)
     382                 :            :  *
     383                 :            :  * Returns: kernel buffer containing copy of user buffer data or an
     384                 :            :  *          ERR_PTR on failure.
     385                 :            :  */
     386                 :          0 : static struct aa_loaddata *aa_simple_write_to_buffer(const char __user *userbuf,
     387                 :            :                                                      size_t alloc_size,
     388                 :            :                                                      size_t copy_size,
     389                 :            :                                                      loff_t *pos)
     390                 :            : {
     391                 :            :         struct aa_loaddata *data;
     392                 :            : 
     393                 :            :         AA_BUG(copy_size > alloc_size);
     394                 :            : 
     395                 :          0 :         if (*pos != 0)
     396                 :            :                 /* only writes from pos 0, that is complete writes */
     397                 :            :                 return ERR_PTR(-ESPIPE);
     398                 :            : 
     399                 :            :         /* freed by caller to simple_write_to_buffer */
     400                 :          0 :         data = aa_loaddata_alloc(alloc_size);
     401                 :          0 :         if (IS_ERR(data))
     402                 :            :                 return data;
     403                 :            : 
     404                 :          0 :         data->size = copy_size;
     405                 :          0 :         if (copy_from_user(data->data, userbuf, copy_size)) {
     406                 :          0 :                 kvfree(data);
     407                 :          0 :                 return ERR_PTR(-EFAULT);
     408                 :            :         }
     409                 :            : 
     410                 :            :         return data;
     411                 :            : }
     412                 :            : 
     413                 :          0 : static ssize_t policy_update(u32 mask, const char __user *buf, size_t size,
     414                 :            :                              loff_t *pos, struct aa_ns *ns)
     415                 :            : {
     416                 :            :         struct aa_loaddata *data;
     417                 :            :         struct aa_label *label;
     418                 :            :         ssize_t error;
     419                 :            : 
     420                 :          0 :         label = begin_current_label_crit_section();
     421                 :            : 
     422                 :            :         /* high level check about policy management - fine grained in
     423                 :            :          * below after unpack
     424                 :            :          */
     425                 :          0 :         error = aa_may_manage_policy(label, ns, mask);
     426                 :          0 :         if (error)
     427                 :            :                 goto end_section;
     428                 :            : 
     429                 :          0 :         data = aa_simple_write_to_buffer(buf, size, size, pos);
     430                 :            :         error = PTR_ERR(data);
     431                 :          0 :         if (!IS_ERR(data)) {
     432                 :          0 :                 error = aa_replace_profiles(ns, label, mask, data);
     433                 :            :                 aa_put_loaddata(data);
     434                 :            :         }
     435                 :            : end_section:
     436                 :          0 :         end_current_label_crit_section(label);
     437                 :            : 
     438                 :          0 :         return error;
     439                 :            : }
     440                 :            : 
     441                 :            : /* .load file hook fn to load policy */
     442                 :          0 : static ssize_t profile_load(struct file *f, const char __user *buf, size_t size,
     443                 :            :                             loff_t *pos)
     444                 :            : {
     445                 :          0 :         struct aa_ns *ns = aa_get_ns(f->f_inode->i_private);
     446                 :          0 :         int error = policy_update(AA_MAY_LOAD_POLICY, buf, size, pos, ns);
     447                 :            : 
     448                 :          0 :         aa_put_ns(ns);
     449                 :            : 
     450                 :          0 :         return error;
     451                 :            : }
     452                 :            : 
     453                 :            : static const struct file_operations aa_fs_profile_load = {
     454                 :            :         .write = profile_load,
     455                 :            :         .llseek = default_llseek,
     456                 :            : };
     457                 :            : 
     458                 :            : /* .replace file hook fn to load and/or replace policy */
     459                 :          0 : static ssize_t profile_replace(struct file *f, const char __user *buf,
     460                 :            :                                size_t size, loff_t *pos)
     461                 :            : {
     462                 :          0 :         struct aa_ns *ns = aa_get_ns(f->f_inode->i_private);
     463                 :          0 :         int error = policy_update(AA_MAY_LOAD_POLICY | AA_MAY_REPLACE_POLICY,
     464                 :            :                                   buf, size, pos, ns);
     465                 :          0 :         aa_put_ns(ns);
     466                 :            : 
     467                 :          0 :         return error;
     468                 :            : }
     469                 :            : 
     470                 :            : static const struct file_operations aa_fs_profile_replace = {
     471                 :            :         .write = profile_replace,
     472                 :            :         .llseek = default_llseek,
     473                 :            : };
     474                 :            : 
     475                 :            : /* .remove file hook fn to remove loaded policy */
     476                 :          0 : static ssize_t profile_remove(struct file *f, const char __user *buf,
     477                 :            :                               size_t size, loff_t *pos)
     478                 :            : {
     479                 :            :         struct aa_loaddata *data;
     480                 :            :         struct aa_label *label;
     481                 :            :         ssize_t error;
     482                 :          0 :         struct aa_ns *ns = aa_get_ns(f->f_inode->i_private);
     483                 :            : 
     484                 :          0 :         label = begin_current_label_crit_section();
     485                 :            :         /* high level check about policy management - fine grained in
     486                 :            :          * below after unpack
     487                 :            :          */
     488                 :          0 :         error = aa_may_manage_policy(label, ns, AA_MAY_REMOVE_POLICY);
     489                 :          0 :         if (error)
     490                 :            :                 goto out;
     491                 :            : 
     492                 :            :         /*
     493                 :            :          * aa_remove_profile needs a null terminated string so 1 extra
     494                 :            :          * byte is allocated and the copied data is null terminated.
     495                 :            :          */
     496                 :          0 :         data = aa_simple_write_to_buffer(buf, size + 1, size, pos);
     497                 :            : 
     498                 :            :         error = PTR_ERR(data);
     499                 :          0 :         if (!IS_ERR(data)) {
     500                 :          0 :                 data->data[size] = 0;
     501                 :          0 :                 error = aa_remove_profiles(ns, label, data->data, size);
     502                 :            :                 aa_put_loaddata(data);
     503                 :            :         }
     504                 :            :  out:
     505                 :          0 :         end_current_label_crit_section(label);
     506                 :          0 :         aa_put_ns(ns);
     507                 :          0 :         return error;
     508                 :            : }
     509                 :            : 
     510                 :            : static const struct file_operations aa_fs_profile_remove = {
     511                 :            :         .write = profile_remove,
     512                 :            :         .llseek = default_llseek,
     513                 :            : };
     514                 :            : 
     515                 :            : struct aa_revision {
     516                 :            :         struct aa_ns *ns;
     517                 :            :         long last_read;
     518                 :            : };
     519                 :            : 
     520                 :            : /* revision file hook fn for policy loads */
     521                 :          0 : static int ns_revision_release(struct inode *inode, struct file *file)
     522                 :            : {
     523                 :          0 :         struct aa_revision *rev = file->private_data;
     524                 :            : 
     525                 :          0 :         if (rev) {
     526                 :          0 :                 aa_put_ns(rev->ns);
     527                 :          0 :                 kfree(rev);
     528                 :            :         }
     529                 :            : 
     530                 :          0 :         return 0;
     531                 :            : }
     532                 :            : 
     533                 :          0 : static ssize_t ns_revision_read(struct file *file, char __user *buf,
     534                 :            :                                 size_t size, loff_t *ppos)
     535                 :            : {
     536                 :          0 :         struct aa_revision *rev = file->private_data;
     537                 :            :         char buffer[32];
     538                 :            :         long last_read;
     539                 :            :         int avail;
     540                 :            : 
     541                 :          0 :         mutex_lock_nested(&rev->ns->lock, rev->ns->level);
     542                 :          0 :         last_read = rev->last_read;
     543                 :          0 :         if (last_read == rev->ns->revision) {
     544                 :          0 :                 mutex_unlock(&rev->ns->lock);
     545                 :          0 :                 if (file->f_flags & O_NONBLOCK)
     546                 :            :                         return -EAGAIN;
     547                 :          0 :                 if (wait_event_interruptible(rev->ns->wait,
     548                 :            :                                              last_read !=
     549                 :            :                                              READ_ONCE(rev->ns->revision)))
     550                 :            :                         return -ERESTARTSYS;
     551                 :          0 :                 mutex_lock_nested(&rev->ns->lock, rev->ns->level);
     552                 :            :         }
     553                 :            : 
     554                 :          0 :         avail = sprintf(buffer, "%ld\n", rev->ns->revision);
     555                 :          0 :         if (*ppos + size > avail) {
     556                 :          0 :                 rev->last_read = rev->ns->revision;
     557                 :          0 :                 *ppos = 0;
     558                 :            :         }
     559                 :          0 :         mutex_unlock(&rev->ns->lock);
     560                 :            : 
     561                 :          0 :         return simple_read_from_buffer(buf, size, ppos, buffer, avail);
     562                 :            : }
     563                 :            : 
     564                 :          0 : static int ns_revision_open(struct inode *inode, struct file *file)
     565                 :            : {
     566                 :          0 :         struct aa_revision *rev = kzalloc(sizeof(*rev), GFP_KERNEL);
     567                 :            : 
     568                 :          0 :         if (!rev)
     569                 :            :                 return -ENOMEM;
     570                 :            : 
     571                 :          0 :         rev->ns = aa_get_ns(inode->i_private);
     572                 :          0 :         if (!rev->ns)
     573                 :          0 :                 rev->ns = aa_get_current_ns();
     574                 :          0 :         file->private_data = rev;
     575                 :            : 
     576                 :          0 :         return 0;
     577                 :            : }
     578                 :            : 
     579                 :          0 : static __poll_t ns_revision_poll(struct file *file, poll_table *pt)
     580                 :            : {
     581                 :          0 :         struct aa_revision *rev = file->private_data;
     582                 :            :         __poll_t mask = 0;
     583                 :            : 
     584                 :          0 :         if (rev) {
     585                 :          0 :                 mutex_lock_nested(&rev->ns->lock, rev->ns->level);
     586                 :          0 :                 poll_wait(file, &rev->ns->wait, pt);
     587                 :          0 :                 if (rev->last_read < rev->ns->revision)
     588                 :            :                         mask |= EPOLLIN | EPOLLRDNORM;
     589                 :          0 :                 mutex_unlock(&rev->ns->lock);
     590                 :            :         }
     591                 :            : 
     592                 :          0 :         return mask;
     593                 :            : }
     594                 :            : 
     595                 :          0 : void __aa_bump_ns_revision(struct aa_ns *ns)
     596                 :            : {
     597                 :          0 :         WRITE_ONCE(ns->revision, ns->revision + 1);
     598                 :          0 :         wake_up_interruptible(&ns->wait);
     599                 :          0 : }
     600                 :            : 
     601                 :            : static const struct file_operations aa_fs_ns_revision_fops = {
     602                 :            :         .owner          = THIS_MODULE,
     603                 :            :         .open           = ns_revision_open,
     604                 :            :         .poll           = ns_revision_poll,
     605                 :            :         .read           = ns_revision_read,
     606                 :            :         .llseek         = generic_file_llseek,
     607                 :            :         .release        = ns_revision_release,
     608                 :            : };
     609                 :            : 
     610                 :          0 : static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
     611                 :            :                              const char *match_str, size_t match_len)
     612                 :            : {
     613                 :          0 :         struct aa_perms tmp = { };
     614                 :            :         struct aa_dfa *dfa;
     615                 :            :         unsigned int state = 0;
     616                 :            : 
     617                 :          0 :         if (profile_unconfined(profile))
     618                 :          0 :                 return;
     619                 :          0 :         if (profile->file.dfa && *match_str == AA_CLASS_FILE) {
     620                 :            :                 dfa = profile->file.dfa;
     621                 :          0 :                 state = aa_dfa_match_len(dfa, profile->file.start,
     622                 :          0 :                                          match_str + 1, match_len - 1);
     623                 :          0 :                 if (state) {
     624                 :          0 :                         struct path_cond cond = { };
     625                 :            : 
     626                 :          0 :                         tmp = aa_compute_fperms(dfa, state, &cond);
     627                 :            :                 }
     628                 :          0 :         } else if (profile->policy.dfa) {
     629                 :          0 :                 if (!PROFILE_MEDIATES(profile, *match_str))
     630                 :            :                         return; /* no change to current perms */
     631                 :          0 :                 dfa = profile->policy.dfa;
     632                 :          0 :                 state = aa_dfa_match_len(dfa, profile->policy.start[0],
     633                 :            :                                          match_str, match_len);
     634                 :          0 :                 if (state)
     635                 :          0 :                         aa_compute_perms(dfa, state, &tmp);
     636                 :            :         }
     637                 :          0 :         aa_apply_modes_to_perms(profile, &tmp);
     638                 :          0 :         aa_perms_accum_raw(perms, &tmp);
     639                 :            : }
     640                 :            : 
     641                 :            : 
     642                 :            : /**
     643                 :            :  * query_data - queries a policy and writes its data to buf
     644                 :            :  * @buf: the resulting data is stored here (NOT NULL)
     645                 :            :  * @buf_len: size of buf
     646                 :            :  * @query: query string used to retrieve data
     647                 :            :  * @query_len: size of query including second NUL byte
     648                 :            :  *
     649                 :            :  * The buffers pointed to by buf and query may overlap. The query buffer is
     650                 :            :  * parsed before buf is written to.
     651                 :            :  *
     652                 :            :  * The query should look like "<LABEL>\0<KEY>\0", where <LABEL> is the name of
     653                 :            :  * the security confinement context and <KEY> is the name of the data to
     654                 :            :  * retrieve. <LABEL> and <KEY> must not be NUL-terminated.
     655                 :            :  *
     656                 :            :  * Don't expect the contents of buf to be preserved on failure.
     657                 :            :  *
     658                 :            :  * Returns: number of characters written to buf or -errno on failure
     659                 :            :  */
     660                 :          0 : static ssize_t query_data(char *buf, size_t buf_len,
     661                 :            :                           char *query, size_t query_len)
     662                 :            : {
     663                 :            :         char *out;
     664                 :            :         const char *key;
     665                 :            :         struct label_it i;
     666                 :            :         struct aa_label *label, *curr;
     667                 :            :         struct aa_profile *profile;
     668                 :            :         struct aa_data *data;
     669                 :            :         u32 bytes, blocks;
     670                 :            :         __le32 outle32;
     671                 :            : 
     672                 :          0 :         if (!query_len)
     673                 :            :                 return -EINVAL; /* need a query */
     674                 :            : 
     675                 :          0 :         key = query + strnlen(query, query_len) + 1;
     676                 :          0 :         if (key + 1 >= query + query_len)
     677                 :            :                 return -EINVAL; /* not enough space for a non-empty key */
     678                 :          0 :         if (key + strnlen(key, query + query_len - key) >= query + query_len)
     679                 :            :                 return -EINVAL; /* must end with NUL */
     680                 :            : 
     681                 :          0 :         if (buf_len < sizeof(bytes) + sizeof(blocks))
     682                 :            :                 return -EINVAL; /* not enough space */
     683                 :            : 
     684                 :          0 :         curr = begin_current_label_crit_section();
     685                 :          0 :         label = aa_label_parse(curr, query, GFP_KERNEL, false, false);
     686                 :          0 :         end_current_label_crit_section(curr);
     687                 :          0 :         if (IS_ERR(label))
     688                 :          0 :                 return PTR_ERR(label);
     689                 :            : 
     690                 :            :         /* We are going to leave space for two numbers. The first is the total
     691                 :            :          * number of bytes we are writing after the first number. This is so
     692                 :            :          * users can read the full output without reallocation.
     693                 :            :          *
     694                 :            :          * The second number is the number of data blocks we're writing. An
     695                 :            :          * application might be confined by multiple policies having data in
     696                 :            :          * the same key.
     697                 :            :          */
     698                 :          0 :         memset(buf, 0, sizeof(bytes) + sizeof(blocks));
     699                 :          0 :         out = buf + sizeof(bytes) + sizeof(blocks);
     700                 :            : 
     701                 :            :         blocks = 0;
     702                 :          0 :         label_for_each_confined(i, label, profile) {
     703                 :          0 :                 if (!profile->data)
     704                 :          0 :                         continue;
     705                 :            : 
     706                 :          0 :                 data = rhashtable_lookup_fast(profile->data, &key,
     707                 :            :                                               profile->data->p);
     708                 :            : 
     709                 :          0 :                 if (data) {
     710                 :          0 :                         if (out + sizeof(outle32) + data->size > buf +
     711                 :            :                             buf_len) {
     712                 :            :                                 aa_put_label(label);
     713                 :            :                                 return -EINVAL; /* not enough space */
     714                 :            :                         }
     715                 :          0 :                         outle32 = __cpu_to_le32(data->size);
     716                 :          0 :                         memcpy(out, &outle32, sizeof(outle32));
     717                 :          0 :                         out += sizeof(outle32);
     718                 :          0 :                         memcpy(out, data->data, data->size);
     719                 :          0 :                         out += data->size;
     720                 :          0 :                         blocks++;
     721                 :            :                 }
     722                 :            :         }
     723                 :            :         aa_put_label(label);
     724                 :            : 
     725                 :          0 :         outle32 = __cpu_to_le32(out - buf - sizeof(bytes));
     726                 :          0 :         memcpy(buf, &outle32, sizeof(outle32));
     727                 :          0 :         outle32 = __cpu_to_le32(blocks);
     728                 :          0 :         memcpy(buf + sizeof(bytes), &outle32, sizeof(outle32));
     729                 :            : 
     730                 :          0 :         return out - buf;
     731                 :            : }
     732                 :            : 
     733                 :            : /**
     734                 :            :  * query_label - queries a label and writes permissions to buf
     735                 :            :  * @buf: the resulting permissions string is stored here (NOT NULL)
     736                 :            :  * @buf_len: size of buf
     737                 :            :  * @query: binary query string to match against the dfa
     738                 :            :  * @query_len: size of query
     739                 :            :  * @view_only: only compute for querier's view
     740                 :            :  *
     741                 :            :  * The buffers pointed to by buf and query may overlap. The query buffer is
     742                 :            :  * parsed before buf is written to.
     743                 :            :  *
     744                 :            :  * The query should look like "LABEL_NAME\0DFA_STRING" where LABEL_NAME is
     745                 :            :  * the name of the label, in the current namespace, that is to be queried and
     746                 :            :  * DFA_STRING is a binary string to match against the label(s)'s DFA.
     747                 :            :  *
     748                 :            :  * LABEL_NAME must be NUL terminated. DFA_STRING may contain NUL characters
     749                 :            :  * but must *not* be NUL terminated.
     750                 :            :  *
     751                 :            :  * Returns: number of characters written to buf or -errno on failure
     752                 :            :  */
     753                 :          0 : static ssize_t query_label(char *buf, size_t buf_len,
     754                 :            :                            char *query, size_t query_len, bool view_only)
     755                 :            : {
     756                 :            :         struct aa_profile *profile;
     757                 :            :         struct aa_label *label, *curr;
     758                 :            :         char *label_name, *match_str;
     759                 :            :         size_t label_name_len, match_len;
     760                 :            :         struct aa_perms perms;
     761                 :            :         struct label_it i;
     762                 :            : 
     763                 :          0 :         if (!query_len)
     764                 :            :                 return -EINVAL;
     765                 :            : 
     766                 :            :         label_name = query;
     767                 :          0 :         label_name_len = strnlen(query, query_len);
     768                 :          0 :         if (!label_name_len || label_name_len == query_len)
     769                 :            :                 return -EINVAL;
     770                 :            : 
     771                 :            :         /**
     772                 :            :          * The extra byte is to account for the null byte between the
     773                 :            :          * profile name and dfa string. profile_name_len is greater
     774                 :            :          * than zero and less than query_len, so a byte can be safely
     775                 :            :          * added or subtracted.
     776                 :            :          */
     777                 :          0 :         match_str = label_name + label_name_len + 1;
     778                 :          0 :         match_len = query_len - label_name_len - 1;
     779                 :            : 
     780                 :          0 :         curr = begin_current_label_crit_section();
     781                 :          0 :         label = aa_label_parse(curr, label_name, GFP_KERNEL, false, false);
     782                 :          0 :         end_current_label_crit_section(curr);
     783                 :          0 :         if (IS_ERR(label))
     784                 :          0 :                 return PTR_ERR(label);
     785                 :            : 
     786                 :          0 :         perms = allperms;
     787                 :          0 :         if (view_only) {
     788                 :          0 :                 label_for_each_in_ns(i, labels_ns(label), label, profile) {
     789                 :          0 :                         profile_query_cb(profile, &perms, match_str, match_len);
     790                 :            :                 }
     791                 :            :         } else {
     792                 :          0 :                 label_for_each(i, label, profile) {
     793                 :          0 :                         profile_query_cb(profile, &perms, match_str, match_len);
     794                 :            :                 }
     795                 :            :         }
     796                 :            :         aa_put_label(label);
     797                 :            : 
     798                 :          0 :         return scnprintf(buf, buf_len,
     799                 :            :                       "allow 0x%08x\ndeny 0x%08x\naudit 0x%08x\nquiet 0x%08x\n",
     800                 :            :                       perms.allow, perms.deny, perms.audit, perms.quiet);
     801                 :            : }
     802                 :            : 
     803                 :            : /*
     804                 :            :  * Transaction based IO.
     805                 :            :  * The file expects a write which triggers the transaction, and then
     806                 :            :  * possibly a read(s) which collects the result - which is stored in a
     807                 :            :  * file-local buffer. Once a new write is performed, a new set of results
     808                 :            :  * are stored in the file-local buffer.
     809                 :            :  */
     810                 :            : struct multi_transaction {
     811                 :            :         struct kref count;
     812                 :            :         ssize_t size;
     813                 :            :         char data[0];
     814                 :            : };
     815                 :            : 
     816                 :            : #define MULTI_TRANSACTION_LIMIT (PAGE_SIZE - sizeof(struct multi_transaction))
     817                 :            : /* TODO: replace with per file lock */
     818                 :            : static DEFINE_SPINLOCK(multi_transaction_lock);
     819                 :            : 
     820                 :          0 : static void multi_transaction_kref(struct kref *kref)
     821                 :            : {
     822                 :            :         struct multi_transaction *t;
     823                 :            : 
     824                 :            :         t = container_of(kref, struct multi_transaction, count);
     825                 :          0 :         free_page((unsigned long) t);
     826                 :          0 : }
     827                 :            : 
     828                 :            : static struct multi_transaction *
     829                 :            : get_multi_transaction(struct multi_transaction *t)
     830                 :            : {
     831                 :          0 :         if  (t)
     832                 :            :                 kref_get(&(t->count));
     833                 :            : 
     834                 :            :         return t;
     835                 :            : }
     836                 :            : 
     837                 :            : static void put_multi_transaction(struct multi_transaction *t)
     838                 :            : {
     839                 :          0 :         if (t)
     840                 :          0 :                 kref_put(&(t->count), multi_transaction_kref);
     841                 :            : }
     842                 :            : 
     843                 :            : /* does not increment @new's count */
     844                 :          0 : static void multi_transaction_set(struct file *file,
     845                 :            :                                   struct multi_transaction *new, size_t n)
     846                 :            : {
     847                 :            :         struct multi_transaction *old;
     848                 :            : 
     849                 :            :         AA_BUG(n > MULTI_TRANSACTION_LIMIT);
     850                 :            : 
     851                 :          0 :         new->size = n;
     852                 :            :         spin_lock(&multi_transaction_lock);
     853                 :          0 :         old = (struct multi_transaction *) file->private_data;
     854                 :          0 :         file->private_data = new;
     855                 :            :         spin_unlock(&multi_transaction_lock);
     856                 :            :         put_multi_transaction(old);
     857                 :          0 : }
     858                 :            : 
     859                 :          0 : static struct multi_transaction *multi_transaction_new(struct file *file,
     860                 :            :                                                        const char __user *buf,
     861                 :            :                                                        size_t size)
     862                 :            : {
     863                 :            :         struct multi_transaction *t;
     864                 :            : 
     865                 :          0 :         if (size > MULTI_TRANSACTION_LIMIT - 1)
     866                 :            :                 return ERR_PTR(-EFBIG);
     867                 :            : 
     868                 :          0 :         t = (struct multi_transaction *)get_zeroed_page(GFP_KERNEL);
     869                 :          0 :         if (!t)
     870                 :            :                 return ERR_PTR(-ENOMEM);
     871                 :            :         kref_init(&t->count);
     872                 :          0 :         if (copy_from_user(t->data, buf, size))
     873                 :            :                 return ERR_PTR(-EFAULT);
     874                 :            : 
     875                 :          0 :         return t;
     876                 :            : }
     877                 :            : 
     878                 :          0 : static ssize_t multi_transaction_read(struct file *file, char __user *buf,
     879                 :            :                                        size_t size, loff_t *pos)
     880                 :            : {
     881                 :            :         struct multi_transaction *t;
     882                 :            :         ssize_t ret;
     883                 :            : 
     884                 :            :         spin_lock(&multi_transaction_lock);
     885                 :          0 :         t = get_multi_transaction(file->private_data);
     886                 :            :         spin_unlock(&multi_transaction_lock);
     887                 :          0 :         if (!t)
     888                 :            :                 return 0;
     889                 :            : 
     890                 :          0 :         ret = simple_read_from_buffer(buf, size, pos, t->data, t->size);
     891                 :            :         put_multi_transaction(t);
     892                 :            : 
     893                 :          0 :         return ret;
     894                 :            : }
     895                 :            : 
     896                 :          0 : static int multi_transaction_release(struct inode *inode, struct file *file)
     897                 :            : {
     898                 :          0 :         put_multi_transaction(file->private_data);
     899                 :            : 
     900                 :          0 :         return 0;
     901                 :            : }
     902                 :            : 
     903                 :            : #define QUERY_CMD_LABEL         "label\0"
     904                 :            : #define QUERY_CMD_LABEL_LEN     6
     905                 :            : #define QUERY_CMD_PROFILE       "profile\0"
     906                 :            : #define QUERY_CMD_PROFILE_LEN   8
     907                 :            : #define QUERY_CMD_LABELALL      "labelall\0"
     908                 :            : #define QUERY_CMD_LABELALL_LEN  9
     909                 :            : #define QUERY_CMD_DATA          "data\0"
     910                 :            : #define QUERY_CMD_DATA_LEN      5
     911                 :            : 
     912                 :            : /**
     913                 :            :  * aa_write_access - generic permissions and data query
     914                 :            :  * @file: pointer to open apparmorfs/access file
     915                 :            :  * @ubuf: user buffer containing the complete query string (NOT NULL)
     916                 :            :  * @count: size of ubuf
     917                 :            :  * @ppos: position in the file (MUST BE ZERO)
     918                 :            :  *
     919                 :            :  * Allows for one permissions or data query per open(), write(), and read()
     920                 :            :  * sequence. The only queries currently supported are label-based queries for
     921                 :            :  * permissions or data.
     922                 :            :  *
     923                 :            :  * For permissions queries, ubuf must begin with "label\0", followed by the
     924                 :            :  * profile query specific format described in the query_label() function
     925                 :            :  * documentation.
     926                 :            :  *
     927                 :            :  * For data queries, ubuf must have the form "data\0<LABEL>\0<KEY>\0", where
     928                 :            :  * <LABEL> is the name of the security confinement context and <KEY> is the
     929                 :            :  * name of the data to retrieve.
     930                 :            :  *
     931                 :            :  * Returns: number of bytes written or -errno on failure
     932                 :            :  */
     933                 :          0 : static ssize_t aa_write_access(struct file *file, const char __user *ubuf,
     934                 :            :                                size_t count, loff_t *ppos)
     935                 :            : {
     936                 :            :         struct multi_transaction *t;
     937                 :            :         ssize_t len;
     938                 :            : 
     939                 :          0 :         if (*ppos)
     940                 :            :                 return -ESPIPE;
     941                 :            : 
     942                 :          0 :         t = multi_transaction_new(file, ubuf, count);
     943                 :          0 :         if (IS_ERR(t))
     944                 :          0 :                 return PTR_ERR(t);
     945                 :            : 
     946                 :          0 :         if (count > QUERY_CMD_PROFILE_LEN &&
     947                 :          0 :             !memcmp(t->data, QUERY_CMD_PROFILE, QUERY_CMD_PROFILE_LEN)) {
     948                 :          0 :                 len = query_label(t->data, MULTI_TRANSACTION_LIMIT,
     949                 :            :                                   t->data + QUERY_CMD_PROFILE_LEN,
     950                 :            :                                   count - QUERY_CMD_PROFILE_LEN, true);
     951                 :          0 :         } else if (count > QUERY_CMD_LABEL_LEN &&
     952                 :          0 :                    !memcmp(t->data, QUERY_CMD_LABEL, QUERY_CMD_LABEL_LEN)) {
     953                 :          0 :                 len = query_label(t->data, MULTI_TRANSACTION_LIMIT,
     954                 :            :                                   t->data + QUERY_CMD_LABEL_LEN,
     955                 :            :                                   count - QUERY_CMD_LABEL_LEN, true);
     956                 :          0 :         } else if (count > QUERY_CMD_LABELALL_LEN &&
     957                 :          0 :                    !memcmp(t->data, QUERY_CMD_LABELALL,
     958                 :            :                            QUERY_CMD_LABELALL_LEN)) {
     959                 :          0 :                 len = query_label(t->data, MULTI_TRANSACTION_LIMIT,
     960                 :            :                                   t->data + QUERY_CMD_LABELALL_LEN,
     961                 :            :                                   count - QUERY_CMD_LABELALL_LEN, false);
     962                 :          0 :         } else if (count > QUERY_CMD_DATA_LEN &&
     963                 :          0 :                    !memcmp(t->data, QUERY_CMD_DATA, QUERY_CMD_DATA_LEN)) {
     964                 :          0 :                 len = query_data(t->data, MULTI_TRANSACTION_LIMIT,
     965                 :            :                                  t->data + QUERY_CMD_DATA_LEN,
     966                 :            :                                  count - QUERY_CMD_DATA_LEN);
     967                 :            :         } else
     968                 :            :                 len = -EINVAL;
     969                 :            : 
     970                 :          0 :         if (len < 0) {
     971                 :            :                 put_multi_transaction(t);
     972                 :          0 :                 return len;
     973                 :            :         }
     974                 :            : 
     975                 :          0 :         multi_transaction_set(file, t, len);
     976                 :            : 
     977                 :          0 :         return count;
     978                 :            : }
     979                 :            : 
     980                 :            : static const struct file_operations aa_sfs_access = {
     981                 :            :         .write          = aa_write_access,
     982                 :            :         .read           = multi_transaction_read,
     983                 :            :         .release        = multi_transaction_release,
     984                 :            :         .llseek         = generic_file_llseek,
     985                 :            : };
     986                 :            : 
     987                 :          0 : static int aa_sfs_seq_show(struct seq_file *seq, void *v)
     988                 :            : {
     989                 :          0 :         struct aa_sfs_entry *fs_file = seq->private;
     990                 :            : 
     991                 :          0 :         if (!fs_file)
     992                 :            :                 return 0;
     993                 :            : 
     994                 :          0 :         switch (fs_file->v_type) {
     995                 :            :         case AA_SFS_TYPE_BOOLEAN:
     996                 :          0 :                 seq_printf(seq, "%s\n", fs_file->v.boolean ? "yes" : "no");
     997                 :          0 :                 break;
     998                 :            :         case AA_SFS_TYPE_STRING:
     999                 :          0 :                 seq_printf(seq, "%s\n", fs_file->v.string);
    1000                 :          0 :                 break;
    1001                 :            :         case AA_SFS_TYPE_U64:
    1002                 :          0 :                 seq_printf(seq, "%#08lx\n", fs_file->v.u64);
    1003                 :          0 :                 break;
    1004                 :            :         default:
    1005                 :            :                 /* Ignore unpritable entry types. */
    1006                 :            :                 break;
    1007                 :            :         }
    1008                 :            : 
    1009                 :            :         return 0;
    1010                 :            : }
    1011                 :            : 
    1012                 :          0 : static int aa_sfs_seq_open(struct inode *inode, struct file *file)
    1013                 :            : {
    1014                 :          0 :         return single_open(file, aa_sfs_seq_show, inode->i_private);
    1015                 :            : }
    1016                 :            : 
    1017                 :            : const struct file_operations aa_sfs_seq_file_ops = {
    1018                 :            :         .owner          = THIS_MODULE,
    1019                 :            :         .open           = aa_sfs_seq_open,
    1020                 :            :         .read           = seq_read,
    1021                 :            :         .llseek         = seq_lseek,
    1022                 :            :         .release        = single_release,
    1023                 :            : };
    1024                 :            : 
    1025                 :            : /*
    1026                 :            :  * profile based file operations
    1027                 :            :  *     policy/profiles/XXXX/profiles/ *
    1028                 :            :  */
    1029                 :            : 
    1030                 :            : #define SEQ_PROFILE_FOPS(NAME)                                                \
    1031                 :            : static int seq_profile_ ##NAME ##_open(struct inode *inode, struct file *file)\
    1032                 :            : {                                                                             \
    1033                 :            :         return seq_profile_open(inode, file, seq_profile_ ##NAME ##_show);    \
    1034                 :            : }                                                                             \
    1035                 :            :                                                                               \
    1036                 :            : static const struct file_operations seq_profile_ ##NAME ##_fops = {           \
    1037                 :            :         .owner          = THIS_MODULE,                                        \
    1038                 :            :         .open           = seq_profile_ ##NAME ##_open,                        \
    1039                 :            :         .read           = seq_read,                                           \
    1040                 :            :         .llseek         = seq_lseek,                                          \
    1041                 :            :         .release        = seq_profile_release,                                \
    1042                 :            : }                                                                             \
    1043                 :            : 
    1044                 :          0 : static int seq_profile_open(struct inode *inode, struct file *file,
    1045                 :            :                             int (*show)(struct seq_file *, void *))
    1046                 :            : {
    1047                 :          0 :         struct aa_proxy *proxy = aa_get_proxy(inode->i_private);
    1048                 :          0 :         int error = single_open(file, show, proxy);
    1049                 :            : 
    1050                 :          0 :         if (error) {
    1051                 :          0 :                 file->private_data = NULL;
    1052                 :            :                 aa_put_proxy(proxy);
    1053                 :            :         }
    1054                 :            : 
    1055                 :          0 :         return error;
    1056                 :            : }
    1057                 :            : 
    1058                 :          0 : static int seq_profile_release(struct inode *inode, struct file *file)
    1059                 :            : {
    1060                 :          0 :         struct seq_file *seq = (struct seq_file *) file->private_data;
    1061                 :          0 :         if (seq)
    1062                 :          0 :                 aa_put_proxy(seq->private);
    1063                 :          0 :         return single_release(inode, file);
    1064                 :            : }
    1065                 :            : 
    1066                 :          0 : static int seq_profile_name_show(struct seq_file *seq, void *v)
    1067                 :            : {
    1068                 :          0 :         struct aa_proxy *proxy = seq->private;
    1069                 :          0 :         struct aa_label *label = aa_get_label_rcu(&proxy->label);
    1070                 :          0 :         struct aa_profile *profile = labels_profile(label);
    1071                 :          0 :         seq_printf(seq, "%s\n", profile->base.name);
    1072                 :            :         aa_put_label(label);
    1073                 :            : 
    1074                 :          0 :         return 0;
    1075                 :            : }
    1076                 :            : 
    1077                 :          0 : static int seq_profile_mode_show(struct seq_file *seq, void *v)
    1078                 :            : {
    1079                 :          0 :         struct aa_proxy *proxy = seq->private;
    1080                 :          0 :         struct aa_label *label = aa_get_label_rcu(&proxy->label);
    1081                 :          0 :         struct aa_profile *profile = labels_profile(label);
    1082                 :          0 :         seq_printf(seq, "%s\n", aa_profile_mode_names[profile->mode]);
    1083                 :            :         aa_put_label(label);
    1084                 :            : 
    1085                 :          0 :         return 0;
    1086                 :            : }
    1087                 :            : 
    1088                 :          0 : static int seq_profile_attach_show(struct seq_file *seq, void *v)
    1089                 :            : {
    1090                 :          0 :         struct aa_proxy *proxy = seq->private;
    1091                 :          0 :         struct aa_label *label = aa_get_label_rcu(&proxy->label);
    1092                 :          0 :         struct aa_profile *profile = labels_profile(label);
    1093                 :          0 :         if (profile->attach)
    1094                 :          0 :                 seq_printf(seq, "%s\n", profile->attach);
    1095                 :          0 :         else if (profile->xmatch)
    1096                 :          0 :                 seq_puts(seq, "<unknown>\n");
    1097                 :            :         else
    1098                 :          0 :                 seq_printf(seq, "%s\n", profile->base.name);
    1099                 :            :         aa_put_label(label);
    1100                 :            : 
    1101                 :          0 :         return 0;
    1102                 :            : }
    1103                 :            : 
    1104                 :          0 : static int seq_profile_hash_show(struct seq_file *seq, void *v)
    1105                 :            : {
    1106                 :          0 :         struct aa_proxy *proxy = seq->private;
    1107                 :          0 :         struct aa_label *label = aa_get_label_rcu(&proxy->label);
    1108                 :          0 :         struct aa_profile *profile = labels_profile(label);
    1109                 :          0 :         unsigned int i, size = aa_hash_size();
    1110                 :            : 
    1111                 :          0 :         if (profile->hash) {
    1112                 :          0 :                 for (i = 0; i < size; i++)
    1113                 :          0 :                         seq_printf(seq, "%.2x", profile->hash[i]);
    1114                 :          0 :                 seq_putc(seq, '\n');
    1115                 :            :         }
    1116                 :            :         aa_put_label(label);
    1117                 :            : 
    1118                 :          0 :         return 0;
    1119                 :            : }
    1120                 :            : 
    1121                 :          0 : SEQ_PROFILE_FOPS(name);
    1122                 :          0 : SEQ_PROFILE_FOPS(mode);
    1123                 :          0 : SEQ_PROFILE_FOPS(attach);
    1124                 :          0 : SEQ_PROFILE_FOPS(hash);
    1125                 :            : 
    1126                 :            : /*
    1127                 :            :  * namespace based files
    1128                 :            :  *     several root files and
    1129                 :            :  *     policy/ *
    1130                 :            :  */
    1131                 :            : 
    1132                 :            : #define SEQ_NS_FOPS(NAME)                                                     \
    1133                 :            : static int seq_ns_ ##NAME ##_open(struct inode *inode, struct file *file)     \
    1134                 :            : {                                                                             \
    1135                 :            :         return single_open(file, seq_ns_ ##NAME ##_show, inode->i_private);   \
    1136                 :            : }                                                                             \
    1137                 :            :                                                                               \
    1138                 :            : static const struct file_operations seq_ns_ ##NAME ##_fops = {        \
    1139                 :            :         .owner          = THIS_MODULE,                                        \
    1140                 :            :         .open           = seq_ns_ ##NAME ##_open,                             \
    1141                 :            :         .read           = seq_read,                                           \
    1142                 :            :         .llseek         = seq_lseek,                                          \
    1143                 :            :         .release        = single_release,                                     \
    1144                 :            : }                                                                             \
    1145                 :            : 
    1146                 :          0 : static int seq_ns_stacked_show(struct seq_file *seq, void *v)
    1147                 :            : {
    1148                 :            :         struct aa_label *label;
    1149                 :            : 
    1150                 :          0 :         label = begin_current_label_crit_section();
    1151                 :          0 :         seq_printf(seq, "%s\n", label->size > 1 ? "yes" : "no");
    1152                 :          0 :         end_current_label_crit_section(label);
    1153                 :            : 
    1154                 :          0 :         return 0;
    1155                 :            : }
    1156                 :            : 
    1157                 :          0 : static int seq_ns_nsstacked_show(struct seq_file *seq, void *v)
    1158                 :            : {
    1159                 :            :         struct aa_label *label;
    1160                 :            :         struct aa_profile *profile;
    1161                 :            :         struct label_it it;
    1162                 :            :         int count = 1;
    1163                 :            : 
    1164                 :          0 :         label = begin_current_label_crit_section();
    1165                 :            : 
    1166                 :          0 :         if (label->size > 1) {
    1167                 :          0 :                 label_for_each(it, label, profile)
    1168                 :          0 :                         if (profile->ns != labels_ns(label)) {
    1169                 :            :                                 count++;
    1170                 :            :                                 break;
    1171                 :            :                         }
    1172                 :            :         }
    1173                 :            : 
    1174                 :          0 :         seq_printf(seq, "%s\n", count > 1 ? "yes" : "no");
    1175                 :          0 :         end_current_label_crit_section(label);
    1176                 :            : 
    1177                 :          0 :         return 0;
    1178                 :            : }
    1179                 :            : 
    1180                 :          0 : static int seq_ns_level_show(struct seq_file *seq, void *v)
    1181                 :            : {
    1182                 :            :         struct aa_label *label;
    1183                 :            : 
    1184                 :          0 :         label = begin_current_label_crit_section();
    1185                 :          0 :         seq_printf(seq, "%d\n", labels_ns(label)->level);
    1186                 :          0 :         end_current_label_crit_section(label);
    1187                 :            : 
    1188                 :          0 :         return 0;
    1189                 :            : }
    1190                 :            : 
    1191                 :          0 : static int seq_ns_name_show(struct seq_file *seq, void *v)
    1192                 :            : {
    1193                 :          0 :         struct aa_label *label = begin_current_label_crit_section();
    1194                 :          0 :         seq_printf(seq, "%s\n", labels_ns(label)->base.name);
    1195                 :          0 :         end_current_label_crit_section(label);
    1196                 :            : 
    1197                 :          0 :         return 0;
    1198                 :            : }
    1199                 :            : 
    1200                 :          0 : SEQ_NS_FOPS(stacked);
    1201                 :          0 : SEQ_NS_FOPS(nsstacked);
    1202                 :          0 : SEQ_NS_FOPS(level);
    1203                 :          0 : SEQ_NS_FOPS(name);
    1204                 :            : 
    1205                 :            : 
    1206                 :            : /* policy/raw_data/ * file ops */
    1207                 :            : 
    1208                 :            : #define SEQ_RAWDATA_FOPS(NAME)                                                \
    1209                 :            : static int seq_rawdata_ ##NAME ##_open(struct inode *inode, struct file *file)\
    1210                 :            : {                                                                             \
    1211                 :            :         return seq_rawdata_open(inode, file, seq_rawdata_ ##NAME ##_show);    \
    1212                 :            : }                                                                             \
    1213                 :            :                                                                               \
    1214                 :            : static const struct file_operations seq_rawdata_ ##NAME ##_fops = {           \
    1215                 :            :         .owner          = THIS_MODULE,                                        \
    1216                 :            :         .open           = seq_rawdata_ ##NAME ##_open,                        \
    1217                 :            :         .read           = seq_read,                                           \
    1218                 :            :         .llseek         = seq_lseek,                                          \
    1219                 :            :         .release        = seq_rawdata_release,                                \
    1220                 :            : }                                                                             \
    1221                 :            : 
    1222                 :          0 : static int seq_rawdata_open(struct inode *inode, struct file *file,
    1223                 :            :                             int (*show)(struct seq_file *, void *))
    1224                 :            : {
    1225                 :          0 :         struct aa_loaddata *data = __aa_get_loaddata(inode->i_private);
    1226                 :            :         int error;
    1227                 :            : 
    1228                 :          0 :         if (!data)
    1229                 :            :                 /* lost race this ent is being reaped */
    1230                 :            :                 return -ENOENT;
    1231                 :            : 
    1232                 :          0 :         error = single_open(file, show, data);
    1233                 :          0 :         if (error) {
    1234                 :            :                 AA_BUG(file->private_data &&
    1235                 :            :                        ((struct seq_file *)file->private_data)->private);
    1236                 :            :                 aa_put_loaddata(data);
    1237                 :            :         }
    1238                 :            : 
    1239                 :          0 :         return error;
    1240                 :            : }
    1241                 :            : 
    1242                 :          0 : static int seq_rawdata_release(struct inode *inode, struct file *file)
    1243                 :            : {
    1244                 :          0 :         struct seq_file *seq = (struct seq_file *) file->private_data;
    1245                 :            : 
    1246                 :          0 :         if (seq)
    1247                 :          0 :                 aa_put_loaddata(seq->private);
    1248                 :            : 
    1249                 :          0 :         return single_release(inode, file);
    1250                 :            : }
    1251                 :            : 
    1252                 :          0 : static int seq_rawdata_abi_show(struct seq_file *seq, void *v)
    1253                 :            : {
    1254                 :          0 :         struct aa_loaddata *data = seq->private;
    1255                 :            : 
    1256                 :          0 :         seq_printf(seq, "v%d\n", data->abi);
    1257                 :            : 
    1258                 :          0 :         return 0;
    1259                 :            : }
    1260                 :            : 
    1261                 :          0 : static int seq_rawdata_revision_show(struct seq_file *seq, void *v)
    1262                 :            : {
    1263                 :          0 :         struct aa_loaddata *data = seq->private;
    1264                 :            : 
    1265                 :          0 :         seq_printf(seq, "%ld\n", data->revision);
    1266                 :            : 
    1267                 :          0 :         return 0;
    1268                 :            : }
    1269                 :            : 
    1270                 :          0 : static int seq_rawdata_hash_show(struct seq_file *seq, void *v)
    1271                 :            : {
    1272                 :          0 :         struct aa_loaddata *data = seq->private;
    1273                 :          0 :         unsigned int i, size = aa_hash_size();
    1274                 :            : 
    1275                 :          0 :         if (data->hash) {
    1276                 :          0 :                 for (i = 0; i < size; i++)
    1277                 :          0 :                         seq_printf(seq, "%.2x", data->hash[i]);
    1278                 :          0 :                 seq_putc(seq, '\n');
    1279                 :            :         }
    1280                 :            : 
    1281                 :          0 :         return 0;
    1282                 :            : }
    1283                 :            : 
    1284                 :          0 : SEQ_RAWDATA_FOPS(abi);
    1285                 :          0 : SEQ_RAWDATA_FOPS(revision);
    1286                 :          0 : SEQ_RAWDATA_FOPS(hash);
    1287                 :            : 
    1288                 :          0 : static ssize_t rawdata_read(struct file *file, char __user *buf, size_t size,
    1289                 :            :                             loff_t *ppos)
    1290                 :            : {
    1291                 :          0 :         struct aa_loaddata *rawdata = file->private_data;
    1292                 :            : 
    1293                 :          0 :         return simple_read_from_buffer(buf, size, ppos, rawdata->data,
    1294                 :            :                                        rawdata->size);
    1295                 :            : }
    1296                 :            : 
    1297                 :          0 : static int rawdata_release(struct inode *inode, struct file *file)
    1298                 :            : {
    1299                 :          0 :         aa_put_loaddata(file->private_data);
    1300                 :            : 
    1301                 :          0 :         return 0;
    1302                 :            : }
    1303                 :            : 
    1304                 :          0 : static int rawdata_open(struct inode *inode, struct file *file)
    1305                 :            : {
    1306                 :          0 :         if (!policy_view_capable(NULL))
    1307                 :            :                 return -EACCES;
    1308                 :          0 :         file->private_data = __aa_get_loaddata(inode->i_private);
    1309                 :          0 :         if (!file->private_data)
    1310                 :            :                 /* lost race: this entry is being reaped */
    1311                 :            :                 return -ENOENT;
    1312                 :            : 
    1313                 :          0 :         return 0;
    1314                 :            : }
    1315                 :            : 
    1316                 :            : static const struct file_operations rawdata_fops = {
    1317                 :            :         .open = rawdata_open,
    1318                 :            :         .read = rawdata_read,
    1319                 :            :         .llseek = generic_file_llseek,
    1320                 :            :         .release = rawdata_release,
    1321                 :            : };
    1322                 :            : 
    1323                 :          0 : static void remove_rawdata_dents(struct aa_loaddata *rawdata)
    1324                 :            : {
    1325                 :            :         int i;
    1326                 :            : 
    1327                 :          0 :         for (i = 0; i < AAFS_LOADDATA_NDENTS; i++) {
    1328                 :          0 :                 if (!IS_ERR_OR_NULL(rawdata->dents[i])) {
    1329                 :            :                         /* no refcounts on i_private */
    1330                 :          0 :                         aafs_remove(rawdata->dents[i]);
    1331                 :          0 :                         rawdata->dents[i] = NULL;
    1332                 :            :                 }
    1333                 :            :         }
    1334                 :          0 : }
    1335                 :            : 
    1336                 :          0 : void __aa_fs_remove_rawdata(struct aa_loaddata *rawdata)
    1337                 :            : {
    1338                 :            :         AA_BUG(rawdata->ns && !mutex_is_locked(&rawdata->ns->lock));
    1339                 :            : 
    1340                 :          0 :         if (rawdata->ns) {
    1341                 :          0 :                 remove_rawdata_dents(rawdata);
    1342                 :          0 :                 list_del_init(&rawdata->list);
    1343                 :          0 :                 aa_put_ns(rawdata->ns);
    1344                 :          0 :                 rawdata->ns = NULL;
    1345                 :            :         }
    1346                 :          0 : }
    1347                 :            : 
    1348                 :          0 : int __aa_fs_create_rawdata(struct aa_ns *ns, struct aa_loaddata *rawdata)
    1349                 :            : {
    1350                 :            :         struct dentry *dent, *dir;
    1351                 :            : 
    1352                 :            :         AA_BUG(!ns);
    1353                 :            :         AA_BUG(!rawdata);
    1354                 :            :         AA_BUG(!mutex_is_locked(&ns->lock));
    1355                 :            :         AA_BUG(!ns_subdata_dir(ns));
    1356                 :            : 
    1357                 :            :         /*
    1358                 :            :          * just use ns revision dir was originally created at. This is
    1359                 :            :          * under ns->lock and if load is successful revision will be
    1360                 :            :          * bumped and is guaranteed to be unique
    1361                 :            :          */
    1362                 :          0 :         rawdata->name = kasprintf(GFP_KERNEL, "%ld", ns->revision);
    1363                 :          0 :         if (!rawdata->name)
    1364                 :            :                 return -ENOMEM;
    1365                 :            : 
    1366                 :          0 :         dir = aafs_create_dir(rawdata->name, ns_subdata_dir(ns));
    1367                 :          0 :         if (IS_ERR(dir))
    1368                 :            :                 /* ->name freed when rawdata freed */
    1369                 :          0 :                 return PTR_ERR(dir);
    1370                 :          0 :         rawdata->dents[AAFS_LOADDATA_DIR] = dir;
    1371                 :            : 
    1372                 :            :         dent = aafs_create_file("abi", S_IFREG | 0444, dir, rawdata,
    1373                 :            :                                       &seq_rawdata_abi_fops);
    1374                 :          0 :         if (IS_ERR(dent))
    1375                 :            :                 goto fail;
    1376                 :          0 :         rawdata->dents[AAFS_LOADDATA_ABI] = dent;
    1377                 :            : 
    1378                 :            :         dent = aafs_create_file("revision", S_IFREG | 0444, dir, rawdata,
    1379                 :            :                                       &seq_rawdata_revision_fops);
    1380                 :          0 :         if (IS_ERR(dent))
    1381                 :            :                 goto fail;
    1382                 :          0 :         rawdata->dents[AAFS_LOADDATA_REVISION] = dent;
    1383                 :            : 
    1384                 :          0 :         if (aa_g_hash_policy) {
    1385                 :            :                 dent = aafs_create_file("sha1", S_IFREG | 0444, dir,
    1386                 :            :                                               rawdata, &seq_rawdata_hash_fops);
    1387                 :          0 :                 if (IS_ERR(dent))
    1388                 :            :                         goto fail;
    1389                 :          0 :                 rawdata->dents[AAFS_LOADDATA_HASH] = dent;
    1390                 :            :         }
    1391                 :            : 
    1392                 :            :         dent = aafs_create_file("raw_data", S_IFREG | 0444,
    1393                 :            :                                       dir, rawdata, &rawdata_fops);
    1394                 :          0 :         if (IS_ERR(dent))
    1395                 :            :                 goto fail;
    1396                 :          0 :         rawdata->dents[AAFS_LOADDATA_DATA] = dent;
    1397                 :          0 :         d_inode(dent)->i_size = rawdata->size;
    1398                 :            : 
    1399                 :          0 :         rawdata->ns = aa_get_ns(ns);
    1400                 :          0 :         list_add(&rawdata->list, &ns->rawdata_list);
    1401                 :            :         /* no refcount on inode rawdata */
    1402                 :            : 
    1403                 :          0 :         return 0;
    1404                 :            : 
    1405                 :            : fail:
    1406                 :          0 :         remove_rawdata_dents(rawdata);
    1407                 :            : 
    1408                 :          0 :         return PTR_ERR(dent);
    1409                 :            : }
    1410                 :            : 
    1411                 :            : /** fns to setup dynamic per profile/namespace files **/
    1412                 :            : 
    1413                 :            : /**
    1414                 :            :  *
    1415                 :            :  * Requires: @profile->ns->lock held
    1416                 :            :  */
    1417                 :          0 : void __aafs_profile_rmdir(struct aa_profile *profile)
    1418                 :            : {
    1419                 :            :         struct aa_profile *child;
    1420                 :            :         int i;
    1421                 :            : 
    1422                 :          0 :         if (!profile)
    1423                 :          0 :                 return;
    1424                 :            : 
    1425                 :          0 :         list_for_each_entry(child, &profile->base.profiles, base.list)
    1426                 :          0 :                 __aafs_profile_rmdir(child);
    1427                 :            : 
    1428                 :          0 :         for (i = AAFS_PROF_SIZEOF - 1; i >= 0; --i) {
    1429                 :            :                 struct aa_proxy *proxy;
    1430                 :          0 :                 if (!profile->dents[i])
    1431                 :          0 :                         continue;
    1432                 :            : 
    1433                 :          0 :                 proxy = d_inode(profile->dents[i])->i_private;
    1434                 :          0 :                 aafs_remove(profile->dents[i]);
    1435                 :            :                 aa_put_proxy(proxy);
    1436                 :          0 :                 profile->dents[i] = NULL;
    1437                 :            :         }
    1438                 :            : }
    1439                 :            : 
    1440                 :            : /**
    1441                 :            :  *
    1442                 :            :  * Requires: @old->ns->lock held
    1443                 :            :  */
    1444                 :          0 : void __aafs_profile_migrate_dents(struct aa_profile *old,
    1445                 :            :                                   struct aa_profile *new)
    1446                 :            : {
    1447                 :            :         int i;
    1448                 :            : 
    1449                 :            :         AA_BUG(!old);
    1450                 :            :         AA_BUG(!new);
    1451                 :            :         AA_BUG(!mutex_is_locked(&profiles_ns(old)->lock));
    1452                 :            : 
    1453                 :          0 :         for (i = 0; i < AAFS_PROF_SIZEOF; i++) {
    1454                 :          0 :                 new->dents[i] = old->dents[i];
    1455                 :          0 :                 if (new->dents[i])
    1456                 :          0 :                         new->dents[i]->d_inode->i_mtime = current_time(new->dents[i]->d_inode);
    1457                 :          0 :                 old->dents[i] = NULL;
    1458                 :            :         }
    1459                 :          0 : }
    1460                 :            : 
    1461                 :          0 : static struct dentry *create_profile_file(struct dentry *dir, const char *name,
    1462                 :            :                                           struct aa_profile *profile,
    1463                 :            :                                           const struct file_operations *fops)
    1464                 :            : {
    1465                 :          0 :         struct aa_proxy *proxy = aa_get_proxy(profile->label.proxy);
    1466                 :            :         struct dentry *dent;
    1467                 :            : 
    1468                 :            :         dent = aafs_create_file(name, S_IFREG | 0444, dir, proxy, fops);
    1469                 :          0 :         if (IS_ERR(dent))
    1470                 :            :                 aa_put_proxy(proxy);
    1471                 :            : 
    1472                 :          0 :         return dent;
    1473                 :            : }
    1474                 :            : 
    1475                 :            : static int profile_depth(struct aa_profile *profile)
    1476                 :            : {
    1477                 :            :         int depth = 0;
    1478                 :            : 
    1479                 :            :         rcu_read_lock();
    1480                 :          0 :         for (depth = 0; profile; profile = rcu_access_pointer(profile->parent))
    1481                 :          0 :                 depth++;
    1482                 :            :         rcu_read_unlock();
    1483                 :            : 
    1484                 :          0 :         return depth;
    1485                 :            : }
    1486                 :            : 
    1487                 :          0 : static char *gen_symlink_name(int depth, const char *dirname, const char *fname)
    1488                 :            : {
    1489                 :            :         char *buffer, *s;
    1490                 :            :         int error;
    1491                 :          0 :         int size = depth * 6 + strlen(dirname) + strlen(fname) + 11;
    1492                 :            : 
    1493                 :            :         s = buffer = kmalloc(size, GFP_KERNEL);
    1494                 :          0 :         if (!buffer)
    1495                 :            :                 return ERR_PTR(-ENOMEM);
    1496                 :            : 
    1497                 :          0 :         for (; depth > 0; depth--) {
    1498                 :          0 :                 strcpy(s, "../../");
    1499                 :          0 :                 s += 6;
    1500                 :          0 :                 size -= 6;
    1501                 :            :         }
    1502                 :            : 
    1503                 :          0 :         error = snprintf(s, size, "raw_data/%s/%s", dirname, fname);
    1504                 :          0 :         if (error >= size || error < 0) {
    1505                 :          0 :                 kfree(buffer);
    1506                 :          0 :                 return ERR_PTR(-ENAMETOOLONG);
    1507                 :            :         }
    1508                 :            : 
    1509                 :            :         return buffer;
    1510                 :            : }
    1511                 :            : 
    1512                 :          0 : static void rawdata_link_cb(void *arg)
    1513                 :            : {
    1514                 :          0 :         kfree(arg);
    1515                 :          0 : }
    1516                 :            : 
    1517                 :          0 : static const char *rawdata_get_link_base(struct dentry *dentry,
    1518                 :            :                                          struct inode *inode,
    1519                 :            :                                          struct delayed_call *done,
    1520                 :            :                                          const char *name)
    1521                 :            : {
    1522                 :          0 :         struct aa_proxy *proxy = inode->i_private;
    1523                 :            :         struct aa_label *label;
    1524                 :            :         struct aa_profile *profile;
    1525                 :            :         char *target;
    1526                 :            :         int depth;
    1527                 :            : 
    1528                 :          0 :         if (!dentry)
    1529                 :            :                 return ERR_PTR(-ECHILD);
    1530                 :            : 
    1531                 :          0 :         label = aa_get_label_rcu(&proxy->label);
    1532                 :          0 :         profile = labels_profile(label);
    1533                 :            :         depth = profile_depth(profile);
    1534                 :          0 :         target = gen_symlink_name(depth, profile->rawdata->name, name);
    1535                 :            :         aa_put_label(label);
    1536                 :            : 
    1537                 :          0 :         if (IS_ERR(target))
    1538                 :            :                 return target;
    1539                 :            : 
    1540                 :            :         set_delayed_call(done, rawdata_link_cb, target);
    1541                 :            : 
    1542                 :          0 :         return target;
    1543                 :            : }
    1544                 :            : 
    1545                 :          0 : static const char *rawdata_get_link_sha1(struct dentry *dentry,
    1546                 :            :                                          struct inode *inode,
    1547                 :            :                                          struct delayed_call *done)
    1548                 :            : {
    1549                 :          0 :         return rawdata_get_link_base(dentry, inode, done, "sha1");
    1550                 :            : }
    1551                 :            : 
    1552                 :          0 : static const char *rawdata_get_link_abi(struct dentry *dentry,
    1553                 :            :                                         struct inode *inode,
    1554                 :            :                                         struct delayed_call *done)
    1555                 :            : {
    1556                 :          0 :         return rawdata_get_link_base(dentry, inode, done, "abi");
    1557                 :            : }
    1558                 :            : 
    1559                 :          0 : static const char *rawdata_get_link_data(struct dentry *dentry,
    1560                 :            :                                          struct inode *inode,
    1561                 :            :                                          struct delayed_call *done)
    1562                 :            : {
    1563                 :          0 :         return rawdata_get_link_base(dentry, inode, done, "raw_data");
    1564                 :            : }
    1565                 :            : 
    1566                 :            : static const struct inode_operations rawdata_link_sha1_iops = {
    1567                 :            :         .get_link       = rawdata_get_link_sha1,
    1568                 :            : };
    1569                 :            : 
    1570                 :            : static const struct inode_operations rawdata_link_abi_iops = {
    1571                 :            :         .get_link       = rawdata_get_link_abi,
    1572                 :            : };
    1573                 :            : static const struct inode_operations rawdata_link_data_iops = {
    1574                 :            :         .get_link       = rawdata_get_link_data,
    1575                 :            : };
    1576                 :            : 
    1577                 :            : 
    1578                 :            : /*
    1579                 :            :  * Requires: @profile->ns->lock held
    1580                 :            :  */
    1581                 :          0 : int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
    1582                 :            : {
    1583                 :            :         struct aa_profile *child;
    1584                 :            :         struct dentry *dent = NULL, *dir;
    1585                 :            :         int error;
    1586                 :            : 
    1587                 :            :         AA_BUG(!profile);
    1588                 :            :         AA_BUG(!mutex_is_locked(&profiles_ns(profile)->lock));
    1589                 :            : 
    1590                 :          0 :         if (!parent) {
    1591                 :            :                 struct aa_profile *p;
    1592                 :            :                 p = aa_deref_parent(profile);
    1593                 :          0 :                 dent = prof_dir(p);
    1594                 :            :                 /* adding to parent that previously didn't have children */
    1595                 :            :                 dent = aafs_create_dir("profiles", dent);
    1596                 :          0 :                 if (IS_ERR(dent))
    1597                 :            :                         goto fail;
    1598                 :          0 :                 prof_child_dir(p) = parent = dent;
    1599                 :            :         }
    1600                 :            : 
    1601                 :          0 :         if (!profile->dirname) {
    1602                 :            :                 int len, id_len;
    1603                 :          0 :                 len = mangle_name(profile->base.name, NULL);
    1604                 :          0 :                 id_len = snprintf(NULL, 0, ".%ld", profile->ns->uniq_id);
    1605                 :            : 
    1606                 :          0 :                 profile->dirname = kmalloc(len + id_len + 1, GFP_KERNEL);
    1607                 :          0 :                 if (!profile->dirname) {
    1608                 :            :                         error = -ENOMEM;
    1609                 :            :                         goto fail2;
    1610                 :            :                 }
    1611                 :            : 
    1612                 :          0 :                 mangle_name(profile->base.name, profile->dirname);
    1613                 :          0 :                 sprintf(profile->dirname + len, ".%ld", profile->ns->uniq_id++);
    1614                 :            :         }
    1615                 :            : 
    1616                 :          0 :         dent = aafs_create_dir(profile->dirname, parent);
    1617                 :          0 :         if (IS_ERR(dent))
    1618                 :            :                 goto fail;
    1619                 :          0 :         prof_dir(profile) = dir = dent;
    1620                 :            : 
    1621                 :          0 :         dent = create_profile_file(dir, "name", profile,
    1622                 :            :                                    &seq_profile_name_fops);
    1623                 :          0 :         if (IS_ERR(dent))
    1624                 :            :                 goto fail;
    1625                 :          0 :         profile->dents[AAFS_PROF_NAME] = dent;
    1626                 :            : 
    1627                 :          0 :         dent = create_profile_file(dir, "mode", profile,
    1628                 :            :                                    &seq_profile_mode_fops);
    1629                 :          0 :         if (IS_ERR(dent))
    1630                 :            :                 goto fail;
    1631                 :          0 :         profile->dents[AAFS_PROF_MODE] = dent;
    1632                 :            : 
    1633                 :          0 :         dent = create_profile_file(dir, "attach", profile,
    1634                 :            :                                    &seq_profile_attach_fops);
    1635                 :          0 :         if (IS_ERR(dent))
    1636                 :            :                 goto fail;
    1637                 :          0 :         profile->dents[AAFS_PROF_ATTACH] = dent;
    1638                 :            : 
    1639                 :          0 :         if (profile->hash) {
    1640                 :          0 :                 dent = create_profile_file(dir, "sha1", profile,
    1641                 :            :                                            &seq_profile_hash_fops);
    1642                 :          0 :                 if (IS_ERR(dent))
    1643                 :            :                         goto fail;
    1644                 :          0 :                 profile->dents[AAFS_PROF_HASH] = dent;
    1645                 :            :         }
    1646                 :            : 
    1647                 :          0 :         if (profile->rawdata) {
    1648                 :          0 :                 dent = aafs_create_symlink("raw_sha1", dir, NULL,
    1649                 :          0 :                                            profile->label.proxy,
    1650                 :            :                                            &rawdata_link_sha1_iops);
    1651                 :          0 :                 if (IS_ERR(dent))
    1652                 :            :                         goto fail;
    1653                 :          0 :                 aa_get_proxy(profile->label.proxy);
    1654                 :          0 :                 profile->dents[AAFS_PROF_RAW_HASH] = dent;
    1655                 :            : 
    1656                 :          0 :                 dent = aafs_create_symlink("raw_abi", dir, NULL,
    1657                 :          0 :                                            profile->label.proxy,
    1658                 :            :                                            &rawdata_link_abi_iops);
    1659                 :          0 :                 if (IS_ERR(dent))
    1660                 :            :                         goto fail;
    1661                 :          0 :                 aa_get_proxy(profile->label.proxy);
    1662                 :          0 :                 profile->dents[AAFS_PROF_RAW_ABI] = dent;
    1663                 :            : 
    1664                 :          0 :                 dent = aafs_create_symlink("raw_data", dir, NULL,
    1665                 :          0 :                                            profile->label.proxy,
    1666                 :            :                                            &rawdata_link_data_iops);
    1667                 :          0 :                 if (IS_ERR(dent))
    1668                 :            :                         goto fail;
    1669                 :          0 :                 aa_get_proxy(profile->label.proxy);
    1670                 :          0 :                 profile->dents[AAFS_PROF_RAW_DATA] = dent;
    1671                 :            :         }
    1672                 :            : 
    1673                 :          0 :         list_for_each_entry(child, &profile->base.profiles, base.list) {
    1674                 :          0 :                 error = __aafs_profile_mkdir(child, prof_child_dir(profile));
    1675                 :          0 :                 if (error)
    1676                 :            :                         goto fail2;
    1677                 :            :         }
    1678                 :            : 
    1679                 :            :         return 0;
    1680                 :            : 
    1681                 :            : fail:
    1682                 :            :         error = PTR_ERR(dent);
    1683                 :            : 
    1684                 :            : fail2:
    1685                 :          0 :         __aafs_profile_rmdir(profile);
    1686                 :            : 
    1687                 :          0 :         return error;
    1688                 :            : }
    1689                 :            : 
    1690                 :          0 : static int ns_mkdir_op(struct inode *dir, struct dentry *dentry, umode_t mode)
    1691                 :            : {
    1692                 :            :         struct aa_ns *ns, *parent;
    1693                 :            :         /* TODO: improve permission check */
    1694                 :            :         struct aa_label *label;
    1695                 :            :         int error;
    1696                 :            : 
    1697                 :          0 :         label = begin_current_label_crit_section();
    1698                 :          0 :         error = aa_may_manage_policy(label, NULL, AA_MAY_LOAD_POLICY);
    1699                 :          0 :         end_current_label_crit_section(label);
    1700                 :          0 :         if (error)
    1701                 :            :                 return error;
    1702                 :            : 
    1703                 :          0 :         parent = aa_get_ns(dir->i_private);
    1704                 :            :         AA_BUG(d_inode(ns_subns_dir(parent)) != dir);
    1705                 :            : 
    1706                 :            :         /* we have to unlock and then relock to get locking order right
    1707                 :            :          * for pin_fs
    1708                 :            :          */
    1709                 :            :         inode_unlock(dir);
    1710                 :          0 :         error = simple_pin_fs(&aafs_ops, &aafs_mnt, &aafs_count);
    1711                 :          0 :         mutex_lock_nested(&parent->lock, parent->level);
    1712                 :            :         inode_lock_nested(dir, I_MUTEX_PARENT);
    1713                 :          0 :         if (error)
    1714                 :            :                 goto out;
    1715                 :            : 
    1716                 :          0 :         error = __aafs_setup_d_inode(dir, dentry, mode | S_IFDIR,  NULL,
    1717                 :            :                                      NULL, NULL, NULL);
    1718                 :          0 :         if (error)
    1719                 :            :                 goto out_pin;
    1720                 :            : 
    1721                 :          0 :         ns = __aa_find_or_create_ns(parent, READ_ONCE(dentry->d_name.name),
    1722                 :            :                                     dentry);
    1723                 :          0 :         if (IS_ERR(ns)) {
    1724                 :            :                 error = PTR_ERR(ns);
    1725                 :            :                 ns = NULL;
    1726                 :            :         }
    1727                 :            : 
    1728                 :          0 :         aa_put_ns(ns);          /* list ref remains */
    1729                 :            : out_pin:
    1730                 :          0 :         if (error)
    1731                 :          0 :                 simple_release_fs(&aafs_mnt, &aafs_count);
    1732                 :            : out:
    1733                 :          0 :         mutex_unlock(&parent->lock);
    1734                 :          0 :         aa_put_ns(parent);
    1735                 :            : 
    1736                 :          0 :         return error;
    1737                 :            : }
    1738                 :            : 
    1739                 :          0 : static int ns_rmdir_op(struct inode *dir, struct dentry *dentry)
    1740                 :            : {
    1741                 :            :         struct aa_ns *ns, *parent;
    1742                 :            :         /* TODO: improve permission check */
    1743                 :            :         struct aa_label *label;
    1744                 :            :         int error;
    1745                 :            : 
    1746                 :          0 :         label = begin_current_label_crit_section();
    1747                 :          0 :         error = aa_may_manage_policy(label, NULL, AA_MAY_LOAD_POLICY);
    1748                 :          0 :         end_current_label_crit_section(label);
    1749                 :          0 :         if (error)
    1750                 :            :                 return error;
    1751                 :            : 
    1752                 :          0 :         parent = aa_get_ns(dir->i_private);
    1753                 :            :         /* rmdir calls the generic securityfs functions to remove files
    1754                 :            :          * from the apparmor dir. It is up to the apparmor ns locking
    1755                 :            :          * to avoid races.
    1756                 :            :          */
    1757                 :            :         inode_unlock(dir);
    1758                 :          0 :         inode_unlock(dentry->d_inode);
    1759                 :            : 
    1760                 :          0 :         mutex_lock_nested(&parent->lock, parent->level);
    1761                 :          0 :         ns = aa_get_ns(__aa_findn_ns(&parent->sub_ns, dentry->d_name.name,
    1762                 :            :                                      dentry->d_name.len));
    1763                 :          0 :         if (!ns) {
    1764                 :            :                 error = -ENOENT;
    1765                 :            :                 goto out;
    1766                 :            :         }
    1767                 :            :         AA_BUG(ns_dir(ns) != dentry);
    1768                 :            : 
    1769                 :          0 :         __aa_remove_ns(ns);
    1770                 :          0 :         aa_put_ns(ns);
    1771                 :            : 
    1772                 :            : out:
    1773                 :          0 :         mutex_unlock(&parent->lock);
    1774                 :            :         inode_lock_nested(dir, I_MUTEX_PARENT);
    1775                 :          0 :         inode_lock(dentry->d_inode);
    1776                 :          0 :         aa_put_ns(parent);
    1777                 :            : 
    1778                 :          0 :         return error;
    1779                 :            : }
    1780                 :            : 
    1781                 :            : static const struct inode_operations ns_dir_inode_operations = {
    1782                 :            :         .lookup         = simple_lookup,
    1783                 :            :         .mkdir          = ns_mkdir_op,
    1784                 :            :         .rmdir          = ns_rmdir_op,
    1785                 :            : };
    1786                 :            : 
    1787                 :          0 : static void __aa_fs_list_remove_rawdata(struct aa_ns *ns)
    1788                 :            : {
    1789                 :            :         struct aa_loaddata *ent, *tmp;
    1790                 :            : 
    1791                 :            :         AA_BUG(!mutex_is_locked(&ns->lock));
    1792                 :            : 
    1793                 :          0 :         list_for_each_entry_safe(ent, tmp, &ns->rawdata_list, list)
    1794                 :          0 :                 __aa_fs_remove_rawdata(ent);
    1795                 :          0 : }
    1796                 :            : 
    1797                 :            : /**
    1798                 :            :  *
    1799                 :            :  * Requires: @ns->lock held
    1800                 :            :  */
    1801                 :          0 : void __aafs_ns_rmdir(struct aa_ns *ns)
    1802                 :            : {
    1803                 :            :         struct aa_ns *sub;
    1804                 :            :         struct aa_profile *child;
    1805                 :            :         int i;
    1806                 :            : 
    1807                 :          0 :         if (!ns)
    1808                 :          0 :                 return;
    1809                 :            :         AA_BUG(!mutex_is_locked(&ns->lock));
    1810                 :            : 
    1811                 :          0 :         list_for_each_entry(child, &ns->base.profiles, base.list)
    1812                 :          0 :                 __aafs_profile_rmdir(child);
    1813                 :            : 
    1814                 :          0 :         list_for_each_entry(sub, &ns->sub_ns, base.list) {
    1815                 :          0 :                 mutex_lock_nested(&sub->lock, sub->level);
    1816                 :          0 :                 __aafs_ns_rmdir(sub);
    1817                 :          0 :                 mutex_unlock(&sub->lock);
    1818                 :            :         }
    1819                 :            : 
    1820                 :          0 :         __aa_fs_list_remove_rawdata(ns);
    1821                 :            : 
    1822                 :          0 :         if (ns_subns_dir(ns)) {
    1823                 :          0 :                 sub = d_inode(ns_subns_dir(ns))->i_private;
    1824                 :          0 :                 aa_put_ns(sub);
    1825                 :            :         }
    1826                 :          0 :         if (ns_subload(ns)) {
    1827                 :          0 :                 sub = d_inode(ns_subload(ns))->i_private;
    1828                 :          0 :                 aa_put_ns(sub);
    1829                 :            :         }
    1830                 :          0 :         if (ns_subreplace(ns)) {
    1831                 :          0 :                 sub = d_inode(ns_subreplace(ns))->i_private;
    1832                 :          0 :                 aa_put_ns(sub);
    1833                 :            :         }
    1834                 :          0 :         if (ns_subremove(ns)) {
    1835                 :          0 :                 sub = d_inode(ns_subremove(ns))->i_private;
    1836                 :          0 :                 aa_put_ns(sub);
    1837                 :            :         }
    1838                 :          0 :         if (ns_subrevision(ns)) {
    1839                 :          0 :                 sub = d_inode(ns_subrevision(ns))->i_private;
    1840                 :          0 :                 aa_put_ns(sub);
    1841                 :            :         }
    1842                 :            : 
    1843                 :          0 :         for (i = AAFS_NS_SIZEOF - 1; i >= 0; --i) {
    1844                 :          0 :                 aafs_remove(ns->dents[i]);
    1845                 :          0 :                 ns->dents[i] = NULL;
    1846                 :            :         }
    1847                 :            : }
    1848                 :            : 
    1849                 :            : /* assumes cleanup in caller */
    1850                 :          0 : static int __aafs_ns_mkdir_entries(struct aa_ns *ns, struct dentry *dir)
    1851                 :            : {
    1852                 :            :         struct dentry *dent;
    1853                 :            : 
    1854                 :            :         AA_BUG(!ns);
    1855                 :            :         AA_BUG(!dir);
    1856                 :            : 
    1857                 :            :         dent = aafs_create_dir("profiles", dir);
    1858                 :          0 :         if (IS_ERR(dent))
    1859                 :          0 :                 return PTR_ERR(dent);
    1860                 :          0 :         ns_subprofs_dir(ns) = dent;
    1861                 :            : 
    1862                 :            :         dent = aafs_create_dir("raw_data", dir);
    1863                 :          0 :         if (IS_ERR(dent))
    1864                 :          0 :                 return PTR_ERR(dent);
    1865                 :          0 :         ns_subdata_dir(ns) = dent;
    1866                 :            : 
    1867                 :            :         dent = aafs_create_file("revision", 0444, dir, ns,
    1868                 :            :                                 &aa_fs_ns_revision_fops);
    1869                 :          0 :         if (IS_ERR(dent))
    1870                 :          0 :                 return PTR_ERR(dent);
    1871                 :            :         aa_get_ns(ns);
    1872                 :          0 :         ns_subrevision(ns) = dent;
    1873                 :            : 
    1874                 :            :         dent = aafs_create_file(".load", 0640, dir, ns,
    1875                 :            :                                       &aa_fs_profile_load);
    1876                 :          0 :         if (IS_ERR(dent))
    1877                 :          0 :                 return PTR_ERR(dent);
    1878                 :            :         aa_get_ns(ns);
    1879                 :          0 :         ns_subload(ns) = dent;
    1880                 :            : 
    1881                 :            :         dent = aafs_create_file(".replace", 0640, dir, ns,
    1882                 :            :                                       &aa_fs_profile_replace);
    1883                 :          0 :         if (IS_ERR(dent))
    1884                 :          0 :                 return PTR_ERR(dent);
    1885                 :            :         aa_get_ns(ns);
    1886                 :          0 :         ns_subreplace(ns) = dent;
    1887                 :            : 
    1888                 :            :         dent = aafs_create_file(".remove", 0640, dir, ns,
    1889                 :            :                                       &aa_fs_profile_remove);
    1890                 :          0 :         if (IS_ERR(dent))
    1891                 :          0 :                 return PTR_ERR(dent);
    1892                 :            :         aa_get_ns(ns);
    1893                 :          0 :         ns_subremove(ns) = dent;
    1894                 :            : 
    1895                 :            :           /* use create_dentry so we can supply private data */
    1896                 :          0 :         dent = aafs_create("namespaces", S_IFDIR | 0755, dir, ns, NULL, NULL,
    1897                 :            :                            &ns_dir_inode_operations);
    1898                 :          0 :         if (IS_ERR(dent))
    1899                 :          0 :                 return PTR_ERR(dent);
    1900                 :            :         aa_get_ns(ns);
    1901                 :          0 :         ns_subns_dir(ns) = dent;
    1902                 :            : 
    1903                 :          0 :         return 0;
    1904                 :            : }
    1905                 :            : 
    1906                 :            : /*
    1907                 :            :  * Requires: @ns->lock held
    1908                 :            :  */
    1909                 :          0 : int __aafs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, const char *name,
    1910                 :            :                     struct dentry *dent)
    1911                 :            : {
    1912                 :            :         struct aa_ns *sub;
    1913                 :            :         struct aa_profile *child;
    1914                 :            :         struct dentry *dir;
    1915                 :            :         int error;
    1916                 :            : 
    1917                 :            :         AA_BUG(!ns);
    1918                 :            :         AA_BUG(!parent);
    1919                 :            :         AA_BUG(!mutex_is_locked(&ns->lock));
    1920                 :            : 
    1921                 :          0 :         if (!name)
    1922                 :          0 :                 name = ns->base.name;
    1923                 :            : 
    1924                 :          0 :         if (!dent) {
    1925                 :            :                 /* create ns dir if it doesn't already exist */
    1926                 :            :                 dent = aafs_create_dir(name, parent);
    1927                 :          0 :                 if (IS_ERR(dent))
    1928                 :            :                         goto fail;
    1929                 :            :         } else
    1930                 :            :                 dget(dent);
    1931                 :          0 :         ns_dir(ns) = dir = dent;
    1932                 :          0 :         error = __aafs_ns_mkdir_entries(ns, dir);
    1933                 :          0 :         if (error)
    1934                 :            :                 goto fail2;
    1935                 :            : 
    1936                 :            :         /* profiles */
    1937                 :          0 :         list_for_each_entry(child, &ns->base.profiles, base.list) {
    1938                 :          0 :                 error = __aafs_profile_mkdir(child, ns_subprofs_dir(ns));
    1939                 :          0 :                 if (error)
    1940                 :            :                         goto fail2;
    1941                 :            :         }
    1942                 :            : 
    1943                 :            :         /* subnamespaces */
    1944                 :          0 :         list_for_each_entry(sub, &ns->sub_ns, base.list) {
    1945                 :          0 :                 mutex_lock_nested(&sub->lock, sub->level);
    1946                 :          0 :                 error = __aafs_ns_mkdir(sub, ns_subns_dir(ns), NULL, NULL);
    1947                 :          0 :                 mutex_unlock(&sub->lock);
    1948                 :          0 :                 if (error)
    1949                 :            :                         goto fail2;
    1950                 :            :         }
    1951                 :            : 
    1952                 :            :         return 0;
    1953                 :            : 
    1954                 :            : fail:
    1955                 :            :         error = PTR_ERR(dent);
    1956                 :            : 
    1957                 :            : fail2:
    1958                 :          0 :         __aafs_ns_rmdir(ns);
    1959                 :            : 
    1960                 :          0 :         return error;
    1961                 :            : }
    1962                 :            : 
    1963                 :            : 
    1964                 :            : #define list_entry_is_head(pos, head, member) (&pos->member == (head))
    1965                 :            : 
    1966                 :            : /**
    1967                 :            :  * __next_ns - find the next namespace to list
    1968                 :            :  * @root: root namespace to stop search at (NOT NULL)
    1969                 :            :  * @ns: current ns position (NOT NULL)
    1970                 :            :  *
    1971                 :            :  * Find the next namespace from @ns under @root and handle all locking needed
    1972                 :            :  * while switching current namespace.
    1973                 :            :  *
    1974                 :            :  * Returns: next namespace or NULL if at last namespace under @root
    1975                 :            :  * Requires: ns->parent->lock to be held
    1976                 :            :  * NOTE: will not unlock root->lock
    1977                 :            :  */
    1978                 :          0 : static struct aa_ns *__next_ns(struct aa_ns *root, struct aa_ns *ns)
    1979                 :            : {
    1980                 :            :         struct aa_ns *parent, *next;
    1981                 :            : 
    1982                 :            :         AA_BUG(!root);
    1983                 :            :         AA_BUG(!ns);
    1984                 :            :         AA_BUG(ns != root && !mutex_is_locked(&ns->parent->lock));
    1985                 :            : 
    1986                 :            :         /* is next namespace a child */
    1987                 :          0 :         if (!list_empty(&ns->sub_ns)) {
    1988                 :          0 :                 next = list_first_entry(&ns->sub_ns, typeof(*ns), base.list);
    1989                 :          0 :                 mutex_lock_nested(&next->lock, next->level);
    1990                 :          0 :                 return next;
    1991                 :            :         }
    1992                 :            : 
    1993                 :            :         /* check if the next ns is a sibling, parent, gp, .. */
    1994                 :          0 :         parent = ns->parent;
    1995                 :          0 :         while (ns != root) {
    1996                 :          0 :                 mutex_unlock(&ns->lock);
    1997                 :          0 :                 next = list_next_entry(ns, base.list);
    1998                 :          0 :                 if (!list_entry_is_head(next, &parent->sub_ns, base.list)) {
    1999                 :          0 :                         mutex_lock_nested(&next->lock, next->level);
    2000                 :          0 :                         return next;
    2001                 :            :                 }
    2002                 :            :                 ns = parent;
    2003                 :          0 :                 parent = parent->parent;
    2004                 :            :         }
    2005                 :            : 
    2006                 :            :         return NULL;
    2007                 :            : }
    2008                 :            : 
    2009                 :            : /**
    2010                 :            :  * __first_profile - find the first profile in a namespace
    2011                 :            :  * @root: namespace that is root of profiles being displayed (NOT NULL)
    2012                 :            :  * @ns: namespace to start in   (NOT NULL)
    2013                 :            :  *
    2014                 :            :  * Returns: unrefcounted profile or NULL if no profile
    2015                 :            :  * Requires: profile->ns.lock to be held
    2016                 :            :  */
    2017                 :          0 : static struct aa_profile *__first_profile(struct aa_ns *root,
    2018                 :            :                                           struct aa_ns *ns)
    2019                 :            : {
    2020                 :            :         AA_BUG(!root);
    2021                 :            :         AA_BUG(ns && !mutex_is_locked(&ns->lock));
    2022                 :            : 
    2023                 :          0 :         for (; ns; ns = __next_ns(root, ns)) {
    2024                 :          0 :                 if (!list_empty(&ns->base.profiles))
    2025                 :          0 :                         return list_first_entry(&ns->base.profiles,
    2026                 :            :                                                 struct aa_profile, base.list);
    2027                 :            :         }
    2028                 :            :         return NULL;
    2029                 :            : }
    2030                 :            : 
    2031                 :            : /**
    2032                 :            :  * __next_profile - step to the next profile in a profile tree
    2033                 :            :  * @profile: current profile in tree (NOT NULL)
    2034                 :            :  *
    2035                 :            :  * Perform a depth first traversal on the profile tree in a namespace
    2036                 :            :  *
    2037                 :            :  * Returns: next profile or NULL if done
    2038                 :            :  * Requires: profile->ns.lock to be held
    2039                 :            :  */
    2040                 :          0 : static struct aa_profile *__next_profile(struct aa_profile *p)
    2041                 :            : {
    2042                 :            :         struct aa_profile *parent;
    2043                 :          0 :         struct aa_ns *ns = p->ns;
    2044                 :            : 
    2045                 :            :         AA_BUG(!mutex_is_locked(&profiles_ns(p)->lock));
    2046                 :            : 
    2047                 :            :         /* is next profile a child */
    2048                 :          0 :         if (!list_empty(&p->base.profiles))
    2049                 :          0 :                 return list_first_entry(&p->base.profiles, typeof(*p),
    2050                 :            :                                         base.list);
    2051                 :            : 
    2052                 :            :         /* is next profile a sibling, parent sibling, gp, sibling, .. */
    2053                 :          0 :         parent = rcu_dereference_protected(p->parent,
    2054                 :            :                                            mutex_is_locked(&p->ns->lock));
    2055                 :          0 :         while (parent) {
    2056                 :          0 :                 p = list_next_entry(p, base.list);
    2057                 :          0 :                 if (!list_entry_is_head(p, &parent->base.profiles, base.list))
    2058                 :          0 :                         return p;
    2059                 :            :                 p = parent;
    2060                 :          0 :                 parent = rcu_dereference_protected(parent->parent,
    2061                 :            :                                             mutex_is_locked(&parent->ns->lock));
    2062                 :            :         }
    2063                 :            : 
    2064                 :            :         /* is next another profile in the namespace */
    2065                 :          0 :         p = list_next_entry(p, base.list);
    2066                 :          0 :         if (!list_entry_is_head(p, &ns->base.profiles, base.list))
    2067                 :          0 :                 return p;
    2068                 :            : 
    2069                 :            :         return NULL;
    2070                 :            : }
    2071                 :            : 
    2072                 :            : /**
    2073                 :            :  * next_profile - step to the next profile in where ever it may be
    2074                 :            :  * @root: root namespace  (NOT NULL)
    2075                 :            :  * @profile: current profile  (NOT NULL)
    2076                 :            :  *
    2077                 :            :  * Returns: next profile or NULL if there isn't one
    2078                 :            :  */
    2079                 :          0 : static struct aa_profile *next_profile(struct aa_ns *root,
    2080                 :            :                                        struct aa_profile *profile)
    2081                 :            : {
    2082                 :          0 :         struct aa_profile *next = __next_profile(profile);
    2083                 :          0 :         if (next)
    2084                 :            :                 return next;
    2085                 :            : 
    2086                 :            :         /* finished all profiles in namespace move to next namespace */
    2087                 :          0 :         return __first_profile(root, __next_ns(root, profile->ns));
    2088                 :            : }
    2089                 :            : 
    2090                 :            : /**
    2091                 :            :  * p_start - start a depth first traversal of profile tree
    2092                 :            :  * @f: seq_file to fill
    2093                 :            :  * @pos: current position
    2094                 :            :  *
    2095                 :            :  * Returns: first profile under current namespace or NULL if none found
    2096                 :            :  *
    2097                 :            :  * acquires first ns->lock
    2098                 :            :  */
    2099                 :          0 : static void *p_start(struct seq_file *f, loff_t *pos)
    2100                 :            : {
    2101                 :            :         struct aa_profile *profile = NULL;
    2102                 :          0 :         struct aa_ns *root = aa_get_current_ns();
    2103                 :          0 :         loff_t l = *pos;
    2104                 :          0 :         f->private = root;
    2105                 :            : 
    2106                 :            :         /* find the first profile */
    2107                 :          0 :         mutex_lock_nested(&root->lock, root->level);
    2108                 :          0 :         profile = __first_profile(root, root);
    2109                 :            : 
    2110                 :            :         /* skip to position */
    2111                 :          0 :         for (; profile && l > 0; l--)
    2112                 :          0 :                 profile = next_profile(root, profile);
    2113                 :            : 
    2114                 :          0 :         return profile;
    2115                 :            : }
    2116                 :            : 
    2117                 :            : /**
    2118                 :            :  * p_next - read the next profile entry
    2119                 :            :  * @f: seq_file to fill
    2120                 :            :  * @p: profile previously returned
    2121                 :            :  * @pos: current position
    2122                 :            :  *
    2123                 :            :  * Returns: next profile after @p or NULL if none
    2124                 :            :  *
    2125                 :            :  * may acquire/release locks in namespace tree as necessary
    2126                 :            :  */
    2127                 :          0 : static void *p_next(struct seq_file *f, void *p, loff_t *pos)
    2128                 :            : {
    2129                 :            :         struct aa_profile *profile = p;
    2130                 :          0 :         struct aa_ns *ns = f->private;
    2131                 :          0 :         (*pos)++;
    2132                 :            : 
    2133                 :          0 :         return next_profile(ns, profile);
    2134                 :            : }
    2135                 :            : 
    2136                 :            : /**
    2137                 :            :  * p_stop - stop depth first traversal
    2138                 :            :  * @f: seq_file we are filling
    2139                 :            :  * @p: the last profile writen
    2140                 :            :  *
    2141                 :            :  * Release all locking done by p_start/p_next on namespace tree
    2142                 :            :  */
    2143                 :          0 : static void p_stop(struct seq_file *f, void *p)
    2144                 :            : {
    2145                 :            :         struct aa_profile *profile = p;
    2146                 :          0 :         struct aa_ns *root = f->private, *ns;
    2147                 :            : 
    2148                 :          0 :         if (profile) {
    2149                 :          0 :                 for (ns = profile->ns; ns && ns != root; ns = ns->parent)
    2150                 :          0 :                         mutex_unlock(&ns->lock);
    2151                 :            :         }
    2152                 :          0 :         mutex_unlock(&root->lock);
    2153                 :          0 :         aa_put_ns(root);
    2154                 :          0 : }
    2155                 :            : 
    2156                 :            : /**
    2157                 :            :  * seq_show_profile - show a profile entry
    2158                 :            :  * @f: seq_file to file
    2159                 :            :  * @p: current position (profile)    (NOT NULL)
    2160                 :            :  *
    2161                 :            :  * Returns: error on failure
    2162                 :            :  */
    2163                 :          0 : static int seq_show_profile(struct seq_file *f, void *p)
    2164                 :            : {
    2165                 :            :         struct aa_profile *profile = (struct aa_profile *)p;
    2166                 :          0 :         struct aa_ns *root = f->private;
    2167                 :            : 
    2168                 :          0 :         aa_label_seq_xprint(f, root, &profile->label,
    2169                 :            :                             FLAG_SHOW_MODE | FLAG_VIEW_SUBNS, GFP_KERNEL);
    2170                 :          0 :         seq_putc(f, '\n');
    2171                 :            : 
    2172                 :          0 :         return 0;
    2173                 :            : }
    2174                 :            : 
    2175                 :            : static const struct seq_operations aa_sfs_profiles_op = {
    2176                 :            :         .start = p_start,
    2177                 :            :         .next = p_next,
    2178                 :            :         .stop = p_stop,
    2179                 :            :         .show = seq_show_profile,
    2180                 :            : };
    2181                 :            : 
    2182                 :          0 : static int profiles_open(struct inode *inode, struct file *file)
    2183                 :            : {
    2184                 :          0 :         if (!policy_view_capable(NULL))
    2185                 :            :                 return -EACCES;
    2186                 :            : 
    2187                 :          0 :         return seq_open(file, &aa_sfs_profiles_op);
    2188                 :            : }
    2189                 :            : 
    2190                 :          0 : static int profiles_release(struct inode *inode, struct file *file)
    2191                 :            : {
    2192                 :          0 :         return seq_release(inode, file);
    2193                 :            : }
    2194                 :            : 
    2195                 :            : static const struct file_operations aa_sfs_profiles_fops = {
    2196                 :            :         .open = profiles_open,
    2197                 :            :         .read = seq_read,
    2198                 :            :         .llseek = seq_lseek,
    2199                 :            :         .release = profiles_release,
    2200                 :            : };
    2201                 :            : 
    2202                 :            : 
    2203                 :            : /** Base file system setup **/
    2204                 :            : static struct aa_sfs_entry aa_sfs_entry_file[] = {
    2205                 :            :         AA_SFS_FILE_STRING("mask",
    2206                 :            :                            "create read write exec append mmap_exec link lock"),
    2207                 :            :         { }
    2208                 :            : };
    2209                 :            : 
    2210                 :            : static struct aa_sfs_entry aa_sfs_entry_ptrace[] = {
    2211                 :            :         AA_SFS_FILE_STRING("mask", "read trace"),
    2212                 :            :         { }
    2213                 :            : };
    2214                 :            : 
    2215                 :            : static struct aa_sfs_entry aa_sfs_entry_signal[] = {
    2216                 :            :         AA_SFS_FILE_STRING("mask", AA_SFS_SIG_MASK),
    2217                 :            :         { }
    2218                 :            : };
    2219                 :            : 
    2220                 :            : static struct aa_sfs_entry aa_sfs_entry_attach[] = {
    2221                 :            :         AA_SFS_FILE_BOOLEAN("xattr", 1),
    2222                 :            :         { }
    2223                 :            : };
    2224                 :            : static struct aa_sfs_entry aa_sfs_entry_domain[] = {
    2225                 :            :         AA_SFS_FILE_BOOLEAN("change_hat",     1),
    2226                 :            :         AA_SFS_FILE_BOOLEAN("change_hatv",    1),
    2227                 :            :         AA_SFS_FILE_BOOLEAN("change_onexec",  1),
    2228                 :            :         AA_SFS_FILE_BOOLEAN("change_profile", 1),
    2229                 :            :         AA_SFS_FILE_BOOLEAN("stack",          1),
    2230                 :            :         AA_SFS_FILE_BOOLEAN("fix_binfmt_elf_mmap",    1),
    2231                 :            :         AA_SFS_FILE_BOOLEAN("post_nnp_subset",        1),
    2232                 :            :         AA_SFS_FILE_BOOLEAN("computed_longest_left",  1),
    2233                 :            :         AA_SFS_DIR("attach_conditions",               aa_sfs_entry_attach),
    2234                 :            :         AA_SFS_FILE_STRING("version", "1.2"),
    2235                 :            :         { }
    2236                 :            : };
    2237                 :            : 
    2238                 :            : static struct aa_sfs_entry aa_sfs_entry_versions[] = {
    2239                 :            :         AA_SFS_FILE_BOOLEAN("v5",     1),
    2240                 :            :         AA_SFS_FILE_BOOLEAN("v6",     1),
    2241                 :            :         AA_SFS_FILE_BOOLEAN("v7",     1),
    2242                 :            :         AA_SFS_FILE_BOOLEAN("v8",     1),
    2243                 :            :         { }
    2244                 :            : };
    2245                 :            : 
    2246                 :            : static struct aa_sfs_entry aa_sfs_entry_policy[] = {
    2247                 :            :         AA_SFS_DIR("versions",                        aa_sfs_entry_versions),
    2248                 :            :         AA_SFS_FILE_BOOLEAN("set_load",               1),
    2249                 :            :         { }
    2250                 :            : };
    2251                 :            : 
    2252                 :            : static struct aa_sfs_entry aa_sfs_entry_mount[] = {
    2253                 :            :         AA_SFS_FILE_STRING("mask", "mount umount pivot_root"),
    2254                 :            :         { }
    2255                 :            : };
    2256                 :            : 
    2257                 :            : static struct aa_sfs_entry aa_sfs_entry_ns[] = {
    2258                 :            :         AA_SFS_FILE_BOOLEAN("profile",                1),
    2259                 :            :         AA_SFS_FILE_BOOLEAN("pivot_root",     0),
    2260                 :            :         { }
    2261                 :            : };
    2262                 :            : 
    2263                 :            : static struct aa_sfs_entry aa_sfs_entry_query_label[] = {
    2264                 :            :         AA_SFS_FILE_STRING("perms", "allow deny audit quiet"),
    2265                 :            :         AA_SFS_FILE_BOOLEAN("data",           1),
    2266                 :            :         AA_SFS_FILE_BOOLEAN("multi_transaction",      1),
    2267                 :            :         { }
    2268                 :            : };
    2269                 :            : 
    2270                 :            : static struct aa_sfs_entry aa_sfs_entry_query[] = {
    2271                 :            :         AA_SFS_DIR("label",                   aa_sfs_entry_query_label),
    2272                 :            :         { }
    2273                 :            : };
    2274                 :            : static struct aa_sfs_entry aa_sfs_entry_features[] = {
    2275                 :            :         AA_SFS_DIR("policy",                  aa_sfs_entry_policy),
    2276                 :            :         AA_SFS_DIR("domain",                  aa_sfs_entry_domain),
    2277                 :            :         AA_SFS_DIR("file",                    aa_sfs_entry_file),
    2278                 :            :         AA_SFS_DIR("network_v8",              aa_sfs_entry_network),
    2279                 :            :         AA_SFS_DIR("mount",                   aa_sfs_entry_mount),
    2280                 :            :         AA_SFS_DIR("namespaces",              aa_sfs_entry_ns),
    2281                 :            :         AA_SFS_FILE_U64("capability",         VFS_CAP_FLAGS_MASK),
    2282                 :            :         AA_SFS_DIR("rlimit",                  aa_sfs_entry_rlimit),
    2283                 :            :         AA_SFS_DIR("caps",                    aa_sfs_entry_caps),
    2284                 :            :         AA_SFS_DIR("ptrace",                  aa_sfs_entry_ptrace),
    2285                 :            :         AA_SFS_DIR("signal",                  aa_sfs_entry_signal),
    2286                 :            :         AA_SFS_DIR("query",                   aa_sfs_entry_query),
    2287                 :            :         { }
    2288                 :            : };
    2289                 :            : 
    2290                 :            : static struct aa_sfs_entry aa_sfs_entry_apparmor[] = {
    2291                 :            :         AA_SFS_FILE_FOPS(".access", 0666, &aa_sfs_access),
    2292                 :            :         AA_SFS_FILE_FOPS(".stacked", 0444, &seq_ns_stacked_fops),
    2293                 :            :         AA_SFS_FILE_FOPS(".ns_stacked", 0444, &seq_ns_nsstacked_fops),
    2294                 :            :         AA_SFS_FILE_FOPS(".ns_level", 0444, &seq_ns_level_fops),
    2295                 :            :         AA_SFS_FILE_FOPS(".ns_name", 0444, &seq_ns_name_fops),
    2296                 :            :         AA_SFS_FILE_FOPS("profiles", 0444, &aa_sfs_profiles_fops),
    2297                 :            :         AA_SFS_DIR("features", aa_sfs_entry_features),
    2298                 :            :         { }
    2299                 :            : };
    2300                 :            : 
    2301                 :            : static struct aa_sfs_entry aa_sfs_entry =
    2302                 :            :         AA_SFS_DIR("apparmor", aa_sfs_entry_apparmor);
    2303                 :            : 
    2304                 :            : /**
    2305                 :            :  * entry_create_file - create a file entry in the apparmor securityfs
    2306                 :            :  * @fs_file: aa_sfs_entry to build an entry for (NOT NULL)
    2307                 :            :  * @parent: the parent dentry in the securityfs
    2308                 :            :  *
    2309                 :            :  * Use entry_remove_file to remove entries created with this fn.
    2310                 :            :  */
    2311                 :          0 : static int __init entry_create_file(struct aa_sfs_entry *fs_file,
    2312                 :            :                                     struct dentry *parent)
    2313                 :            : {
    2314                 :            :         int error = 0;
    2315                 :            : 
    2316                 :          0 :         fs_file->dentry = securityfs_create_file(fs_file->name,
    2317                 :          0 :                                                  S_IFREG | fs_file->mode,
    2318                 :            :                                                  parent, fs_file,
    2319                 :            :                                                  fs_file->file_ops);
    2320                 :          0 :         if (IS_ERR(fs_file->dentry)) {
    2321                 :            :                 error = PTR_ERR(fs_file->dentry);
    2322                 :          0 :                 fs_file->dentry = NULL;
    2323                 :            :         }
    2324                 :          0 :         return error;
    2325                 :            : }
    2326                 :            : 
    2327                 :            : static void __init entry_remove_dir(struct aa_sfs_entry *fs_dir);
    2328                 :            : /**
    2329                 :            :  * entry_create_dir - recursively create a directory entry in the securityfs
    2330                 :            :  * @fs_dir: aa_sfs_entry (and all child entries) to build (NOT NULL)
    2331                 :            :  * @parent: the parent dentry in the securityfs
    2332                 :            :  *
    2333                 :            :  * Use entry_remove_dir to remove entries created with this fn.
    2334                 :            :  */
    2335                 :          0 : static int __init entry_create_dir(struct aa_sfs_entry *fs_dir,
    2336                 :            :                                    struct dentry *parent)
    2337                 :            : {
    2338                 :            :         struct aa_sfs_entry *fs_file;
    2339                 :            :         struct dentry *dir;
    2340                 :            :         int error;
    2341                 :            : 
    2342                 :          0 :         dir = securityfs_create_dir(fs_dir->name, parent);
    2343                 :          0 :         if (IS_ERR(dir))
    2344                 :          0 :                 return PTR_ERR(dir);
    2345                 :          0 :         fs_dir->dentry = dir;
    2346                 :            : 
    2347                 :          0 :         for (fs_file = fs_dir->v.files; fs_file && fs_file->name; ++fs_file) {
    2348                 :          0 :                 if (fs_file->v_type == AA_SFS_TYPE_DIR)
    2349                 :          0 :                         error = entry_create_dir(fs_file, fs_dir->dentry);
    2350                 :            :                 else
    2351                 :          0 :                         error = entry_create_file(fs_file, fs_dir->dentry);
    2352                 :          0 :                 if (error)
    2353                 :            :                         goto failed;
    2354                 :            :         }
    2355                 :            : 
    2356                 :            :         return 0;
    2357                 :            : 
    2358                 :            : failed:
    2359                 :          0 :         entry_remove_dir(fs_dir);
    2360                 :            : 
    2361                 :          0 :         return error;
    2362                 :            : }
    2363                 :            : 
    2364                 :            : /**
    2365                 :            :  * entry_remove_file - drop a single file entry in the apparmor securityfs
    2366                 :            :  * @fs_file: aa_sfs_entry to detach from the securityfs (NOT NULL)
    2367                 :            :  */
    2368                 :          0 : static void __init entry_remove_file(struct aa_sfs_entry *fs_file)
    2369                 :            : {
    2370                 :          0 :         if (!fs_file->dentry)
    2371                 :          0 :                 return;
    2372                 :            : 
    2373                 :          0 :         securityfs_remove(fs_file->dentry);
    2374                 :          0 :         fs_file->dentry = NULL;
    2375                 :            : }
    2376                 :            : 
    2377                 :            : /**
    2378                 :            :  * entry_remove_dir - recursively drop a directory entry from the securityfs
    2379                 :            :  * @fs_dir: aa_sfs_entry (and all child entries) to detach (NOT NULL)
    2380                 :            :  */
    2381                 :          0 : static void __init entry_remove_dir(struct aa_sfs_entry *fs_dir)
    2382                 :            : {
    2383                 :            :         struct aa_sfs_entry *fs_file;
    2384                 :            : 
    2385                 :          0 :         for (fs_file = fs_dir->v.files; fs_file && fs_file->name; ++fs_file) {
    2386                 :          0 :                 if (fs_file->v_type == AA_SFS_TYPE_DIR)
    2387                 :          0 :                         entry_remove_dir(fs_file);
    2388                 :            :                 else
    2389                 :          0 :                         entry_remove_file(fs_file);
    2390                 :            :         }
    2391                 :            : 
    2392                 :          0 :         entry_remove_file(fs_dir);
    2393                 :          0 : }
    2394                 :            : 
    2395                 :            : /**
    2396                 :            :  * aa_destroy_aafs - cleanup and free aafs
    2397                 :            :  *
    2398                 :            :  * releases dentries allocated by aa_create_aafs
    2399                 :            :  */
    2400                 :          0 : void __init aa_destroy_aafs(void)
    2401                 :            : {
    2402                 :          0 :         entry_remove_dir(&aa_sfs_entry);
    2403                 :          0 : }
    2404                 :            : 
    2405                 :            : 
    2406                 :            : #define NULL_FILE_NAME ".null"
    2407                 :            : struct path aa_null;
    2408                 :            : 
    2409                 :          0 : static int aa_mk_null_file(struct dentry *parent)
    2410                 :            : {
    2411                 :          0 :         struct vfsmount *mount = NULL;
    2412                 :            :         struct dentry *dentry;
    2413                 :            :         struct inode *inode;
    2414                 :          0 :         int count = 0;
    2415                 :          0 :         int error = simple_pin_fs(parent->d_sb->s_type, &mount, &count);
    2416                 :            : 
    2417                 :          0 :         if (error)
    2418                 :            :                 return error;
    2419                 :            : 
    2420                 :            :         inode_lock(d_inode(parent));
    2421                 :          0 :         dentry = lookup_one_len(NULL_FILE_NAME, parent, strlen(NULL_FILE_NAME));
    2422                 :          0 :         if (IS_ERR(dentry)) {
    2423                 :            :                 error = PTR_ERR(dentry);
    2424                 :          0 :                 goto out;
    2425                 :            :         }
    2426                 :          0 :         inode = new_inode(parent->d_inode->i_sb);
    2427                 :          0 :         if (!inode) {
    2428                 :            :                 error = -ENOMEM;
    2429                 :            :                 goto out1;
    2430                 :            :         }
    2431                 :            : 
    2432                 :          0 :         inode->i_ino = get_next_ino();
    2433                 :          0 :         inode->i_mode = S_IFCHR | S_IRUGO | S_IWUGO;
    2434                 :          0 :         inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
    2435                 :          0 :         init_special_inode(inode, S_IFCHR | S_IRUGO | S_IWUGO,
    2436                 :            :                            MKDEV(MEM_MAJOR, 3));
    2437                 :          0 :         d_instantiate(dentry, inode);
    2438                 :          0 :         aa_null.dentry = dget(dentry);
    2439                 :          0 :         aa_null.mnt = mntget(mount);
    2440                 :            : 
    2441                 :            :         error = 0;
    2442                 :            : 
    2443                 :            : out1:
    2444                 :          0 :         dput(dentry);
    2445                 :            : out:
    2446                 :            :         inode_unlock(d_inode(parent));
    2447                 :          0 :         simple_release_fs(&mount, &count);
    2448                 :          0 :         return error;
    2449                 :            : }
    2450                 :            : 
    2451                 :            : 
    2452                 :            : 
    2453                 :          0 : static const char *policy_get_link(struct dentry *dentry,
    2454                 :            :                                    struct inode *inode,
    2455                 :            :                                    struct delayed_call *done)
    2456                 :            : {
    2457                 :            :         struct aa_ns *ns;
    2458                 :            :         struct path path;
    2459                 :            : 
    2460                 :          0 :         if (!dentry)
    2461                 :            :                 return ERR_PTR(-ECHILD);
    2462                 :          0 :         ns = aa_get_current_ns();
    2463                 :          0 :         path.mnt = mntget(aafs_mnt);
    2464                 :          0 :         path.dentry = dget(ns_dir(ns));
    2465                 :          0 :         nd_jump_link(&path);
    2466                 :          0 :         aa_put_ns(ns);
    2467                 :            : 
    2468                 :          0 :         return NULL;
    2469                 :            : }
    2470                 :            : 
    2471                 :          0 : static int policy_readlink(struct dentry *dentry, char __user *buffer,
    2472                 :            :                            int buflen)
    2473                 :            : {
    2474                 :            :         char name[32];
    2475                 :            :         int res;
    2476                 :            : 
    2477                 :          0 :         res = snprintf(name, sizeof(name), "%s:[%lu]", AAFS_NAME,
    2478                 :            :                        d_inode(dentry)->i_ino);
    2479                 :          0 :         if (res > 0 && res < sizeof(name))
    2480                 :          0 :                 res = readlink_copy(buffer, buflen, name);
    2481                 :            :         else
    2482                 :            :                 res = -ENOENT;
    2483                 :            : 
    2484                 :          0 :         return res;
    2485                 :            : }
    2486                 :            : 
    2487                 :            : static const struct inode_operations policy_link_iops = {
    2488                 :            :         .readlink       = policy_readlink,
    2489                 :            :         .get_link       = policy_get_link,
    2490                 :            : };
    2491                 :            : 
    2492                 :            : 
    2493                 :            : /**
    2494                 :            :  * aa_create_aafs - create the apparmor security filesystem
    2495                 :            :  *
    2496                 :            :  * dentries created here are released by aa_destroy_aafs
    2497                 :            :  *
    2498                 :            :  * Returns: error on failure
    2499                 :            :  */
    2500                 :          3 : static int __init aa_create_aafs(void)
    2501                 :            : {
    2502                 :            :         struct dentry *dent;
    2503                 :            :         int error;
    2504                 :            : 
    2505                 :          3 :         if (!apparmor_initialized)
    2506                 :            :                 return 0;
    2507                 :            : 
    2508                 :          0 :         if (aa_sfs_entry.dentry) {
    2509                 :          0 :                 AA_ERROR("%s: AppArmor securityfs already exists\n", __func__);
    2510                 :            :                 return -EEXIST;
    2511                 :            :         }
    2512                 :            : 
    2513                 :            :         /* setup apparmorfs used to virtualize policy/ */
    2514                 :          0 :         aafs_mnt = kern_mount(&aafs_ops);
    2515                 :          0 :         if (IS_ERR(aafs_mnt))
    2516                 :          0 :                 panic("can't set apparmorfs up\n");
    2517                 :          0 :         aafs_mnt->mnt_sb->s_flags &= ~SB_NOUSER;
    2518                 :            : 
    2519                 :            :         /* Populate fs tree. */
    2520                 :          0 :         error = entry_create_dir(&aa_sfs_entry, NULL);
    2521                 :          0 :         if (error)
    2522                 :            :                 goto error;
    2523                 :            : 
    2524                 :          0 :         dent = securityfs_create_file(".load", 0666, aa_sfs_entry.dentry,
    2525                 :            :                                       NULL, &aa_fs_profile_load);
    2526                 :          0 :         if (IS_ERR(dent))
    2527                 :            :                 goto dent_error;
    2528                 :          0 :         ns_subload(root_ns) = dent;
    2529                 :            : 
    2530                 :          0 :         dent = securityfs_create_file(".replace", 0666, aa_sfs_entry.dentry,
    2531                 :            :                                       NULL, &aa_fs_profile_replace);
    2532                 :          0 :         if (IS_ERR(dent))
    2533                 :            :                 goto dent_error;
    2534                 :          0 :         ns_subreplace(root_ns) = dent;
    2535                 :            : 
    2536                 :          0 :         dent = securityfs_create_file(".remove", 0666, aa_sfs_entry.dentry,
    2537                 :            :                                       NULL, &aa_fs_profile_remove);
    2538                 :          0 :         if (IS_ERR(dent))
    2539                 :            :                 goto dent_error;
    2540                 :          0 :         ns_subremove(root_ns) = dent;
    2541                 :            : 
    2542                 :          0 :         dent = securityfs_create_file("revision", 0444, aa_sfs_entry.dentry,
    2543                 :            :                                       NULL, &aa_fs_ns_revision_fops);
    2544                 :          0 :         if (IS_ERR(dent))
    2545                 :            :                 goto dent_error;
    2546                 :          0 :         ns_subrevision(root_ns) = dent;
    2547                 :            : 
    2548                 :            :         /* policy tree referenced by magic policy symlink */
    2549                 :          0 :         mutex_lock_nested(&root_ns->lock, root_ns->level);
    2550                 :          0 :         error = __aafs_ns_mkdir(root_ns, aafs_mnt->mnt_root, ".policy",
    2551                 :          0 :                                 aafs_mnt->mnt_root);
    2552                 :          0 :         mutex_unlock(&root_ns->lock);
    2553                 :          0 :         if (error)
    2554                 :            :                 goto error;
    2555                 :            : 
    2556                 :            :         /* magic symlink similar to nsfs redirects based on task policy */
    2557                 :          0 :         dent = securityfs_create_symlink("policy", aa_sfs_entry.dentry,
    2558                 :            :                                          NULL, &policy_link_iops);
    2559                 :          0 :         if (IS_ERR(dent))
    2560                 :            :                 goto dent_error;
    2561                 :            : 
    2562                 :          0 :         error = aa_mk_null_file(aa_sfs_entry.dentry);
    2563                 :          0 :         if (error)
    2564                 :            :                 goto error;
    2565                 :            : 
    2566                 :            :         /* TODO: add default profile to apparmorfs */
    2567                 :            : 
    2568                 :            :         /* Report that AppArmor fs is enabled */
    2569                 :          0 :         aa_info_message("AppArmor Filesystem Enabled");
    2570                 :          0 :         return 0;
    2571                 :            : 
    2572                 :            : dent_error:
    2573                 :            :         error = PTR_ERR(dent);
    2574                 :            : error:
    2575                 :          0 :         aa_destroy_aafs();
    2576                 :          0 :         AA_ERROR("Error creating AppArmor securityfs\n");
    2577                 :          0 :         return error;
    2578                 :            : }
    2579                 :            : 
    2580                 :            : fs_initcall(aa_create_aafs);
    

Generated by: LCOV version 1.14