int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) { struct sysfs_dirent *sd = dentry->d_fsdata; void *secdata; int error; u32 secdata_len = 0; if (!sd) return -EINVAL; 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; mutex_lock(&sysfs_mutex); error = sysfs_sd_setsecdata(sd, &secdata, &secdata_len); mutex_unlock(&sysfs_mutex); if (secdata) security_release_secctx(secdata, secdata_len); } else return -EINVAL; out: return error; }
static int kernfs_security_xattr_set(const struct xattr_handler *handler, struct dentry *unused, struct inode *inode, const char *suffix, const void *value, size_t size, int flags) { struct kernfs_node *kn = inode->i_private; struct kernfs_iattrs *attrs; void *secdata; u32 secdata_len = 0; int error; attrs = kernfs_iattrs(kn); if (!attrs) return -ENOMEM; error = security_inode_setsecurity(inode, suffix, value, size, flags); if (error) return error; error = security_inode_getsecctx(inode, &secdata, &secdata_len); if (error) return error; mutex_lock(&kernfs_mutex); error = kernfs_node_setsecdata(attrs, &secdata, &secdata_len); mutex_unlock(&kernfs_mutex); if (secdata) security_release_secctx(secdata, secdata_len); return error; }
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; }
int kernfs_iop_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) { struct kernfs_node *kn = dentry->d_fsdata; struct kernfs_iattrs *attrs; void *secdata; int error; u32 secdata_len = 0; attrs = kernfs_iattrs(kn); if (!attrs) return -ENOMEM; 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) return error; error = security_inode_getsecctx(dentry->d_inode, &secdata, &secdata_len); if (error) return error; mutex_lock(&kernfs_mutex); error = kernfs_node_setsecdata(kn, &secdata, &secdata_len); mutex_unlock(&kernfs_mutex); if (secdata) security_release_secctx(secdata, secdata_len); return error; } else if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) { return simple_xattr_set(&attrs->xattrs, name, value, size, flags); } return -EINVAL; }