On Wed, 2018-05-09 at 13:28 -0700, Matthew Garrett wrote: > +/** > + * evm_write_xattrs - write() for <securityfs>/evm_xattrs > + * @file: file pointer, not actually used > + * @buf: where to get the data from > + * @count: bytes sent > + * @ppos: where to start > + * > + * Returns number of bytes written or error code, as appropriate > + */ > +static ssize_t evm_write_xattrs(struct file *file, const char __user *buf, > + size_t count, loff_t *ppos) > +{ > + int len, err; > + struct xattr_list *xattr, *tmp; > + > + if (!capable(CAP_SYS_ADMIN) || evm_xattrs_locked) > + return -EPERM; > + > + if (*ppos != 0) > + return -EINVAL; > + > + if (count > XATTR_NAME_MAX) > + return -E2BIG; > + > + xattr = kmalloc(sizeof(struct xattr_list), GFP_KERNEL); > + if (!xattr) > + return -ENOMEM; > + > + xattr->name = memdup_user_nul(buf, count); > + if (IS_ERR(xattr->name)) { > + err = PTR_ERR(xattr->name); > + kfree(xattr); > + return err; > + } > + > + /* Remove any trailing newline */ > + len = strlen(xattr->name); > + if (xattr->name[len-1] == '\n') > + xattr->name[len-1] = '\0'; > + > + if (strcmp(xattr->name, ".") == 0) { > + evm_xattrs_locked = 1; > + err = count; > + goto out; > + } > + > + /* Guard against races in evm_read_xattrs */ > + mutex_lock(&xattr_list_mutex); > + list_for_each_entry(tmp, &evm_config_xattrnames, list) { > + if (strcmp(xattr->name, tmp->name) == 0) { > + err = -EEXIST; > + mutex_unlock(&xattr_list_mutex); > + goto out; > + } > + } > + list_add_tail_rcu(&xattr->list, &evm_config_xattrnames); > + mutex_unlock(&xattr_list_mutex); > + > + return count; > +out: > + kfree(xattr->name); > + kfree(xattr); > + return err; > +} Shouldn't new xattrs be audited/logged? Mimi