LCOV - code coverage report
Current view: top level - fs - xattr_acl.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 42 2.4 %
Date: 2014-02-18 Functions: 1 4 25.0 %
Branches: 0 35 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * linux/fs/xattr_acl.c
       3                 :            :  *
       4                 :            :  * Almost all from linux/fs/ext2/acl.c:
       5                 :            :  * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
       6                 :            :  */
       7                 :            : 
       8                 :            : #include <linux/export.h>
       9                 :            : #include <linux/fs.h>
      10                 :            : #include <linux/posix_acl_xattr.h>
      11                 :            : #include <linux/gfp.h>
      12                 :            : #include <linux/user_namespace.h>
      13                 :            : 
      14                 :            : /*
      15                 :            :  * Fix up the uids and gids in posix acl extended attributes in place.
      16                 :            :  */
      17                 :            : static void posix_acl_fix_xattr_userns(
      18                 :            :         struct user_namespace *to, struct user_namespace *from,
      19                 :            :         void *value, size_t size)
      20                 :            : {
      21                 :            :         posix_acl_xattr_header *header = (posix_acl_xattr_header *)value;
      22                 :            :         posix_acl_xattr_entry *entry = (posix_acl_xattr_entry *)(header+1), *end;
      23                 :            :         int count;
      24                 :            :         kuid_t uid;
      25                 :            :         kgid_t gid;
      26                 :            : 
      27                 :            :         if (!value)
      28                 :            :                 return;
      29                 :            :         if (size < sizeof(posix_acl_xattr_header))
      30                 :            :                 return;
      31                 :            :         if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
      32                 :            :                 return;
      33                 :            : 
      34                 :            :         count = posix_acl_xattr_count(size);
      35                 :            :         if (count < 0)
      36                 :            :                 return;
      37                 :            :         if (count == 0)
      38                 :            :                 return;
      39                 :            : 
      40                 :            :         for (end = entry + count; entry != end; entry++) {
      41                 :            :                 switch(le16_to_cpu(entry->e_tag)) {
      42                 :            :                 case ACL_USER:
      43                 :            :                         uid = make_kuid(from, le32_to_cpu(entry->e_id));
      44                 :            :                         entry->e_id = cpu_to_le32(from_kuid(to, uid));
      45                 :            :                         break;
      46                 :            :                 case ACL_GROUP:
      47                 :            :                         gid = make_kgid(from, le32_to_cpu(entry->e_id));
      48                 :            :                         entry->e_id = cpu_to_le32(from_kgid(to, gid));
      49                 :            :                         break;
      50                 :            :                 default:
      51                 :            :                         break;
      52                 :            :                 }
      53                 :            :         }
      54                 :            : }
      55                 :            : 
      56                 :          0 : void posix_acl_fix_xattr_from_user(void *value, size_t size)
      57                 :            : {
      58                 :            :         struct user_namespace *user_ns = current_user_ns();
      59                 :            :         if (user_ns == &init_user_ns)
      60                 :       2636 :                 return;
      61                 :            :         posix_acl_fix_xattr_userns(&init_user_ns, user_ns, value, size);
      62                 :            : }
      63                 :            : 
      64                 :          0 : void posix_acl_fix_xattr_to_user(void *value, size_t size)
      65                 :            : {
      66                 :            :         struct user_namespace *user_ns = current_user_ns();
      67                 :            :         if (user_ns == &init_user_ns)
      68                 :          0 :                 return;
      69                 :            :         posix_acl_fix_xattr_userns(user_ns, &init_user_ns, value, size);
      70                 :            : }
      71                 :            : 
      72                 :            : /*
      73                 :            :  * Convert from extended attribute to in-memory representation.
      74                 :            :  */
      75                 :            : struct posix_acl *
      76                 :          0 : posix_acl_from_xattr(struct user_namespace *user_ns,
      77                 :            :                      const void *value, size_t size)
      78                 :            : {
      79                 :            :         posix_acl_xattr_header *header = (posix_acl_xattr_header *)value;
      80                 :          0 :         posix_acl_xattr_entry *entry = (posix_acl_xattr_entry *)(header+1), *end;
      81                 :            :         int count;
      82                 :            :         struct posix_acl *acl;
      83                 :            :         struct posix_acl_entry *acl_e;
      84                 :            : 
      85         [ #  # ]:          0 :         if (!value)
      86                 :            :                 return NULL;
      87         [ #  # ]:          0 :         if (size < sizeof(posix_acl_xattr_header))
      88                 :            :                  return ERR_PTR(-EINVAL);
      89         [ #  # ]:          0 :         if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
      90                 :            :                 return ERR_PTR(-EOPNOTSUPP);
      91                 :            : 
      92                 :            :         count = posix_acl_xattr_count(size);
      93         [ #  # ]:          0 :         if (count < 0)
      94                 :            :                 return ERR_PTR(-EINVAL);
      95         [ #  # ]:          0 :         if (count == 0)
      96                 :            :                 return NULL;
      97                 :            :         
      98                 :          0 :         acl = posix_acl_alloc(count, GFP_NOFS);
      99         [ #  # ]:          0 :         if (!acl)
     100                 :            :                 return ERR_PTR(-ENOMEM);
     101                 :          0 :         acl_e = acl->a_entries;
     102                 :            :         
     103         [ #  # ]:          0 :         for (end = entry + count; entry != end; acl_e++, entry++) {
     104                 :          0 :                 acl_e->e_tag  = le16_to_cpu(entry->e_tag);
     105 [ #  # ][ #  # ]:          0 :                 acl_e->e_perm = le16_to_cpu(entry->e_perm);
         [ #  # ][ #  # ]
     106                 :            : 
     107                 :            :                 switch(acl_e->e_tag) {
     108                 :            :                         case ACL_USER_OBJ:
     109                 :            :                         case ACL_GROUP_OBJ:
     110                 :            :                         case ACL_MASK:
     111                 :            :                         case ACL_OTHER:
     112                 :            :                                 break;
     113                 :            : 
     114                 :            :                         case ACL_USER:
     115                 :          0 :                                 acl_e->e_uid =
     116                 :          0 :                                         make_kuid(user_ns,
     117                 :            :                                                   le32_to_cpu(entry->e_id));
     118         [ #  # ]:          0 :                                 if (!uid_valid(acl_e->e_uid))
     119                 :            :                                         goto fail;
     120                 :            :                                 break;
     121                 :            :                         case ACL_GROUP:
     122                 :          0 :                                 acl_e->e_gid =
     123                 :          0 :                                         make_kgid(user_ns,
     124                 :            :                                                   le32_to_cpu(entry->e_id));
     125         [ #  # ]:          0 :                                 if (!gid_valid(acl_e->e_gid))
     126                 :            :                                         goto fail;
     127                 :            :                                 break;
     128                 :            : 
     129                 :            :                         default:
     130                 :            :                                 goto fail;
     131                 :            :                 }
     132                 :            :         }
     133                 :            :         return acl;
     134                 :            : 
     135                 :            : fail:
     136                 :            :         posix_acl_release(acl);
     137                 :            :         return ERR_PTR(-EINVAL);
     138                 :            : }
     139                 :            : EXPORT_SYMBOL (posix_acl_from_xattr);
     140                 :            : 
     141                 :            : /*
     142                 :            :  * Convert from in-memory to extended attribute representation.
     143                 :            :  */
     144                 :            : int
     145                 :          0 : posix_acl_to_xattr(struct user_namespace *user_ns, const struct posix_acl *acl,
     146                 :            :                    void *buffer, size_t size)
     147                 :            : {
     148                 :            :         posix_acl_xattr_header *ext_acl = (posix_acl_xattr_header *)buffer;
     149                 :          0 :         posix_acl_xattr_entry *ext_entry = ext_acl->a_entries;
     150                 :            :         int real_size, n;
     151                 :            : 
     152                 :          0 :         real_size = posix_acl_xattr_size(acl->a_count);
     153         [ #  # ]:          0 :         if (!buffer)
     154                 :            :                 return real_size;
     155         [ #  # ]:          0 :         if (real_size > size)
     156                 :            :                 return -ERANGE;
     157                 :            :         
     158                 :          0 :         ext_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
     159                 :            : 
     160         [ #  # ]:          0 :         for (n=0; n < acl->a_count; n++, ext_entry++) {
     161                 :          0 :                 const struct posix_acl_entry *acl_e = &acl->a_entries[n];
     162                 :          0 :                 ext_entry->e_tag  = cpu_to_le16(acl_e->e_tag);
     163                 :          0 :                 ext_entry->e_perm = cpu_to_le16(acl_e->e_perm);
     164      [ #  #  # ]:          0 :                 switch(acl_e->e_tag) {
     165                 :            :                 case ACL_USER:
     166                 :          0 :                         ext_entry->e_id =
     167                 :          0 :                                 cpu_to_le32(from_kuid(user_ns, acl_e->e_uid));
     168                 :          0 :                         break;
     169                 :            :                 case ACL_GROUP:
     170                 :          0 :                         ext_entry->e_id =
     171                 :          0 :                                 cpu_to_le32(from_kgid(user_ns, acl_e->e_gid));
     172                 :          0 :                         break;
     173                 :            :                 default:
     174                 :          0 :                         ext_entry->e_id = cpu_to_le32(ACL_UNDEFINED_ID);
     175                 :          0 :                         break;
     176                 :            :                 }
     177                 :            :         }
     178                 :            :         return real_size;
     179                 :            : }
     180                 :            : EXPORT_SYMBOL (posix_acl_to_xattr);

Generated by: LCOV version 1.9