Example #1
0
static int
set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key)
{
	int len;
	size_t buflen;
	char *buf = NULL;
	int error = 0;
	struct inode *inode = dentry->d_inode;

	buflen = posix_acl_xattr_size(pacl->a_count);
	buf = kmalloc(buflen, GFP_KERNEL);
	error = -ENOMEM;
	if (buf == NULL)
		goto out;

	len = posix_acl_to_xattr(pacl, buf, buflen);
	if (len < 0) {
		error = len;
		goto out;
	}

	error = -EOPNOTSUPP;
	if (inode->i_op && inode->i_op->setxattr) {
		down(&inode->i_sem);
		security_inode_setxattr(dentry, key, buf, len, 0);
		error = inode->i_op->setxattr(dentry, key, buf, len, 0);
		if (!error)
			security_inode_post_setxattr(dentry, key, buf, len, 0);
		up(&inode->i_sem);
	}
out:
	kfree(buf);
	return error;
}
Example #2
0
int
vfs_setxattr(struct dentry *dentry, const char *name, const void *value,
		size_t size, int flags)
{
	struct inode *inode = dentry->d_inode;
	int error;

	error = xattr_permission(inode, name, MAY_WRITE);
	if (error)
		return error;

	mutex_lock(&inode->i_mutex);
	error = security_inode_setxattr(dentry, name, value, size, flags);
	if (error)
		goto out;
	error = -EOPNOTSUPP;
	if (inode->i_op->setxattr) {
		error = inode->i_op->setxattr(dentry, name, value, size, flags);
		if (!error) {
			fsnotify_xattr(dentry);
			security_inode_post_setxattr(dentry, name, value,
						     size, flags);
		}
	} else if (!strncmp(name, XATTR_SECURITY_PREFIX,
				XATTR_SECURITY_PREFIX_LEN)) {
		const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
		error = security_inode_setsecurity(inode, suffix, value,
						   size, flags);
		if (!error)
			fsnotify_xattr(dentry);
	}
out:
	mutex_unlock(&inode->i_mutex);
	return error;
}
Example #3
0
/*
 * Extended attribute SET operations
 */
static long
setxattr(struct dentry *d, char __user *name, void __user *value,
	 size_t size, int flags)
{
	int error;
	void *kvalue = NULL;
	char kname[XATTR_NAME_MAX + 1];

	if (flags & ~(XATTR_CREATE|XATTR_REPLACE))
		return -EINVAL;

	error = strncpy_from_user(kname, name, sizeof(kname));
	if (error == 0 || error == sizeof(kname))
		error = -ERANGE;
	if (error < 0)
		return error;

	if (size) {
		if (size > XATTR_SIZE_MAX)
			return -E2BIG;
		kvalue = kmalloc(size, GFP_KERNEL);
		if (!kvalue)
			return -ENOMEM;
		if (copy_from_user(kvalue, value, size)) {
			kfree(kvalue);
			return -EFAULT;
		}
	}

	error = -EOPNOTSUPP;
	if (d->d_inode->i_op && d->d_inode->i_op->setxattr) {
		down(&d->d_inode->i_sem);
		audit_notify_watch(d->d_inode, MAY_WRITE);
		error = security_inode_setxattr(d, kname, kvalue, size, flags);
		if (error)
			goto out;
		error = d->d_inode->i_op->setxattr(d, kname, kvalue, size, flags);
		if (!error)
			security_inode_post_setxattr(d, kname, kvalue, size, flags);
out:
		up(&d->d_inode->i_sem);
	}
	if (kvalue)
		kfree(kvalue);
	return error;
}
Example #4
0
/**
 *  __vfs_setxattr_noperm - perform setxattr operation without performing
 *  permission checks.
 *
 *  @dentry - object to perform setxattr on
 *  @name - xattr name to set
 *  @value - value to set @name to
 *  @size - size of @value
 *  @flags - flags to pass into filesystem operations
 *
 *  returns the result of the internal setxattr or setsecurity operations.
 *
 *  This function requires the caller to lock the inode's i_mutex before it
 *  is executed. It also assumes that the caller will make the appropriate
 *  permission checks.
 */
int __vfs_setxattr_noperm(struct dentry *dentry, const char *name,
		const void *value, size_t size, int flags)
{
	struct inode *inode = dentry->d_inode;
	int error = -EOPNOTSUPP;

	if (inode->i_op->setxattr) {
		error = inode->i_op->setxattr(dentry, name, value, size, flags);
		if (!error) {
			fsnotify_xattr(dentry);
			security_inode_post_setxattr(dentry, name, value,
						     size, flags);
		}
	} else if (!strncmp(name, XATTR_SECURITY_PREFIX,
				XATTR_SECURITY_PREFIX_LEN)) {
		const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
		error = security_inode_setsecurity(inode, suffix, value,
						   size, flags);
		if (!error)
			fsnotify_xattr(dentry);
	}

	return error;
}
Example #5
0
/*Not Working Yet*/
static int copyup_xattrs(struct dentry *old_hidden_dentry,
			 struct dentry *new_hidden_dentry)
{
	int err = 0;
	ssize_t list_size = -1;
	char *name_list = NULL;
	char *attr_value = NULL;
	char *name_list_orig = NULL;

	print_entry_location();

	PASSERT(old_hidden_dentry);
	PASSERT(old_hidden_dentry->d_inode);
	PASSERT(old_hidden_dentry->d_inode->i_op);
	PASSERT(new_hidden_dentry);
	PASSERT(new_hidden_dentry->d_inode);
	PASSERT(new_hidden_dentry->d_inode->i_op);

	if (!old_hidden_dentry->d_inode->i_op->getxattr ||
	    !old_hidden_dentry->d_inode->i_op->listxattr ||
	    !new_hidden_dentry->d_inode->i_op->setxattr) {
		err = -ENOTSUPP;
		goto out;
	}

	list_size =
	    old_hidden_dentry->d_inode->i_op->listxattr(old_hidden_dentry, NULL,
							0);
	if (list_size <= 0) {
		err = list_size;
		goto out;
	}

	name_list = xattr_alloc(list_size + 1, XATTR_LIST_MAX);
	if (!name_list || IS_ERR(name_list)) {
		err = PTR_ERR(name_list);
		goto out;
	}
	list_size =
	    old_hidden_dentry->d_inode->i_op->listxattr(old_hidden_dentry,
							name_list, list_size);
	attr_value = xattr_alloc(XATTR_SIZE_MAX, XATTR_SIZE_MAX);
	if (!attr_value || IS_ERR(attr_value)) {
		err = PTR_ERR(name_list);
		goto out;
	}
	name_list_orig = name_list;
	while (*name_list) {
		ssize_t size;
		down(&old_hidden_dentry->d_inode->i_sem);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
		err = security_inode_getxattr(old_hidden_dentry, name_list);
		if (err)
			size = err;
		else
#endif
			size =
			    old_hidden_dentry->d_inode->i_op->
			    getxattr(old_hidden_dentry, name_list, attr_value,
				     XATTR_SIZE_MAX);
		up(&old_hidden_dentry->d_inode->i_sem);
		if (size < 0) {
			err = size;
			goto out;
		}

		if (size > XATTR_SIZE_MAX) {
			err = -E2BIG;
			goto out;
		}

		down(&new_hidden_dentry->d_inode->i_sem);

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
		err =
		    security_inode_setxattr(old_hidden_dentry, name_list,
					    attr_value, size, 0);

		if (!err) {
#endif
			err =
			    new_hidden_dentry->d_inode->i_op->
			    setxattr(new_hidden_dentry, name_list, attr_value,
				     size, 0);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
			if (!err)
				security_inode_post_setxattr(old_hidden_dentry,
							     name_list,
							     attr_value, size,
							     0);
		}
#endif
		up(&new_hidden_dentry->d_inode->i_sem);

		if (err < 0)
			goto out;
		name_list += strlen(name_list) + 1;
	}
      out:
	name_list = name_list_orig;

	if (name_list)
		xattr_free(name_list, list_size + 1);
	if (attr_value)
		xattr_free(attr_value, XATTR_SIZE_MAX);
	/* It is no big deal if this fails, we just roll with the punches. */
	if (err == -ENOTSUPP)
		err = 0;
	return err;
}