Example #1
0
int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr * iattr)
{
	struct sysfs_inode_attrs *sd_attrs;
	struct iattr *iattrs;
	unsigned int ia_valid = iattr->ia_valid;

	sd_attrs = sd->s_iattr;

	if (!sd_attrs) {
		/* setting attributes for the first time, allocate now */
		sd_attrs = sysfs_init_inode_attrs(sd);
		if (!sd_attrs)
			return -ENOMEM;
		sd->s_iattr = sd_attrs;
	}
	/* attributes were changed at least once in past */
	iattrs = &sd_attrs->ia_iattr;

	if (ia_valid & ATTR_UID)
		iattrs->ia_uid = iattr->ia_uid;
	if (ia_valid & ATTR_GID)
		iattrs->ia_gid = iattr->ia_gid;
	if (ia_valid & ATTR_ATIME)
		iattrs->ia_atime = iattr->ia_atime;
	if (ia_valid & ATTR_MTIME)
		iattrs->ia_mtime = iattr->ia_mtime;
	if (ia_valid & ATTR_CTIME)
		iattrs->ia_ctime = iattr->ia_ctime;
	if (ia_valid & ATTR_MODE) {
		umode_t mode = iattr->ia_mode;
		iattrs->ia_mode = sd->s_mode = mode;
	}
	return 0;
}
Example #2
0
int sysfs_setattr(struct dentry * dentry, struct iattr * iattr)
{
	struct inode * inode = dentry->d_inode;
	struct sysfs_dirent * sd = dentry->d_fsdata;
	struct sysfs_inode_attrs *sd_attrs;
	struct iattr *iattrs;
	unsigned int ia_valid = iattr->ia_valid;
	int error;

	if (!sd)
		return -EINVAL;

	sd_attrs = sd->s_iattr;

	error = inode_change_ok(inode, iattr);
	if (error)
		return error;

	iattr->ia_valid &= ~ATTR_SIZE; /* ignore size changes */

	error = inode_setattr(inode, iattr);
	if (error)
		return error;

	if (!sd_attrs) {
		/* setting attributes for the first time, allocate now */
		sd_attrs = sysfs_init_inode_attrs(sd);
		if (!sd_attrs)
			return -ENOMEM;
		sd->s_iattr = sd_attrs;
	}
	/* attributes were changed at least once in past */
	iattrs = &sd_attrs->ia_iattr;

	if (ia_valid & ATTR_UID)
		iattrs->ia_uid = iattr->ia_uid;
	if (ia_valid & ATTR_GID)
		iattrs->ia_gid = iattr->ia_gid;
	if (ia_valid & ATTR_ATIME)
		iattrs->ia_atime = timespec_trunc(iattr->ia_atime,
			inode->i_sb->s_time_gran);
	if (ia_valid & ATTR_MTIME)
		iattrs->ia_mtime = timespec_trunc(iattr->ia_mtime,
			inode->i_sb->s_time_gran);
	if (ia_valid & ATTR_CTIME)
		iattrs->ia_ctime = timespec_trunc(iattr->ia_ctime,
			inode->i_sb->s_time_gran);
	if (ia_valid & ATTR_MODE) {
		umode_t mode = iattr->ia_mode;

		if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
			mode &= ~S_ISGID;
		iattrs->ia_mode = sd->s_mode = mode;
	}
	return error;
}
Example #3
0
int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value,
		size_t size, int flags)
{
	struct sysfs_dirent *sd = dentry->d_fsdata;
	struct sysfs_inode_attrs *iattrs;
	void *secdata;
	int error;
	u32 secdata_len = 0;

	if (!sd)
		return -EINVAL;
	if (!sd->s_iattr)
		sd->s_iattr = sysfs_init_inode_attrs(sd);
	if (!sd->s_iattr)
		return -ENOMEM;

	iattrs = sd->s_iattr;

	if (!strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN)) {
		const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
		error = security_inode_setsecurity(dentry->d_inode, suffix,
						value, size, flags);
		if (error)
			goto out;
		error = security_inode_getsecctx(dentry->d_inode,
						&secdata, &secdata_len);
		if (error)
			goto out;
		if (iattrs->ia_secdata)
			security_release_secctx(iattrs->ia_secdata,
						iattrs->ia_secdata_len);
		iattrs->ia_secdata = secdata;
		iattrs->ia_secdata_len = secdata_len;

	} else
		return -EINVAL;
out:
	return error;
}
Example #4
0
static int sysfs_sd_setsecdata(struct sysfs_dirent *sd, void **secdata, u32 *secdata_len)
{
	struct sysfs_inode_attrs *iattrs;
	void *old_secdata;
	size_t old_secdata_len;

	iattrs = sd->s_iattr;
	if (!iattrs)
		iattrs = sysfs_init_inode_attrs(sd);
	if (!iattrs)
		return -ENOMEM;

	old_secdata = iattrs->ia_secdata;
	old_secdata_len = iattrs->ia_secdata_len;

	iattrs->ia_secdata = *secdata;
	iattrs->ia_secdata_len = *secdata_len;

	*secdata = old_secdata;
	*secdata_len = old_secdata_len;
	return 0;
}