Пример #1
0
int ext4_to_fuse_acl(acl_ea_header **facl, size_t *facl_sz,
		     const ext4_acl_header *eacl, size_t eacl_sz)
{
	int i, eacl_count;
	acl_ea_header *f;
	ext4_acl_entry *e;
	acl_ea_entry *a;
	size_t f_sz;
	unsigned char *hptr;
	int err = 0;

	eacl_count = ext4_acl_count(eacl_sz);
	f_sz = acl_ea_size(eacl_count);
	if (eacl_count < 0 ||
	    eacl->a_version != ext2fs_cpu_to_le32(EXT4_ACL_VERSION))
		return -EINVAL;

	f = malloc(f_sz);
	if (!f)
		return -ENOMEM;

	f->a_version = ACL_EA_VERSION;
	hptr = (unsigned char *) (eacl + 1);
	for (i = 0, a = f->a_entries; i < eacl_count; i++, a++) {
		e = (ext4_acl_entry *) hptr;
		a->e_tag = ext2fs_le16_to_cpu(e->e_tag);
		a->e_perm = ext2fs_le16_to_cpu(e->e_perm);

		switch (a->e_tag) {
		case ACL_USER:
		case ACL_GROUP:
			a->e_id = ext2fs_le32_to_cpu(e->e_id);
			hptr += sizeof(ext4_acl_entry);
			break;
		case ACL_USER_OBJ:
		case ACL_GROUP_OBJ:
		case ACL_MASK:
		case ACL_OTHER:
			hptr += sizeof(ext4_acl_entry_short);
			break;
		default:
			err = -EINVAL;
			goto out;
		}
	}

	*facl = f;
	*facl_sz = f_sz;
	return err;
out:
	free(f);
	return err;
}
Пример #2
0
/*
 * Convert from filesystem to in-memory representation.
 */
static struct posix_acl *
ext4_acl_from_disk(const void *value, size_t size)
{
	const char *end = (char *)value + size;
	int n, count;
	struct posix_acl *acl;

	if (!value)
		return NULL;
	if (size < sizeof(ext4_acl_header))
		 return ERR_PTR(-EINVAL);
	if (((ext4_acl_header *)value)->a_version !=
	    cpu_to_le32(EXT4_ACL_VERSION))
		return ERR_PTR(-EINVAL);
	value = (char *)value + sizeof(ext4_acl_header);
	count = ext4_acl_count(size);
	if (count < 0)
		return ERR_PTR(-EINVAL);
	if (count == 0)
		return NULL;
	acl = posix_acl_alloc(count, GFP_NOFS);
	if (!acl)
		return ERR_PTR(-ENOMEM);
	for (n = 0; n < count; n++) {
		ext4_acl_entry *entry =
			(ext4_acl_entry *)value;
		if ((char *)value + sizeof(ext4_acl_entry_short) > end)
			goto fail;
		acl->a_entries[n].e_tag  = le16_to_cpu(entry->e_tag);
		acl->a_entries[n].e_perm = le16_to_cpu(entry->e_perm);

		switch (acl->a_entries[n].e_tag) {
		case ACL_USER_OBJ:
		case ACL_GROUP_OBJ:
		case ACL_MASK:
		case ACL_OTHER:
			value = (char *)value +
				sizeof(ext4_acl_entry_short);
			acl->a_entries[n].e_id = ACL_UNDEFINED_ID;
			break;

		case ACL_USER:
		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);
			break;

		default:
			goto fail;
		}
	}
	if (value != end)
		goto fail;
	return acl;

fail:
	posix_acl_release(acl);
	return ERR_PTR(-EINVAL);
}