static int sel_make_bools(void) { int i, ret = 0; ssize_t len; struct dentry *dentry = NULL; struct dentry *dir = bool_dir; struct inode *inode = NULL; struct inode_security_struct *isec; char **names = NULL, *page; int num; int *values = NULL; u32 sid; /* remove any existing files */ kfree(bool_pending_names); kfree(bool_pending_values); bool_pending_names = NULL; bool_pending_values = NULL; sel_remove_entries(dir); page = (char *)get_zeroed_page(GFP_KERNEL); if (!page) return -ENOMEM; ret = security_get_bools(&num, &names, &values); if (ret != 0) goto out; for (i = 0; i < num; i++) { dentry = d_alloc_name(dir, names[i]); if (!dentry) { ret = -ENOMEM; goto err; } inode = sel_make_inode(dir->d_sb, S_IFREG | S_IRUGO | S_IWUSR); if (!inode) { ret = -ENOMEM; goto err; } len = snprintf(page, PAGE_SIZE, "/%s/%s", BOOL_DIR_NAME, names[i]); if (len < 0) { ret = -EINVAL; goto err; } else if (len >= PAGE_SIZE) { ret = -ENAMETOOLONG; goto err; } isec = (struct inode_security_struct *)inode->i_security; ret = security_genfs_sid("selinuxfs", page, SECCLASS_FILE, &sid); if (ret) goto err; isec->sid = sid; isec->initialized = 1; inode->i_fop = &sel_bool_ops; inode->i_ino = i|SEL_BOOL_INO_OFFSET; d_add(dentry, inode); } bool_num = num; bool_pending_names = names; bool_pending_values = values; out: free_page((unsigned long)page); return ret; err: if (names) { for (i = 0; i < num; i++) kfree(names[i]); kfree(names); } kfree(values); sel_remove_entries(dir); ret = -ENOMEM; goto out; }
static int sel_make_bools(void) { int i, ret; ssize_t len; struct dentry *dentry = NULL; struct dentry *dir = bool_dir; struct inode *inode = NULL; struct inode_security_struct *isec; char **names = NULL, *page; int num; int *values = NULL; u32 sid; /* remove any existing files */ for (i = 0; i < bool_num; i++) kfree(bool_pending_names[i]); kfree(bool_pending_names); kfree(bool_pending_values); bool_num = 0; bool_pending_names = NULL; bool_pending_values = NULL; sel_remove_entries(dir); ret = -ENOMEM; page = (char *)get_zeroed_page(GFP_KERNEL); if (!page) goto out; ret = security_get_bools(&num, &names, &values); if (ret) goto out; for (i = 0; i < num; i++) { ret = -ENOMEM; dentry = d_alloc_name(dir, names[i]); if (!dentry) goto out; ret = -ENOMEM; inode = sel_make_inode(dir->d_sb, S_IFREG | S_IRUGO | S_IWUSR); if (!inode) goto out; ret = -ENAMETOOLONG; len = snprintf(page, PAGE_SIZE, "/%s/%s", BOOL_DIR_NAME, names[i]); if (len >= PAGE_SIZE) goto out; isec = (struct inode_security_struct *)inode->i_security; ret = security_genfs_sid("selinuxfs", page, SECCLASS_FILE, &sid); if (ret) { pr_warn_ratelimited("SELinux: no sid found, defaulting to security isid for %s\n", page); sid = SECINITSID_SECURITY; } isec->sid = sid; isec->initialized = LABEL_INITIALIZED; inode->i_fop = &sel_bool_ops; inode->i_ino = i|SEL_BOOL_INO_OFFSET; d_add(dentry, inode); } bool_num = num; bool_pending_names = names; bool_pending_values = values; free_page((unsigned long)page); return 0; out: free_page((unsigned long)page); if (names) { for (i = 0; i < num; i++) kfree(names[i]); kfree(names); } kfree(values); sel_remove_entries(dir); return ret; }