static int flask_security_set_bool(struct xen_flask_boolean *arg) { int rv; rv = domain_has_security(current->domain, SECURITY__SETBOOL); if ( rv ) return rv; rv = flask_security_resolve_bool(arg); if ( rv ) return rv; spin_lock(&sel_sem); if ( arg->commit ) { int num; int *values; rv = security_get_bools(&num, NULL, &values, NULL); if ( rv != 0 ) goto out; if ( arg->bool_id >= num ) { xfree(values); rv = -ENOENT; goto out; } values[arg->bool_id] = !!(arg->new_value); arg->enforcing = arg->pending = !!(arg->new_value); if ( bool_pending_values ) bool_pending_values[arg->bool_id] = !!(arg->new_value); rv = security_set_bools(num, values); xfree(values); } else { if ( !bool_pending_values ) rv = flask_security_make_bools(); if ( !rv && arg->bool_id >= bool_num ) rv = -ENOENT; if ( rv ) goto out; bool_pending_values[arg->bool_id] = !!(arg->new_value); arg->pending = !!(arg->new_value); arg->enforcing = security_get_bool_value(arg->bool_id); rv = 0; } out: spin_unlock(&sel_sem); return rv; }
static ssize_t sel_commit_bools_write(struct file *filep, const char __user *buf, size_t count, loff_t *ppos) { char *page = NULL; ssize_t length; int new_value; mutex_lock(&sel_mutex); length = task_has_security(current, SECURITY__SETBOOL); if (length) goto out; length = -ENOMEM; if (count >= PAGE_SIZE) goto out; /* No partial writes. */ length = -EINVAL; if (*ppos != 0) goto out; length = -ENOMEM; page = (char *)get_zeroed_page(GFP_KERNEL); if (!page) goto out; length = -EFAULT; if (copy_from_user(page, buf, count)) goto out; length = -EINVAL; if (sscanf(page, "%d", &new_value) != 1) goto out; length = 0; if (new_value && bool_pending_values) length = security_set_bools(bool_num, bool_pending_values); if (!length) length = count; out: mutex_unlock(&sel_mutex); free_page((unsigned long) page); return length; }
static ssize_t sel_commit_bools_write(struct file *filep, const char __user *buf, size_t count, loff_t *ppos) { char *page = NULL; ssize_t length; int new_value; mutex_lock(&sel_mutex); length = avc_has_perm(current_sid(), SECINITSID_SECURITY, SECCLASS_SECURITY, SECURITY__SETBOOL, NULL); if (length) goto out; length = -ENOMEM; if (count >= PAGE_SIZE) goto out; /* No partial writes. */ length = -EINVAL; if (*ppos != 0) goto out; page = memdup_user_nul(buf, count); if (IS_ERR(page)) { length = PTR_ERR(page); page = NULL; goto out; } length = -EINVAL; if (sscanf(page, "%d", &new_value) != 1) goto out; length = 0; if (new_value && bool_pending_values) length = security_set_bools(bool_num, bool_pending_values); if (!length) length = count; out: mutex_unlock(&sel_mutex); kfree(page); return length; }
static int flask_security_commit_bools(void) { int rv; spin_lock(&sel_sem); rv = domain_has_security(current->domain, SECURITY__SETBOOL); if ( rv ) goto out; if ( bool_pending_values ) rv = security_set_bools(bool_num, bool_pending_values); out: spin_unlock(&sel_sem); return rv; }