⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 policydb.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		lra = ra;	}	kfree(lra);	for (rt = p->range_tr; rt; rt = rt -> next) {		cond_resched();		if (lrt) {			ebitmap_destroy(&lrt->target_range.level[0].cat);			ebitmap_destroy(&lrt->target_range.level[1].cat);			kfree(lrt);		}		lrt = rt;	}	if (lrt) {		ebitmap_destroy(&lrt->target_range.level[0].cat);		ebitmap_destroy(&lrt->target_range.level[1].cat);		kfree(lrt);	}	if (p->type_attr_map) {		for (i = 0; i < p->p_types.nprim; i++)			ebitmap_destroy(&p->type_attr_map[i]);	}	kfree(p->type_attr_map);	kfree(p->undefined_perms);	return;}/* * Load the initial SIDs specified in a policy database * structure into a SID table. */int policydb_load_isids(struct policydb *p, struct sidtab *s){	struct ocontext *head, *c;	int rc;	rc = sidtab_init(s);	if (rc) {		printk(KERN_ERR "security:  out of memory on SID table init\n");		goto out;	}	head = p->ocontexts[OCON_ISID];	for (c = head; c; c = c->next) {		if (!c->context[0].user) {			printk(KERN_ERR "security:  SID %s was never "			       "defined.\n", c->u.name);			rc = -EINVAL;			goto out;		}		if (sidtab_insert(s, c->sid[0], &c->context[0])) {			printk(KERN_ERR "security:  unable to load initial "			       "SID %s.\n", c->u.name);			rc = -EINVAL;			goto out;		}	}out:	return rc;}int policydb_class_isvalid(struct policydb *p, unsigned int class){	if (!class || class > p->p_classes.nprim)		return 0;	return 1;}int policydb_role_isvalid(struct policydb *p, unsigned int role){	if (!role || role > p->p_roles.nprim)		return 0;	return 1;}int policydb_type_isvalid(struct policydb *p, unsigned int type){	if (!type || type > p->p_types.nprim)		return 0;	return 1;}/* * Return 1 if the fields in the security context * structure `c' are valid.  Return 0 otherwise. */int policydb_context_isvalid(struct policydb *p, struct context *c){	struct role_datum *role;	struct user_datum *usrdatum;	if (!c->role || c->role > p->p_roles.nprim)		return 0;	if (!c->user || c->user > p->p_users.nprim)		return 0;	if (!c->type || c->type > p->p_types.nprim)		return 0;	if (c->role != OBJECT_R_VAL) {		/*		 * Role must be authorized for the type.		 */		role = p->role_val_to_struct[c->role - 1];		if (!ebitmap_get_bit(&role->types,				     c->type - 1))			/* role may not be associated with type */			return 0;		/*		 * User must be authorized for the role.		 */		usrdatum = p->user_val_to_struct[c->user - 1];		if (!usrdatum)			return 0;		if (!ebitmap_get_bit(&usrdatum->roles,				     c->role - 1))			/* user may not be associated with role */			return 0;	}	if (!mls_context_isvalid(p, c))		return 0;	return 1;}/* * Read a MLS range structure from a policydb binary * representation file. */static int mls_read_range_helper(struct mls_range *r, void *fp){	__le32 buf[2];	u32 items;	int rc;	rc = next_entry(buf, fp, sizeof(u32));	if (rc < 0)		goto out;	items = le32_to_cpu(buf[0]);	if (items > ARRAY_SIZE(buf)) {		printk(KERN_ERR "security: mls:  range overflow\n");		rc = -EINVAL;		goto out;	}	rc = next_entry(buf, fp, sizeof(u32) * items);	if (rc < 0) {		printk(KERN_ERR "security: mls:  truncated range\n");		goto out;	}	r->level[0].sens = le32_to_cpu(buf[0]);	if (items > 1)		r->level[1].sens = le32_to_cpu(buf[1]);	else		r->level[1].sens = r->level[0].sens;	rc = ebitmap_read(&r->level[0].cat, fp);	if (rc) {		printk(KERN_ERR "security: mls:  error reading low "		       "categories\n");		goto out;	}	if (items > 1) {		rc = ebitmap_read(&r->level[1].cat, fp);		if (rc) {			printk(KERN_ERR "security: mls:  error reading high "			       "categories\n");			goto bad_high;		}	} else {		rc = ebitmap_cpy(&r->level[1].cat, &r->level[0].cat);		if (rc) {			printk(KERN_ERR "security: mls:  out of memory\n");			goto bad_high;		}	}	rc = 0;out:	return rc;bad_high:	ebitmap_destroy(&r->level[0].cat);	goto out;}/* * Read and validate a security context structure * from a policydb binary representation file. */static int context_read_and_validate(struct context *c,				     struct policydb *p,				     void *fp){	__le32 buf[3];	int rc;	rc = next_entry(buf, fp, sizeof buf);	if (rc < 0) {		printk(KERN_ERR "security: context truncated\n");		goto out;	}	c->user = le32_to_cpu(buf[0]);	c->role = le32_to_cpu(buf[1]);	c->type = le32_to_cpu(buf[2]);	if (p->policyvers >= POLICYDB_VERSION_MLS) {		if (mls_read_range_helper(&c->range, fp)) {			printk(KERN_ERR "security: error reading MLS range of "			       "context\n");			rc = -EINVAL;			goto out;		}	}	if (!policydb_context_isvalid(p, c)) {		printk(KERN_ERR "security:  invalid security context\n");		context_destroy(c);		rc = -EINVAL;	}out:	return rc;}/* * The following *_read functions are used to * read the symbol data from a policy database * binary representation file. */static int perm_read(struct policydb *p, struct hashtab *h, void *fp){	char *key = NULL;	struct perm_datum *perdatum;	int rc;	__le32 buf[2];	u32 len;	perdatum = kzalloc(sizeof(*perdatum), GFP_KERNEL);	if (!perdatum) {		rc = -ENOMEM;		goto out;	}	rc = next_entry(buf, fp, sizeof buf);	if (rc < 0)		goto bad;	len = le32_to_cpu(buf[0]);	perdatum->value = le32_to_cpu(buf[1]);	key = kmalloc(len + 1,GFP_KERNEL);	if (!key) {		rc = -ENOMEM;		goto bad;	}	rc = next_entry(key, fp, len);	if (rc < 0)		goto bad;	key[len] = 0;	rc = hashtab_insert(h, key, perdatum);	if (rc)		goto bad;out:	return rc;bad:	perm_destroy(key, perdatum, NULL);	goto out;}static int common_read(struct policydb *p, struct hashtab *h, void *fp){	char *key = NULL;	struct common_datum *comdatum;	__le32 buf[4];	u32 len, nel;	int i, rc;	comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL);	if (!comdatum) {		rc = -ENOMEM;		goto out;	}	rc = next_entry(buf, fp, sizeof buf);	if (rc < 0)		goto bad;	len = le32_to_cpu(buf[0]);	comdatum->value = le32_to_cpu(buf[1]);	rc = symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE);	if (rc)		goto bad;	comdatum->permissions.nprim = le32_to_cpu(buf[2]);	nel = le32_to_cpu(buf[3]);	key = kmalloc(len + 1,GFP_KERNEL);	if (!key) {		rc = -ENOMEM;		goto bad;	}	rc = next_entry(key, fp, len);	if (rc < 0)		goto bad;	key[len] = 0;	for (i = 0; i < nel; i++) {		rc = perm_read(p, comdatum->permissions.table, fp);		if (rc)			goto bad;	}	rc = hashtab_insert(h, key, comdatum);	if (rc)		goto bad;out:	return rc;bad:	common_destroy(key, comdatum, NULL);	goto out;}static int read_cons_helper(struct constraint_node **nodep, int ncons,                            int allowxtarget, void *fp){	struct constraint_node *c, *lc;	struct constraint_expr *e, *le;	__le32 buf[3];	u32 nexpr;	int rc, i, j, depth;	lc = NULL;	for (i = 0; i < ncons; i++) {		c = kzalloc(sizeof(*c), GFP_KERNEL);		if (!c)			return -ENOMEM;		if (lc) {			lc->next = c;		} else {			*nodep = c;		}		rc = next_entry(buf, fp, (sizeof(u32) * 2));		if (rc < 0)			return rc;		c->permissions = le32_to_cpu(buf[0]);		nexpr = le32_to_cpu(buf[1]);		le = NULL;		depth = -1;		for (j = 0; j < nexpr; j++) {			e = kzalloc(sizeof(*e), GFP_KERNEL);			if (!e)				return -ENOMEM;			if (le) {				le->next = e;			} else {				c->expr = e;			}			rc = next_entry(buf, fp, (sizeof(u32) * 3));			if (rc < 0)				return rc;			e->expr_type = le32_to_cpu(buf[0]);			e->attr = le32_to_cpu(buf[1]);			e->op = le32_to_cpu(buf[2]);			switch (e->expr_type) {			case CEXPR_NOT:				if (depth < 0)					return -EINVAL;				break;			case CEXPR_AND:			case CEXPR_OR:				if (depth < 1)					return -EINVAL;				depth--;				break;			case CEXPR_ATTR:				if (depth == (CEXPR_MAXDEPTH - 1))					return -EINVAL;				depth++;				break;			case CEXPR_NAMES:				if (!allowxtarget && (e->attr & CEXPR_XTARGET))					return -EINVAL;				if (depth == (CEXPR_MAXDEPTH - 1))					return -EINVAL;				depth++;				if (ebitmap_read(&e->names, fp))					return -EINVAL;				break;			default:				return -EINVAL;			}			le = e;		}		if (depth != 0)			return -EINVAL;		lc = c;	}	return 0;}static int class_read(struct policydb *p, struct hashtab *h, void *fp){	char *key = NULL;	struct class_datum *cladatum;	__le32 buf[6];	u32 len, len2, ncons, nel;	int i, rc;	cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL);	if (!cladatum) {		rc = -ENOMEM;		goto out;	}	rc = next_entry(buf, fp, sizeof(u32)*6);	if (rc < 0)		goto bad;	len = le32_to_cpu(buf[0]);	len2 = le32_to_cpu(buf[1]);	cladatum->value = le32_to_cpu(buf[2]);	rc = symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE);	if (rc)		goto bad;	cladatum->permissions.nprim = le32_to_cpu(buf[3]);	nel = le32_to_cpu(buf[4]);	ncons = le32_to_cpu(buf[5]);	key = kmalloc(len + 1,GFP_KERNEL);	if (!key) {		rc = -ENOMEM;		goto bad;	}	rc = next_entry(key, fp, len);	if (rc < 0)		goto bad;	key[len] = 0;	if (len2) {		cladatum->comkey = kmalloc(len2 + 1,GFP_KERNEL);		if (!cladatum->comkey) {			rc = -ENOMEM;			goto bad;		}		rc = next_entry(cladatum->comkey, fp, len2);		if (rc < 0)			goto bad;		cladatum->comkey[len2] = 0;		cladatum->comdatum = hashtab_search(p->p_commons.table,						    cladatum->comkey);		if (!cladatum->comdatum) {			printk(KERN_ERR "security:  unknown common %s\n",			       cladatum->comkey);			rc = -EINVAL;			goto bad;		}	}	for (i = 0; i < nel; i++) {		rc = perm_read(p, cladatum->permissions.table, fp);		if (rc)			goto bad;	}	rc = read_cons_helper(&cladatum->constraints, ncons, 0, fp);	if (rc)		goto bad;	if (p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) {		/* grab the validatetrans rules */		rc = next_entry(buf, fp, sizeof(u32));		if (rc < 0)			goto bad;		ncons = le32_to_cpu(buf[0]);		rc = read_cons_helper(&cladatum->validatetrans, ncons, 1, fp);		if (rc)			goto bad;	}	rc = hashtab_insert(h, key, cladatum);	if (rc)		goto bad;	rc = 0;out:	return rc;bad:	cls_destroy(key, cladatum, NULL);	goto out;}static int role_read(struct policydb *p, struct hashtab *h, void *fp){	char *key = NULL;	struct role_datum *role;	int rc;	__le32 buf[2];	u32 len;	role = kzalloc(sizeof(*role), GFP_KERNEL);	if (!role) {		rc = -ENOMEM;		goto out;	}	rc = next_entry(buf, fp, sizeof buf);	if (rc < 0)		goto bad;	len = le32_to_cpu(buf[0]);	role->value = le32_to_cpu(buf[1]);	key = kmalloc(len + 1,GFP_KERNEL);	if (!key) {		rc = -ENOMEM;		goto bad;	}	rc = next_entry(key, fp, len);	if (rc < 0)		goto bad;	key[len] = 0;	rc = ebitmap_read(&role->dominates, fp);	if (rc)		goto bad;	rc = ebitmap_read(&role->types, fp);	if (rc)		goto bad;	if (strcmp(key, OBJECT_R) == 0) {		if (role->value != OBJECT_R_VAL) {			printk(KERN_ERR "Role %s has wrong value %d\n",			       OBJECT_R, role->value);			rc = -EINVAL;			goto bad;		}		rc = 0;		goto bad;	}	rc = hashtab_insert(h, key, role);	if (rc)		goto bad;out:	return rc;bad:	role_destroy(key, role, NULL);	goto out;}static int type_read(struct policydb *p, struct hashtab *h, void *fp){	char *key = NULL;	struct type_datum *typdatum;	int rc;	__le32 buf[3];	u32 len;	typdatum = kzalloc(sizeof(*typdatum),GFP_KERNEL);	if (!typdatum) {		rc = -ENOMEM;		return rc;	}	rc = next_entry(buf, fp, sizeof buf);	if (rc < 0)		goto bad;	len = le32_to_cpu(buf[0]);	typdatum->value = le32_to_cpu(buf[1]);	typdatum->primary = le32_to_cpu(buf[2]);	key = kmalloc(len + 1,GFP_KERNEL);	if (!key) {		rc = -ENOMEM;		goto bad;	}	rc = next_entry(key, fp, len);	if (rc < 0)		goto bad;	key[len] = 0;	rc = hashtab_insert(h, key, typdatum);	if (rc)		goto bad;out:	return rc;bad:	type_destroy(key, typdatum, NULL);	goto out;}/* * Read a MLS level structure from a policydb binary * representation file. */static int mls_read_level(struct mls_level *lp, void *fp){	__le32 buf[1];	int rc;	memset(lp, 0, sizeof(*lp));	rc = next_entry(buf, fp, sizeof buf);	if (rc < 0) {		printk(KERN_ERR "security: mls: truncated level\n");		goto bad;	}	lp->sens = le32_to_cpu(buf[0]);	if (ebitmap_read(&lp->cat, fp)) {		printk(KERN_ERR "security: mls:  error reading level "		       "categories\n");		goto bad;	}	return 0;bad:	return -EINVAL;}static int user_read(struct policydb *p, struct hashtab *h, void *fp){	char *key = NULL;	struct user_datum *usrdatum;	int rc;	__le32 buf[2];	u32 len;	usrdatum = kzalloc(sizeof(*usrdatum), GFP_KERNEL);	if (!usrdatum) {		rc = -ENOMEM;		goto out;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -