userns: Convert extN to support kuids and kgids in posix acls
Eric W. Biederman [Tue, 11 Sep 2012 03:44:54 +0000 (20:44 -0700)]
Convert ext2, ext3, and ext4 to fully support the posix acl changes,
using e_uid e_gid instead e_id.

Enabled building with posix acls enabled, all filesystems supporting
user namespaces, now also support posix acls when user namespaces are enabled.

Cc: Theodore Tso <tytso@mit.edu>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andreas Dilger <adilger.kernel@dilger.ca>
Cc: Jan Kara <jack@suse.cz>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>

fs/ext2/acl.c
fs/ext3/acl.c
fs/ext4/acl.c
init/Kconfig

index 70bb1bc..110b6b3 100644 (file)
@@ -53,16 +53,23 @@ ext2_acl_from_disk(const void *value, size_t size)
                        case ACL_OTHER:
                                value = (char *)value +
                                        sizeof(ext2_acl_entry_short);
-                               acl->a_entries[n].e_id = ACL_UNDEFINED_ID;
                                break;
 
                        case ACL_USER:
+                               value = (char *)value + sizeof(ext2_acl_entry);
+                               if ((char *)value > end)
+                                       goto fail;
+                               acl->a_entries[n].e_uid =
+                                       make_kuid(&init_user_ns,
+                                                 le32_to_cpu(entry->e_id));
+                               break;
                        case ACL_GROUP:
                                value = (char *)value + sizeof(ext2_acl_entry);
                                if ((char *)value > end)
                                        goto fail;
-                               acl->a_entries[n].e_id =
-                                       le32_to_cpu(entry->e_id);
+                               acl->a_entries[n].e_gid =
+                                       make_kgid(&init_user_ns,
+                                                 le32_to_cpu(entry->e_id));
                                break;
 
                        default:
@@ -96,14 +103,19 @@ ext2_acl_to_disk(const struct posix_acl *acl, size_t *size)
        ext_acl->a_version = cpu_to_le32(EXT2_ACL_VERSION);
        e = (char *)ext_acl + sizeof(ext2_acl_header);
        for (n=0; n < acl->a_count; n++) {
+               const struct posix_acl_entry *acl_e = &acl->a_entries[n];
                ext2_acl_entry *entry = (ext2_acl_entry *)e;
-               entry->e_tag  = cpu_to_le16(acl->a_entries[n].e_tag);
-               entry->e_perm = cpu_to_le16(acl->a_entries[n].e_perm);
-               switch(acl->a_entries[n].e_tag) {
+               entry->e_tag  = cpu_to_le16(acl_e->e_tag);
+               entry->e_perm = cpu_to_le16(acl_e->e_perm);
+               switch(acl_e->e_tag) {
                        case ACL_USER:
+                               entry->e_id = cpu_to_le32(
+                                       from_kuid(&init_user_ns, acl_e->e_uid));
+                               e += sizeof(ext2_acl_entry);
+                               break;
                        case ACL_GROUP:
-                               entry->e_id =
-                                       cpu_to_le32(acl->a_entries[n].e_id);
+                               entry->e_id = cpu_to_le32(
+                                       from_kgid(&init_user_ns, acl_e->e_gid));
                                e += sizeof(ext2_acl_entry);
                                break;
 
index 2cf6a80..dbb5ad5 100644 (file)
@@ -48,16 +48,23 @@ ext3_acl_from_disk(const void *value, size_t size)
                        case ACL_OTHER:
                                value = (char *)value +
                                        sizeof(ext3_acl_entry_short);
-                               acl->a_entries[n].e_id = ACL_UNDEFINED_ID;
                                break;
 
                        case ACL_USER:
+                               value = (char *)value + sizeof(ext3_acl_entry);
+                               if ((char *)value > end)
+                                       goto fail;
+                               acl->a_entries[n].e_uid =
+                                       make_kuid(&init_user_ns,
+                                                 le32_to_cpu(entry->e_id));
+                               break;
                        case ACL_GROUP:
                                value = (char *)value + sizeof(ext3_acl_entry);
                                if ((char *)value > end)
                                        goto fail;
-                               acl->a_entries[n].e_id =
-                                       le32_to_cpu(entry->e_id);
+                               acl->a_entries[n].e_gid =
+                                       make_kgid(&init_user_ns,
+                                                 le32_to_cpu(entry->e_id));
                                break;
 
                        default:
@@ -91,14 +98,19 @@ ext3_acl_to_disk(const struct posix_acl *acl, size_t *size)
        ext_acl->a_version = cpu_to_le32(EXT3_ACL_VERSION);
        e = (char *)ext_acl + sizeof(ext3_acl_header);
        for (n=0; n < acl->a_count; n++) {
+               const struct posix_acl_entry *acl_e = &acl->a_entries[n];
                ext3_acl_entry *entry = (ext3_acl_entry *)e;
-               entry->e_tag  = cpu_to_le16(acl->a_entries[n].e_tag);
-               entry->e_perm = cpu_to_le16(acl->a_entries[n].e_perm);
-               switch(acl->a_entries[n].e_tag) {
+               entry->e_tag  = cpu_to_le16(acl_e->e_tag);
+               entry->e_perm = cpu_to_le16(acl_e->e_perm);
+               switch(acl_e->e_tag) {
                        case ACL_USER:
+                               entry->e_id = cpu_to_le32(
+                                       from_kuid(&init_user_ns, acl_e->e_uid));
+                               e += sizeof(ext3_acl_entry);
+                               break;
                        case ACL_GROUP:
-                               entry->e_id =
-                                       cpu_to_le32(acl->a_entries[n].e_id);
+                               entry->e_id = cpu_to_le32(
+                                       from_kgid(&init_user_ns, acl_e->e_gid));
                                e += sizeof(ext3_acl_entry);
                                break;
 
index 42b95fc..d3c5b88 100644 (file)
@@ -55,16 +55,23 @@ ext4_acl_from_disk(const void *value, size_t size)
                case ACL_OTHER:
                        value = (char *)value +
                                sizeof(ext4_acl_entry_short);
-                       acl->a_entries[n].e_id = ACL_UNDEFINED_ID;
                        break;
 
                case ACL_USER:
+                       value = (char *)value + sizeof(ext4_acl_entry);
+                       if ((char *)value > end)
+                               goto fail;
+                       acl->a_entries[n].e_uid =
+                               make_kuid(&init_user_ns,
+                                         le32_to_cpu(entry->e_id));
+                       break;
                case ACL_GROUP:
                        value = (char *)value + sizeof(ext4_acl_entry);
                        if ((char *)value > end)
                                goto fail;
-                       acl->a_entries[n].e_id =
-                               le32_to_cpu(entry->e_id);
+                       acl->a_entries[n].e_gid =
+                               make_kgid(&init_user_ns,
+                                         le32_to_cpu(entry->e_id));
                        break;
 
                default:
@@ -98,13 +105,19 @@ ext4_acl_to_disk(const struct posix_acl *acl, size_t *size)
        ext_acl->a_version = cpu_to_le32(EXT4_ACL_VERSION);
        e = (char *)ext_acl + sizeof(ext4_acl_header);
        for (n = 0; n < acl->a_count; n++) {
+               const struct posix_acl_entry *acl_e = &acl->a_entries[n];
                ext4_acl_entry *entry = (ext4_acl_entry *)e;
-               entry->e_tag  = cpu_to_le16(acl->a_entries[n].e_tag);
-               entry->e_perm = cpu_to_le16(acl->a_entries[n].e_perm);
-               switch (acl->a_entries[n].e_tag) {
+               entry->e_tag  = cpu_to_le16(acl_e->e_tag);
+               entry->e_perm = cpu_to_le16(acl_e->e_perm);
+               switch (acl_e->e_tag) {
                case ACL_USER:
+                       entry->e_id = cpu_to_le32(
+                               from_kuid(&init_user_ns, acl_e->e_uid));
+                       e += sizeof(ext4_acl_entry);
+                       break;
                case ACL_GROUP:
-                       entry->e_id = cpu_to_le32(acl->a_entries[n].e_id);
+                       entry->e_id = cpu_to_le32(
+                               from_kgid(&init_user_ns, acl_e->e_gid));
                        e += sizeof(ext4_acl_entry);
                        break;
 
index 2a388e5..ed6310b 100644 (file)
@@ -927,7 +927,6 @@ config UIDGID_CONVERTED
        # Features
        depends on IMA = n
        depends on EVM = n
-       depends on FS_POSIX_ACL = n
        depends on QUOTA = n
        depends on QUOTACTL = n