LCOV - code coverage report
Current view: top level - security/apparmor - file.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 161 0.0 %
Date: 2014-02-18 Functions: 0 9 0.0 %
Branches: 0 100 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * AppArmor security module
       3                 :            :  *
       4                 :            :  * This file contains AppArmor mediation of files
       5                 :            :  *
       6                 :            :  * Copyright (C) 1998-2008 Novell/SUSE
       7                 :            :  * Copyright 2009-2010 Canonical Ltd.
       8                 :            :  *
       9                 :            :  * This program is free software; you can redistribute it and/or
      10                 :            :  * modify it under the terms of the GNU General Public License as
      11                 :            :  * published by the Free Software Foundation, version 2 of the
      12                 :            :  * License.
      13                 :            :  */
      14                 :            : 
      15                 :            : #include "include/apparmor.h"
      16                 :            : #include "include/audit.h"
      17                 :            : #include "include/file.h"
      18                 :            : #include "include/match.h"
      19                 :            : #include "include/path.h"
      20                 :            : #include "include/policy.h"
      21                 :            : 
      22                 :            : struct file_perms nullperms;
      23                 :            : 
      24                 :            : 
      25                 :            : /**
      26                 :            :  * audit_file_mask - convert mask to permission string
      27                 :            :  * @buffer: buffer to write string to (NOT NULL)
      28                 :            :  * @mask: permission mask to convert
      29                 :            :  */
      30                 :          0 : static void audit_file_mask(struct audit_buffer *ab, u32 mask)
      31                 :            : {
      32                 :            :         char str[10];
      33                 :            : 
      34                 :            :         char *m = str;
      35                 :            : 
      36         [ #  # ]:          0 :         if (mask & AA_EXEC_MMAP)
      37                 :          0 :                 *m++ = 'm';
      38         [ #  # ]:          0 :         if (mask & (MAY_READ | AA_MAY_META_READ))
      39                 :          0 :                 *m++ = 'r';
      40         [ #  # ]:          0 :         if (mask & (MAY_WRITE | AA_MAY_META_WRITE | AA_MAY_CHMOD |
      41                 :            :                     AA_MAY_CHOWN))
      42                 :          0 :                 *m++ = 'w';
      43         [ #  # ]:          0 :         else if (mask & MAY_APPEND)
      44                 :          0 :                 *m++ = 'a';
      45         [ #  # ]:          0 :         if (mask & AA_MAY_CREATE)
      46                 :          0 :                 *m++ = 'c';
      47         [ #  # ]:          0 :         if (mask & AA_MAY_DELETE)
      48                 :          0 :                 *m++ = 'd';
      49         [ #  # ]:          0 :         if (mask & AA_MAY_LINK)
      50                 :          0 :                 *m++ = 'l';
      51         [ #  # ]:          0 :         if (mask & AA_MAY_LOCK)
      52                 :          0 :                 *m++ = 'k';
      53         [ #  # ]:          0 :         if (mask & MAY_EXEC)
      54                 :          0 :                 *m++ = 'x';
      55                 :          0 :         *m = '\0';
      56                 :            : 
      57                 :            :         audit_log_string(ab, str);
      58                 :          0 : }
      59                 :            : 
      60                 :            : /**
      61                 :            :  * file_audit_cb - call back for file specific audit fields
      62                 :            :  * @ab: audit_buffer  (NOT NULL)
      63                 :            :  * @va: audit struct to audit values of  (NOT NULL)
      64                 :            :  */
      65                 :          0 : static void file_audit_cb(struct audit_buffer *ab, void *va)
      66                 :            : {
      67                 :            :         struct common_audit_data *sa = va;
      68                 :          0 :         kuid_t fsuid = current_fsuid();
      69                 :            : 
      70         [ #  # ]:          0 :         if (sa->aad->fs.request & AA_AUDIT_FILE_MASK) {
      71                 :          0 :                 audit_log_format(ab, " requested_mask=");
      72                 :          0 :                 audit_file_mask(ab, sa->aad->fs.request);
      73                 :            :         }
      74         [ #  # ]:          0 :         if (sa->aad->fs.denied & AA_AUDIT_FILE_MASK) {
      75                 :          0 :                 audit_log_format(ab, " denied_mask=");
      76                 :          0 :                 audit_file_mask(ab, sa->aad->fs.denied);
      77                 :            :         }
      78         [ #  # ]:          0 :         if (sa->aad->fs.request & AA_AUDIT_FILE_MASK) {
      79                 :          0 :                 audit_log_format(ab, " fsuid=%d",
      80                 :            :                                  from_kuid(&init_user_ns, fsuid));
      81                 :          0 :                 audit_log_format(ab, " ouid=%d",
      82                 :          0 :                                  from_kuid(&init_user_ns, sa->aad->fs.ouid));
      83                 :            :         }
      84                 :            : 
      85         [ #  # ]:          0 :         if (sa->aad->fs.target) {
      86                 :          0 :                 audit_log_format(ab, " target=");
      87                 :          0 :                 audit_log_untrustedstring(ab, sa->aad->fs.target);
      88                 :            :         }
      89                 :          0 : }
      90                 :            : 
      91                 :            : /**
      92                 :            :  * aa_audit_file - handle the auditing of file operations
      93                 :            :  * @profile: the profile being enforced  (NOT NULL)
      94                 :            :  * @perms: the permissions computed for the request (NOT NULL)
      95                 :            :  * @gfp: allocation flags
      96                 :            :  * @op: operation being mediated
      97                 :            :  * @request: permissions requested
      98                 :            :  * @name: name of object being mediated (MAYBE NULL)
      99                 :            :  * @target: name of target (MAYBE NULL)
     100                 :            :  * @ouid: object uid
     101                 :            :  * @info: extra information message (MAYBE NULL)
     102                 :            :  * @error: 0 if operation allowed else failure error code
     103                 :            :  *
     104                 :            :  * Returns: %0 or error on failure
     105                 :            :  */
     106                 :          0 : int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
     107                 :            :                   gfp_t gfp, int op, u32 request, const char *name,
     108                 :            :                   const char *target, kuid_t ouid, const char *info, int error)
     109                 :            : {
     110                 :            :         int type = AUDIT_APPARMOR_AUTO;
     111                 :            :         struct common_audit_data sa;
     112                 :          0 :         struct apparmor_audit_data aad = {0,};
     113                 :          0 :         sa.type = LSM_AUDIT_DATA_NONE;
     114                 :          0 :         sa.aad = &aad;
     115                 :          0 :         aad.op = op,
     116                 :          0 :         aad.fs.request = request;
     117                 :          0 :         aad.name = name;
     118                 :          0 :         aad.fs.target = target;
     119                 :          0 :         aad.fs.ouid = ouid;
     120                 :          0 :         aad.info = info;
     121                 :          0 :         aad.error = error;
     122                 :            : 
     123         [ #  # ]:          0 :         if (likely(!sa.aad->error)) {
     124                 :          0 :                 u32 mask = perms->audit;
     125                 :            : 
     126         [ #  # ]:          0 :                 if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL))
     127                 :            :                         mask = 0xffff;
     128                 :            : 
     129                 :            :                 /* mask off perms that are not being force audited */
     130                 :          0 :                 sa.aad->fs.request &= mask;
     131                 :            : 
     132         [ #  # ]:          0 :                 if (likely(!sa.aad->fs.request))
     133                 :            :                         return 0;
     134                 :            :                 type = AUDIT_APPARMOR_AUDIT;
     135                 :            :         } else {
     136                 :            :                 /* only report permissions that were denied */
     137                 :          0 :                 sa.aad->fs.request = sa.aad->fs.request & ~perms->allow;
     138                 :            : 
     139         [ #  # ]:          0 :                 if (sa.aad->fs.request & perms->kill)
     140                 :            :                         type = AUDIT_APPARMOR_KILL;
     141                 :            : 
     142                 :            :                 /* quiet known rejects, assumes quiet and kill do not overlap */
     143 [ #  # ][ #  # ]:          0 :                 if ((sa.aad->fs.request & perms->quiet) &&
     144         [ #  # ]:          0 :                     AUDIT_MODE(profile) != AUDIT_NOQUIET &&
     145                 :            :                     AUDIT_MODE(profile) != AUDIT_ALL)
     146                 :          0 :                         sa.aad->fs.request &= ~perms->quiet;
     147                 :            : 
     148         [ #  # ]:          0 :                 if (!sa.aad->fs.request)
     149 [ #  # ][ #  # ]:          0 :                         return COMPLAIN_MODE(profile) ? 0 : sa.aad->error;
     150                 :            :         }
     151                 :            : 
     152                 :          0 :         sa.aad->fs.denied = sa.aad->fs.request & ~perms->allow;
     153                 :          0 :         return aa_audit(type, profile, gfp, &sa, file_audit_cb);
     154                 :            : }
     155                 :            : 
     156                 :            : /**
     157                 :            :  * map_old_perms - map old file perms layout to the new layout
     158                 :            :  * @old: permission set in old mapping
     159                 :            :  *
     160                 :            :  * Returns: new permission mapping
     161                 :            :  */
     162                 :          0 : static u32 map_old_perms(u32 old)
     163                 :            : {
     164                 :          0 :         u32 new = old & 0xf;
     165         [ #  # ]:          0 :         if (old & MAY_READ)
     166                 :          0 :                 new |= AA_MAY_META_READ;
     167         [ #  # ]:          0 :         if (old & MAY_WRITE)
     168                 :          0 :                 new |= AA_MAY_META_WRITE | AA_MAY_CREATE | AA_MAY_DELETE |
     169                 :            :                         AA_MAY_CHMOD | AA_MAY_CHOWN;
     170         [ #  # ]:          0 :         if (old & 0x10)
     171                 :          0 :                 new |= AA_MAY_LINK;
     172                 :            :         /* the old mapping lock and link_subset flags where overlaid
     173                 :            :          * and use was determined by part of a pair that they were in
     174                 :            :          */
     175         [ #  # ]:          0 :         if (old & 0x20)
     176                 :          0 :                 new |= AA_MAY_LOCK | AA_LINK_SUBSET;
     177         [ #  # ]:          0 :         if (old & 0x40)     /* AA_EXEC_MMAP */
     178                 :          0 :                 new |= AA_EXEC_MMAP;
     179                 :            : 
     180                 :          0 :         return new;
     181                 :            : }
     182                 :            : 
     183                 :            : /**
     184                 :            :  * compute_perms - convert dfa compressed perms to internal perms
     185                 :            :  * @dfa: dfa to compute perms for   (NOT NULL)
     186                 :            :  * @state: state in dfa
     187                 :            :  * @cond:  conditions to consider  (NOT NULL)
     188                 :            :  *
     189                 :            :  * TODO: convert from dfa + state to permission entry, do computation conversion
     190                 :            :  *       at load time.
     191                 :            :  *
     192                 :            :  * Returns: computed permission set
     193                 :            :  */
     194                 :          0 : static struct file_perms compute_perms(struct aa_dfa *dfa, unsigned int state,
     195                 :            :                                        struct path_cond *cond)
     196                 :            : {
     197                 :            :         struct file_perms perms;
     198                 :            : 
     199                 :            :         /* FIXME: change over to new dfa format
     200                 :            :          * currently file perms are encoded in the dfa, new format
     201                 :            :          * splits the permissions from the dfa.  This mapping can be
     202                 :            :          * done at profile load
     203                 :            :          */
     204                 :            :         perms.kill = 0;
     205                 :            : 
     206         [ #  # ]:          0 :         if (uid_eq(current_fsuid(), cond->uid)) {
     207                 :          0 :                 perms.allow = map_old_perms(dfa_user_allow(dfa, state));
     208                 :          0 :                 perms.audit = map_old_perms(dfa_user_audit(dfa, state));
     209                 :          0 :                 perms.quiet = map_old_perms(dfa_user_quiet(dfa, state));
     210                 :          0 :                 perms.xindex = dfa_user_xindex(dfa, state);
     211                 :            :         } else {
     212                 :          0 :                 perms.allow = map_old_perms(dfa_other_allow(dfa, state));
     213                 :          0 :                 perms.audit = map_old_perms(dfa_other_audit(dfa, state));
     214                 :          0 :                 perms.quiet = map_old_perms(dfa_other_quiet(dfa, state));
     215                 :          0 :                 perms.xindex = dfa_other_xindex(dfa, state);
     216                 :            :         }
     217                 :          0 :         perms.allow |= AA_MAY_META_READ;
     218                 :            : 
     219                 :            :         /* change_profile wasn't determined by ownership in old mapping */
     220         [ #  # ]:          0 :         if (ACCEPT_TABLE(dfa)[state] & 0x80000000)
     221                 :          0 :                 perms.allow |= AA_MAY_CHANGE_PROFILE;
     222         [ #  # ]:          0 :         if (ACCEPT_TABLE(dfa)[state] & 0x40000000)
     223                 :          0 :                 perms.allow |= AA_MAY_ONEXEC;
     224                 :            : 
     225                 :          0 :         return perms;
     226                 :            : }
     227                 :            : 
     228                 :            : /**
     229                 :            :  * aa_str_perms - find permission that match @name
     230                 :            :  * @dfa: to match against  (MAYBE NULL)
     231                 :            :  * @state: state to start matching in
     232                 :            :  * @name: string to match against dfa  (NOT NULL)
     233                 :            :  * @cond: conditions to consider for permission set computation  (NOT NULL)
     234                 :            :  * @perms: Returns - the permissions found when matching @name
     235                 :            :  *
     236                 :            :  * Returns: the final state in @dfa when beginning @start and walking @name
     237                 :            :  */
     238                 :          0 : unsigned int aa_str_perms(struct aa_dfa *dfa, unsigned int start,
     239                 :          0 :                           const char *name, struct path_cond *cond,
     240                 :            :                           struct file_perms *perms)
     241                 :            : {
     242                 :            :         unsigned int state;
     243         [ #  # ]:          0 :         if (!dfa) {
     244                 :          0 :                 *perms = nullperms;
     245                 :          0 :                 return DFA_NOMATCH;
     246                 :            :         }
     247                 :            : 
     248                 :          0 :         state = aa_dfa_match(dfa, start, name);
     249                 :          0 :         *perms = compute_perms(dfa, state, cond);
     250                 :            : 
     251                 :          0 :         return state;
     252                 :            : }
     253                 :            : 
     254                 :            : /**
     255                 :            :  * is_deleted - test if a file has been completely unlinked
     256                 :            :  * @dentry: dentry of file to test for deletion  (NOT NULL)
     257                 :            :  *
     258                 :            :  * Returns: %1 if deleted else %0
     259                 :            :  */
     260                 :            : static inline bool is_deleted(struct dentry *dentry)
     261                 :            : {
     262 [ #  # ][ #  # ]:          0 :         if (d_unlinked(dentry) && dentry->d_inode->i_nlink == 0)
     263                 :            :                 return 1;
     264                 :            :         return 0;
     265                 :            : }
     266                 :            : 
     267                 :            : /**
     268                 :            :  * aa_path_perm - do permissions check & audit for @path
     269                 :            :  * @op: operation being checked
     270                 :            :  * @profile: profile being enforced  (NOT NULL)
     271                 :            :  * @path: path to check permissions of  (NOT NULL)
     272                 :            :  * @flags: any additional path flags beyond what the profile specifies
     273                 :            :  * @request: requested permissions
     274                 :            :  * @cond: conditional info for this request  (NOT NULL)
     275                 :            :  *
     276                 :            :  * Returns: %0 else error if access denied or other error
     277                 :            :  */
     278                 :          0 : int aa_path_perm(int op, struct aa_profile *profile, struct path *path,
     279                 :            :                  int flags, u32 request, struct path_cond *cond)
     280                 :            : {
     281                 :          0 :         char *buffer = NULL;
     282                 :          0 :         struct file_perms perms = {};
     283                 :          0 :         const char *name, *info = NULL;
     284                 :            :         int error;
     285                 :            : 
     286         [ #  # ]:          0 :         flags |= profile->path_flags | (S_ISDIR(cond->mode) ? PATH_IS_DIR : 0);
     287                 :          0 :         error = aa_path_name(path, flags, &buffer, &name, &info);
     288         [ #  # ]:          0 :         if (error) {
     289 [ #  # ][ #  # ]:          0 :                 if (error == -ENOENT && is_deleted(path->dentry)) {
     290                 :            :                         /* Access to open files that are deleted are
     291                 :            :                          * give a pass (implicit delegation)
     292                 :            :                          */
     293                 :            :                         error = 0;
     294                 :          0 :                         info = NULL;
     295                 :          0 :                         perms.allow = request;
     296                 :            :                 }
     297                 :            :         } else {
     298                 :          0 :                 aa_str_perms(profile->file.dfa, profile->file.start, name, cond,
     299                 :            :                              &perms);
     300         [ #  # ]:          0 :                 if (request & ~perms.allow)
     301                 :            :                         error = -EACCES;
     302                 :            :         }
     303                 :          0 :         error = aa_audit_file(profile, &perms, GFP_KERNEL, op, request, name,
     304                 :            :                               NULL, cond->uid, info, error);
     305                 :          0 :         kfree(buffer);
     306                 :            : 
     307                 :          0 :         return error;
     308                 :            : }
     309                 :            : 
     310                 :            : /**
     311                 :            :  * xindex_is_subset - helper for aa_path_link
     312                 :            :  * @link: link permission set
     313                 :            :  * @target: target permission set
     314                 :            :  *
     315                 :            :  * test target x permissions are equal OR a subset of link x permissions
     316                 :            :  * this is done as part of the subset test, where a hardlink must have
     317                 :            :  * a subset of permissions that the target has.
     318                 :            :  *
     319                 :            :  * Returns: %1 if subset else %0
     320                 :            :  */
     321                 :            : static inline bool xindex_is_subset(u32 link, u32 target)
     322                 :            : {
     323 [ #  # ][ #  # ]:          0 :         if (((link & ~AA_X_UNSAFE) != (target & ~AA_X_UNSAFE)) ||
     324         [ #  # ]:          0 :             ((link & AA_X_UNSAFE) && !(target & AA_X_UNSAFE)))
     325                 :            :                 return 0;
     326                 :            : 
     327                 :            :         return 1;
     328                 :            : }
     329                 :            : 
     330                 :            : /**
     331                 :            :  * aa_path_link - Handle hard link permission check
     332                 :            :  * @profile: the profile being enforced  (NOT NULL)
     333                 :            :  * @old_dentry: the target dentry  (NOT NULL)
     334                 :            :  * @new_dir: directory the new link will be created in  (NOT NULL)
     335                 :            :  * @new_dentry: the link being created  (NOT NULL)
     336                 :            :  *
     337                 :            :  * Handle the permission test for a link & target pair.  Permission
     338                 :            :  * is encoded as a pair where the link permission is determined
     339                 :            :  * first, and if allowed, the target is tested.  The target test
     340                 :            :  * is done from the point of the link match (not start of DFA)
     341                 :            :  * making the target permission dependent on the link permission match.
     342                 :            :  *
     343                 :            :  * The subset test if required forces that permissions granted
     344                 :            :  * on link are a subset of the permission granted to target.
     345                 :            :  *
     346                 :            :  * Returns: %0 if allowed else error
     347                 :            :  */
     348                 :          0 : int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry,
     349                 :            :                  struct path *new_dir, struct dentry *new_dentry)
     350                 :            : {
     351                 :          0 :         struct path link = { new_dir->mnt, new_dentry };
     352                 :          0 :         struct path target = { new_dir->mnt, old_dentry };
     353                 :          0 :         struct path_cond cond = {
     354                 :          0 :                 old_dentry->d_inode->i_uid,
     355                 :          0 :                 old_dentry->d_inode->i_mode
     356                 :            :         };
     357                 :          0 :         char *buffer = NULL, *buffer2 = NULL;
     358                 :          0 :         const char *lname, *tname = NULL, *info = NULL;
     359                 :            :         struct file_perms lperms, perms;
     360                 :            :         u32 request = AA_MAY_LINK;
     361                 :            :         unsigned int state;
     362                 :            :         int error;
     363                 :            : 
     364                 :          0 :         lperms = nullperms;
     365                 :            : 
     366                 :            :         /* buffer freed below, lname is pointer in buffer */
     367                 :          0 :         error = aa_path_name(&link, profile->path_flags, &buffer, &lname,
     368                 :            :                              &info);
     369         [ #  # ]:          0 :         if (error)
     370                 :            :                 goto audit;
     371                 :            : 
     372                 :            :         /* buffer2 freed below, tname is pointer in buffer2 */
     373                 :          0 :         error = aa_path_name(&target, profile->path_flags, &buffer2, &tname,
     374                 :            :                              &info);
     375         [ #  # ]:          0 :         if (error)
     376                 :            :                 goto audit;
     377                 :            : 
     378                 :            :         error = -EACCES;
     379                 :            :         /* aa_str_perms - handles the case of the dfa being NULL */
     380                 :          0 :         state = aa_str_perms(profile->file.dfa, profile->file.start, lname,
     381                 :            :                              &cond, &lperms);
     382                 :            : 
     383         [ #  # ]:          0 :         if (!(lperms.allow & AA_MAY_LINK))
     384                 :            :                 goto audit;
     385                 :            : 
     386                 :            :         /* test to see if target can be paired with link */
     387                 :          0 :         state = aa_dfa_null_transition(profile->file.dfa, state);
     388                 :          0 :         aa_str_perms(profile->file.dfa, state, tname, &cond, &perms);
     389                 :            : 
     390                 :            :         /* force audit/quiet masks for link are stored in the second entry
     391                 :            :          * in the link pair.
     392                 :            :          */
     393                 :          0 :         lperms.audit = perms.audit;
     394                 :          0 :         lperms.quiet = perms.quiet;
     395                 :          0 :         lperms.kill = perms.kill;
     396                 :            : 
     397         [ #  # ]:          0 :         if (!(perms.allow & AA_MAY_LINK)) {
     398                 :          0 :                 info = "target restricted";
     399                 :          0 :                 goto audit;
     400                 :            :         }
     401                 :            : 
     402                 :            :         /* done if link subset test is not required */
     403         [ #  # ]:          0 :         if (!(perms.allow & AA_LINK_SUBSET))
     404                 :            :                 goto done_tests;
     405                 :            : 
     406                 :            :         /* Do link perm subset test requiring allowed permission on link are a
     407                 :            :          * subset of the allowed permissions on target.
     408                 :            :          */
     409                 :          0 :         aa_str_perms(profile->file.dfa, profile->file.start, tname, &cond,
     410                 :            :                      &perms);
     411                 :            : 
     412                 :            :         /* AA_MAY_LINK is not considered in the subset test */
     413                 :          0 :         request = lperms.allow & ~AA_MAY_LINK;
     414                 :          0 :         lperms.allow &= perms.allow | AA_MAY_LINK;
     415                 :            : 
     416                 :          0 :         request |= AA_AUDIT_FILE_MASK & (lperms.allow & ~perms.allow);
     417         [ #  # ]:          0 :         if (request & ~lperms.allow) {
     418                 :            :                 goto audit;
     419 [ #  # ][ #  # ]:          0 :         } else if ((lperms.allow & MAY_EXEC) &&
     420                 :          0 :                    !xindex_is_subset(lperms.xindex, perms.xindex)) {
     421                 :          0 :                 lperms.allow &= ~MAY_EXEC;
     422                 :          0 :                 request |= MAY_EXEC;
     423                 :          0 :                 info = "link not subset of target";
     424                 :          0 :                 goto audit;
     425                 :            :         }
     426                 :            : 
     427                 :            : done_tests:
     428                 :            :         error = 0;
     429                 :            : 
     430                 :            : audit:
     431                 :          0 :         error = aa_audit_file(profile, &lperms, GFP_KERNEL, OP_LINK, request,
     432                 :            :                               lname, tname, cond.uid, info, error);
     433                 :          0 :         kfree(buffer);
     434                 :          0 :         kfree(buffer2);
     435                 :            : 
     436                 :          0 :         return error;
     437                 :            : }
     438                 :            : 
     439                 :            : /**
     440                 :            :  * aa_file_perm - do permission revalidation check & audit for @file
     441                 :            :  * @op: operation being checked
     442                 :            :  * @profile: profile being enforced   (NOT NULL)
     443                 :            :  * @file: file to revalidate access permissions on  (NOT NULL)
     444                 :            :  * @request: requested permissions
     445                 :            :  *
     446                 :            :  * Returns: %0 if access allowed else error
     447                 :            :  */
     448                 :          0 : int aa_file_perm(int op, struct aa_profile *profile, struct file *file,
     449                 :            :                  u32 request)
     450                 :            : {
     451                 :          0 :         struct path_cond cond = {
     452                 :          0 :                 .uid = file_inode(file)->i_uid,
     453                 :          0 :                 .mode = file_inode(file)->i_mode
     454                 :            :         };
     455                 :            : 
     456                 :          0 :         return aa_path_perm(op, profile, &file->f_path, PATH_DELEGATE_DELETED,
     457                 :            :                             request, &cond);
     458                 :            : }

Generated by: LCOV version 1.9