X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=fs%2Fext2%2Facl.c;h=8369ee8d28c4f2249ab20d0cd36645d7d18148de;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=89d1df91411f6e9a35655c6a8feda7578c0d41db;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index 89d1df914..8369ee8d2 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c @@ -255,8 +255,6 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl) return -EINVAL; } if (acl) { - if (acl->a_count > EXT2_ACL_MAX_ENTRIES) - return -EINVAL; value = ext2_acl_to_disk(acl, &size); if (IS_ERR(value)) return (int)PTR_ERR(value); @@ -280,60 +278,24 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl) return error; } -/* - * Inode operation permission(). - * - * inode->i_sem: don't care - */ -int -ext2_permission(struct inode *inode, int mask, struct nameidata *nd) +static int +ext2_check_acl(struct inode *inode, int mask) { - int mode = inode->i_mode; - - /* Nobody gets write access to a read-only fs */ - if ((mask & MAY_WRITE) && IS_RDONLY(inode) && - (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) - return -EROFS; - /* Nobody gets write access to an immutable file */ - if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode)) - return -EACCES; - if (current->fsuid == inode->i_uid) { - mode >>= 6; - } else if (test_opt(inode->i_sb, POSIX_ACL)) { - struct posix_acl *acl; - - /* The access ACL cannot grant access if the group class - permission bits don't contain all requested permissions. */ - if (((mode >> 3) & mask & S_IRWXO) != mask) - goto check_groups; - acl = ext2_get_acl(inode, ACL_TYPE_ACCESS); - if (acl) { - int error = posix_acl_permission(inode, acl, mask); - posix_acl_release(acl); - if (error == -EACCES) - goto check_capabilities; - return error; - } else - goto check_groups; - } else { -check_groups: - if (in_group_p(inode->i_gid)) - mode >>= 3; + struct posix_acl *acl = ext2_get_acl(inode, ACL_TYPE_ACCESS); + + if (acl) { + int error = posix_acl_permission(inode, acl, mask); + posix_acl_release(acl); + return error; } - if ((mode & mask & S_IRWXO) == mask) - return 0; -check_capabilities: - /* Allowed to override Discretionary Access Control? */ - if (!(mask & MAY_EXEC) || - (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode)) - if (capable(CAP_DAC_OVERRIDE)) - return 0; - /* Read and search granted if capable(CAP_DAC_READ_SEARCH) */ - if (capable(CAP_DAC_READ_SEARCH) && ((mask == MAY_READ) || - (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE)))) - return 0; - return -EACCES; + return -EAGAIN; +} + +int +ext2_permission(struct inode *inode, int mask, struct nameidata *nd) +{ + return generic_permission(inode, mask, ext2_check_acl); } /* @@ -429,27 +391,27 @@ ext2_acl_chmod(struct inode *inode) * Extended attribut handlers */ static size_t -ext2_xattr_list_acl_access(char *list, struct inode *inode, - const char *name, int name_len) +ext2_xattr_list_acl_access(struct inode *inode, char *list, size_t list_size, + const char *name, size_t name_len) { const size_t size = sizeof(XATTR_NAME_ACL_ACCESS); if (!test_opt(inode->i_sb, POSIX_ACL)) return 0; - if (list) + if (list && size <= list_size) memcpy(list, XATTR_NAME_ACL_ACCESS, size); return size; } static size_t -ext2_xattr_list_acl_default(char *list, struct inode *inode, - const char *name, int name_len) +ext2_xattr_list_acl_default(struct inode *inode, char *list, size_t list_size, + const char *name, size_t name_len) { const size_t size = sizeof(XATTR_NAME_ACL_DEFAULT); if (!test_opt(inode->i_sb, POSIX_ACL)) return 0; - if (list) + if (list && size <= list_size) memcpy(list, XATTR_NAME_ACL_DEFAULT, size); return size; } @@ -541,45 +503,16 @@ ext2_xattr_set_acl_default(struct inode *inode, const char *name, return ext2_xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size); } -struct ext2_xattr_handler ext2_xattr_acl_access_handler = { +struct xattr_handler ext2_xattr_acl_access_handler = { .prefix = XATTR_NAME_ACL_ACCESS, .list = ext2_xattr_list_acl_access, .get = ext2_xattr_get_acl_access, .set = ext2_xattr_set_acl_access, }; -struct ext2_xattr_handler ext2_xattr_acl_default_handler = { +struct xattr_handler ext2_xattr_acl_default_handler = { .prefix = XATTR_NAME_ACL_DEFAULT, .list = ext2_xattr_list_acl_default, .get = ext2_xattr_get_acl_default, .set = ext2_xattr_set_acl_default, }; - -void -exit_ext2_acl(void) -{ - ext2_xattr_unregister(EXT2_XATTR_INDEX_POSIX_ACL_ACCESS, - &ext2_xattr_acl_access_handler); - ext2_xattr_unregister(EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT, - &ext2_xattr_acl_default_handler); -} - -int __init -init_ext2_acl(void) -{ - int error; - - error = ext2_xattr_register(EXT2_XATTR_INDEX_POSIX_ACL_ACCESS, - &ext2_xattr_acl_access_handler); - if (error) - goto fail; - error = ext2_xattr_register(EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT, - &ext2_xattr_acl_default_handler); - if (error) - goto fail; - return 0; - -fail: - exit_ext2_acl(); - return error; -}