]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commitdiff
UBUNTU: SAUCE: (namespace) posix_acl: Export posix_acl_fix_xattr_userns() to modules
authorSeth Forshee <seth.forshee@canonical.com>
Fri, 8 Jul 2016 20:57:51 +0000 (15:57 -0500)
committerTim Gardner <tim.gardner@canonical.com>
Mon, 20 Feb 2017 03:57:58 +0000 (20:57 -0700)
Fuse will make use of this function to provide backwards-
compatible acl support when proper posix acl support is added.
Add a check to return immediately if the to and from namespaces
are the same, and remove equivalent checks from its callers.

Also return an error code to indicate to callers whether or not
the conversion of the id between the user namespaces was
successful. For a valid xattr the id will continue to be changed
regardless to maintain the current behaviour for existing
callers, so they do not require updates to handle failed
conversions.

Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
fs/posix_acl.c
include/linux/posix_acl_xattr.h

index c9d48dc784953fa4af62f9af58dfbb56ed2faa70..f1d7d2ad8f6f66b5bcaa01fbc4c6f1cbf240448e 100644 (file)
@@ -661,58 +661,68 @@ EXPORT_SYMBOL(posix_acl_update_mode);
 /*
  * Fix up the uids and gids in posix acl extended attributes in place.
  */
-static void posix_acl_fix_xattr_userns(
+int posix_acl_fix_xattr_userns(
        struct user_namespace *to, struct user_namespace *from,
        void *value, size_t size)
 {
        struct posix_acl_xattr_header *header = value;
        struct posix_acl_xattr_entry *entry = (void *)(header + 1), *end;
        int count;
-       kuid_t uid;
-       kgid_t gid;
+       kuid_t kuid;
+       kgid_t kgid;
+       uid_t uid;
+       gid_t gid;
+       int ret = 0;
 
+       if (to == from)
+               return 0;
        if (!value)
-               return;
+               return 0;
        if (size < sizeof(struct posix_acl_xattr_header))
-               return;
+               return -EINVAL;
        if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
-               return;
+               return -EINVAL;
 
        count = posix_acl_xattr_count(size);
        if (count < 0)
-               return;
+               return -EINVAL;
        if (count == 0)
-               return;
+               return 0;
 
        for (end = entry + count; entry != end; entry++) {
                switch(le16_to_cpu(entry->e_tag)) {
                case ACL_USER:
-                       uid = make_kuid(from, le32_to_cpu(entry->e_id));
-                       entry->e_id = cpu_to_le32(from_kuid(to, uid));
+                       kuid = make_kuid(from, le32_to_cpu(entry->e_id));
+                       uid = from_kuid(to, kuid);
+                       entry->e_id = cpu_to_le32(uid);
+                       if (uid == (uid_t)-1)
+                               ret = -EOVERFLOW;
                        break;
                case ACL_GROUP:
-                       gid = make_kgid(from, le32_to_cpu(entry->e_id));
-                       entry->e_id = cpu_to_le32(from_kgid(to, gid));
+                       kgid = make_kgid(from, le32_to_cpu(entry->e_id));
+                       gid = from_kgid(to, kgid);
+                       entry->e_id = cpu_to_le32(gid);
+                       if (gid == (gid_t)-1)
+                               ret = -EOVERFLOW;
                        break;
                default:
                        break;
                }
        }
+
+       return ret;
 }
+EXPORT_SYMBOL(posix_acl_fix_xattr_userns);
 
 void posix_acl_fix_xattr_from_user(void *value, size_t size)
 {
        struct user_namespace *user_ns = current_user_ns();
-       if (user_ns == &init_user_ns)
-               return;
        posix_acl_fix_xattr_userns(&init_user_ns, user_ns, value, size);
 }
 
 void posix_acl_fix_xattr_to_user(void *value, size_t size)
 {
        struct user_namespace *user_ns = current_user_ns();
-       if (user_ns == &init_user_ns)
-               return;
        posix_acl_fix_xattr_userns(user_ns, &init_user_ns, value, size);
 }
 
index 8b867e3bf3aa84e553e2c02fa0e6244284abcc51..67e148d8e9d2b28cd16bb72af30a0c077120c04e 100644 (file)
@@ -32,9 +32,18 @@ posix_acl_xattr_count(size_t size)
 }
 
 #ifdef CONFIG_FS_POSIX_ACL
+int posix_acl_fix_xattr_userns(struct user_namespace *to,
+                              struct user_namespace *from,
+                              void *value, size_t size);
 void posix_acl_fix_xattr_from_user(void *value, size_t size);
 void posix_acl_fix_xattr_to_user(void *value, size_t size);
 #else
+static inline int posix_acl_fix_xattr_userns(struct user_namespace *to,
+                                            struct user_namespace *from,
+                                            void *value, size_t size)
+{
+       return 0;
+}
 static inline void posix_acl_fix_xattr_from_user(void *value, size_t size)
 {
 }