The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/xattr_acl.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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 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                 return;
   61         posix_acl_fix_xattr_userns(&init_user_ns, user_ns, value, size);
   62 }
   63 
   64 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                 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 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         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         if (!value)
   86                 return NULL;
   87         if (size < sizeof(posix_acl_xattr_header))
   88                  return ERR_PTR(-EINVAL);
   89         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         if (count < 0)
   94                 return ERR_PTR(-EINVAL);
   95         if (count == 0)
   96                 return NULL;
   97         
   98         acl = posix_acl_alloc(count, GFP_NOFS);
   99         if (!acl)
  100                 return ERR_PTR(-ENOMEM);
  101         acl_e = acl->a_entries;
  102         
  103         for (end = entry + count; entry != end; acl_e++, entry++) {
  104                 acl_e->e_tag  = le16_to_cpu(entry->e_tag);
  105                 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                                 acl_e->e_uid =
  116                                         make_kuid(user_ns,
  117                                                   le32_to_cpu(entry->e_id));
  118                                 if (!uid_valid(acl_e->e_uid))
  119                                         goto fail;
  120                                 break;
  121                         case ACL_GROUP:
  122                                 acl_e->e_gid =
  123                                         make_kgid(user_ns,
  124                                                   le32_to_cpu(entry->e_id));
  125                                 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 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         posix_acl_xattr_entry *ext_entry = ext_acl->a_entries;
  150         int real_size, n;
  151 
  152         real_size = posix_acl_xattr_size(acl->a_count);
  153         if (!buffer)
  154                 return real_size;
  155         if (real_size > size)
  156                 return -ERANGE;
  157         
  158         ext_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
  159 
  160         for (n=0; n < acl->a_count; n++, ext_entry++) {
  161                 const struct posix_acl_entry *acl_e = &acl->a_entries[n];
  162                 ext_entry->e_tag  = cpu_to_le16(acl_e->e_tag);
  163                 ext_entry->e_perm = cpu_to_le16(acl_e->e_perm);
  164                 switch(acl_e->e_tag) {
  165                 case ACL_USER:
  166                         ext_entry->e_id =
  167                                 cpu_to_le32(from_kuid(user_ns, acl_e->e_uid));
  168                         break;
  169                 case ACL_GROUP:
  170                         ext_entry->e_id =
  171                                 cpu_to_le32(from_kgid(user_ns, acl_e->e_gid));
  172                         break;
  173                 default:
  174                         ext_entry->e_id = cpu_to_le32(ACL_UNDEFINED_ID);
  175                         break;
  176                 }
  177         }
  178         return real_size;
  179 }
  180 EXPORT_SYMBOL (posix_acl_to_xattr);

Cache object: 1ba796144ebe1d48386dedc87f464c8b


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.