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

📄 policydb.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	rc = next_entry(buf, fp, sizeof buf);	if (rc < 0)		goto bad;	len = le32_to_cpu(buf[0]);	usrdatum->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(&usrdatum->roles, fp);	if (rc)		goto bad;	if (p->policyvers >= POLICYDB_VERSION_MLS) {		rc = mls_read_range_helper(&usrdatum->range, fp);		if (rc)			goto bad;		rc = mls_read_level(&usrdatum->dfltlevel, fp);		if (rc)			goto bad;	}	rc = hashtab_insert(h, key, usrdatum);	if (rc)		goto bad;out:	return rc;bad:	user_destroy(key, usrdatum, NULL);	goto out;}static int sens_read(struct policydb *p, struct hashtab *h, void *fp){	char *key = NULL;	struct level_datum *levdatum;	int rc;	__le32 buf[2];	u32 len;	levdatum = kzalloc(sizeof(*levdatum), GFP_ATOMIC);	if (!levdatum) {		rc = -ENOMEM;		goto out;	}	rc = next_entry(buf, fp, sizeof buf);	if (rc < 0)		goto bad;	len = le32_to_cpu(buf[0]);	levdatum->isalias = le32_to_cpu(buf[1]);	key = kmalloc(len + 1,GFP_ATOMIC);	if (!key) {		rc = -ENOMEM;		goto bad;	}	rc = next_entry(key, fp, len);	if (rc < 0)		goto bad;	key[len] = 0;	levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC);	if (!levdatum->level) {		rc = -ENOMEM;		goto bad;	}	if (mls_read_level(levdatum->level, fp)) {		rc = -EINVAL;		goto bad;	}	rc = hashtab_insert(h, key, levdatum);	if (rc)		goto bad;out:	return rc;bad:	sens_destroy(key, levdatum, NULL);	goto out;}static int cat_read(struct policydb *p, struct hashtab *h, void *fp){	char *key = NULL;	struct cat_datum *catdatum;	int rc;	__le32 buf[3];	u32 len;	catdatum = kzalloc(sizeof(*catdatum), GFP_ATOMIC);	if (!catdatum) {		rc = -ENOMEM;		goto out;	}	rc = next_entry(buf, fp, sizeof buf);	if (rc < 0)		goto bad;	len = le32_to_cpu(buf[0]);	catdatum->value = le32_to_cpu(buf[1]);	catdatum->isalias = le32_to_cpu(buf[2]);	key = kmalloc(len + 1,GFP_ATOMIC);	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, catdatum);	if (rc)		goto bad;out:	return rc;bad:	cat_destroy(key, catdatum, NULL);	goto out;}static int (*read_f[SYM_NUM]) (struct policydb *p, struct hashtab *h, void *fp) ={	common_read,	class_read,	role_read,	type_read,	user_read,	cond_read_bool,	sens_read,	cat_read,};extern int ss_initialized;/* * Read the configuration data from a policy database binary * representation file into a policy database structure. */int policydb_read(struct policydb *p, void *fp){	struct role_allow *ra, *lra;	struct role_trans *tr, *ltr;	struct ocontext *l, *c, *newc;	struct genfs *genfs_p, *genfs, *newgenfs;	int i, j, rc;	__le32 buf[8];	u32 len, len2, config, nprim, nel, nel2;	char *policydb_str;	struct policydb_compat_info *info;	struct range_trans *rt, *lrt;	config = 0;	rc = policydb_init(p);	if (rc)		goto out;	/* Read the magic number and string length. */	rc = next_entry(buf, fp, sizeof(u32)* 2);	if (rc < 0)		goto bad;	if (le32_to_cpu(buf[0]) != POLICYDB_MAGIC) {		printk(KERN_ERR "security:  policydb magic number 0x%x does "		       "not match expected magic number 0x%x\n",		       le32_to_cpu(buf[0]), POLICYDB_MAGIC);		goto bad;	}	len = le32_to_cpu(buf[1]);	if (len != strlen(POLICYDB_STRING)) {		printk(KERN_ERR "security:  policydb string length %d does not "		       "match expected length %Zu\n",		       len, strlen(POLICYDB_STRING));		goto bad;	}	policydb_str = kmalloc(len + 1,GFP_KERNEL);	if (!policydb_str) {		printk(KERN_ERR "security:  unable to allocate memory for policydb "		       "string of length %d\n", len);		rc = -ENOMEM;		goto bad;	}	rc = next_entry(policydb_str, fp, len);	if (rc < 0) {		printk(KERN_ERR "security:  truncated policydb string identifier\n");		kfree(policydb_str);		goto bad;	}	policydb_str[len] = 0;	if (strcmp(policydb_str, POLICYDB_STRING)) {		printk(KERN_ERR "security:  policydb string %s does not match "		       "my string %s\n", policydb_str, POLICYDB_STRING);		kfree(policydb_str);		goto bad;	}	/* Done with policydb_str. */	kfree(policydb_str);	policydb_str = NULL;	/* Read the version, config, and table sizes. */	rc = next_entry(buf, fp, sizeof(u32)*4);	if (rc < 0)		goto bad;	p->policyvers = le32_to_cpu(buf[0]);	if (p->policyvers < POLICYDB_VERSION_MIN ||	    p->policyvers > POLICYDB_VERSION_MAX) {	    	printk(KERN_ERR "security:  policydb version %d does not match "	    	       "my version range %d-%d\n",	    	       le32_to_cpu(buf[0]), POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);	    	goto bad;	}	if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {		if (ss_initialized && !selinux_mls_enabled) {			printk(KERN_ERR "Cannot switch between non-MLS and MLS "			       "policies\n");			goto bad;		}		selinux_mls_enabled = 1;		config |= POLICYDB_CONFIG_MLS;		if (p->policyvers < POLICYDB_VERSION_MLS) {			printk(KERN_ERR "security policydb version %d (MLS) "			       "not backwards compatible\n", p->policyvers);			goto bad;		}	} else {		if (ss_initialized && selinux_mls_enabled) {			printk(KERN_ERR "Cannot switch between MLS and non-MLS "			       "policies\n");			goto bad;		}	}	p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);	p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);	info = policydb_lookup_compat(p->policyvers);	if (!info) {		printk(KERN_ERR "security:  unable to find policy compat info "		       "for version %d\n", p->policyvers);		goto bad;	}	if (le32_to_cpu(buf[2]) != info->sym_num ||		le32_to_cpu(buf[3]) != info->ocon_num) {		printk(KERN_ERR "security:  policydb table sizes (%d,%d) do "		       "not match mine (%d,%d)\n", le32_to_cpu(buf[2]),			le32_to_cpu(buf[3]),		       info->sym_num, info->ocon_num);		goto bad;	}	for (i = 0; i < info->sym_num; i++) {		rc = next_entry(buf, fp, sizeof(u32)*2);		if (rc < 0)			goto bad;		nprim = le32_to_cpu(buf[0]);		nel = le32_to_cpu(buf[1]);		for (j = 0; j < nel; j++) {			rc = read_f[i](p, p->symtab[i].table, fp);			if (rc)				goto bad;		}		p->symtab[i].nprim = nprim;	}	rc = avtab_read(&p->te_avtab, fp, p);	if (rc)		goto bad;	if (p->policyvers >= POLICYDB_VERSION_BOOL) {		rc = cond_read_list(p, fp);		if (rc)			goto bad;	}	rc = next_entry(buf, fp, sizeof(u32));	if (rc < 0)		goto bad;	nel = le32_to_cpu(buf[0]);	ltr = NULL;	for (i = 0; i < nel; i++) {		tr = kzalloc(sizeof(*tr), GFP_KERNEL);		if (!tr) {			rc = -ENOMEM;			goto bad;		}		if (ltr) {			ltr->next = tr;		} else {			p->role_tr = tr;		}		rc = next_entry(buf, fp, sizeof(u32)*3);		if (rc < 0)			goto bad;		tr->role = le32_to_cpu(buf[0]);		tr->type = le32_to_cpu(buf[1]);		tr->new_role = le32_to_cpu(buf[2]);		if (!policydb_role_isvalid(p, tr->role) ||		    !policydb_type_isvalid(p, tr->type) ||		    !policydb_role_isvalid(p, tr->new_role)) {			rc = -EINVAL;			goto bad;		}		ltr = tr;	}	rc = next_entry(buf, fp, sizeof(u32));	if (rc < 0)		goto bad;	nel = le32_to_cpu(buf[0]);	lra = NULL;	for (i = 0; i < nel; i++) {		ra = kzalloc(sizeof(*ra), GFP_KERNEL);		if (!ra) {			rc = -ENOMEM;			goto bad;		}		if (lra) {			lra->next = ra;		} else {			p->role_allow = ra;		}		rc = next_entry(buf, fp, sizeof(u32)*2);		if (rc < 0)			goto bad;		ra->role = le32_to_cpu(buf[0]);		ra->new_role = le32_to_cpu(buf[1]);		if (!policydb_role_isvalid(p, ra->role) ||		    !policydb_role_isvalid(p, ra->new_role)) {			rc = -EINVAL;			goto bad;		}		lra = ra;	}	rc = policydb_index_classes(p);	if (rc)		goto bad;	rc = policydb_index_others(p);	if (rc)		goto bad;	for (i = 0; i < info->ocon_num; i++) {		rc = next_entry(buf, fp, sizeof(u32));		if (rc < 0)			goto bad;		nel = le32_to_cpu(buf[0]);		l = NULL;		for (j = 0; j < nel; j++) {			c = kzalloc(sizeof(*c), GFP_KERNEL);			if (!c) {				rc = -ENOMEM;				goto bad;			}			if (l) {				l->next = c;			} else {				p->ocontexts[i] = c;			}			l = c;			rc = -EINVAL;			switch (i) {			case OCON_ISID:				rc = next_entry(buf, fp, sizeof(u32));				if (rc < 0)					goto bad;				c->sid[0] = le32_to_cpu(buf[0]);				rc = context_read_and_validate(&c->context[0], p, fp);				if (rc)					goto bad;				break;			case OCON_FS:			case OCON_NETIF:				rc = next_entry(buf, fp, sizeof(u32));				if (rc < 0)					goto bad;				len = le32_to_cpu(buf[0]);				c->u.name = kmalloc(len + 1,GFP_KERNEL);				if (!c->u.name) {					rc = -ENOMEM;					goto bad;				}				rc = next_entry(c->u.name, fp, len);				if (rc < 0)					goto bad;				c->u.name[len] = 0;				rc = context_read_and_validate(&c->context[0], p, fp);				if (rc)					goto bad;				rc = context_read_and_validate(&c->context[1], p, fp);				if (rc)					goto bad;				break;			case OCON_PORT:				rc = next_entry(buf, fp, sizeof(u32)*3);				if (rc < 0)					goto bad;				c->u.port.protocol = le32_to_cpu(buf[0]);				c->u.port.low_port = le32_to_cpu(buf[1]);				c->u.port.high_port = le32_to_cpu(buf[2]);				rc = context_read_and_validate(&c->context[0], p, fp);				if (rc)					goto bad;				break;			case OCON_NODE:				rc = next_entry(buf, fp, sizeof(u32)* 2);				if (rc < 0)					goto bad;				c->u.node.addr = le32_to_cpu(buf[0]);				c->u.node.mask = le32_to_cpu(buf[1]);				rc = context_read_and_validate(&c->context[0], p, fp);				if (rc)					goto bad;				break;			case OCON_FSUSE:				rc = next_entry(buf, fp, sizeof(u32)*2);				if (rc < 0)					goto bad;				c->v.behavior = le32_to_cpu(buf[0]);				if (c->v.behavior > SECURITY_FS_USE_NONE)					goto bad;				len = le32_to_cpu(buf[1]);				c->u.name = kmalloc(len + 1,GFP_KERNEL);				if (!c->u.name) {					rc = -ENOMEM;					goto bad;				}				rc = next_entry(c->u.name, fp, len);				if (rc < 0)					goto bad;				c->u.name[len] = 0;				rc = context_read_and_validate(&c->context[0], p, fp);				if (rc)					goto bad;				break;			case OCON_NODE6: {				int k;				rc = next_entry(buf, fp, sizeof(u32) * 8);				if (rc < 0)					goto bad;				for (k = 0; k < 4; k++)					c->u.node6.addr[k] = le32_to_cpu(buf[k]);				for (k = 0; k < 4; k++)					c->u.node6.mask[k] = le32_to_cpu(buf[k+4]);				if (context_read_and_validate(&c->context[0], p, fp))					goto bad;				break;			}			}		}	}	rc = next_entry(buf, fp, sizeof(u32));	if (rc < 0)		goto bad;	nel = le32_to_cpu(buf[0]);	genfs_p = NULL;	rc = -EINVAL;	for (i = 0; i < nel; i++) {		rc = next_entry(buf, fp, sizeof(u32));		if (rc < 0)			goto bad;		len = le32_to_cpu(buf[0]);		newgenfs = kzalloc(sizeof(*newgenfs), GFP_KERNEL);		if (!newgenfs) {			rc = -ENOMEM;			goto bad;		}		newgenfs->fstype = kmalloc(len + 1,GFP_KERNEL);		if (!newgenfs->fstype) {			rc = -ENOMEM;			kfree(newgenfs);			goto bad;		}		rc = next_entry(newgenfs->fstype, fp, len);		if (rc < 0) {			kfree(newgenfs->fstype);			kfree(newgenfs);			goto bad;		}		newgenfs->fstype[len] = 0;		for (genfs_p = NULL, genfs = p->genfs; genfs;		     genfs_p = genfs, genfs = genfs->next) {			if (strcmp(newgenfs->fstype, genfs->fstype) == 0) {				printk(KERN_ERR "security:  dup genfs "				       "fstype %s\n", newgenfs->fstype);				kfree(newgenfs->fstype);				kfree(newgenfs);				goto bad;			}			if (strcmp(newgenfs->fstype, genfs->fstype) < 0)				break;		}		newgenfs->next = genfs;		if (genfs_p)			genfs_p->next = newgenfs;		else			p->genfs = newgenfs;		rc = next_entry(buf, fp, sizeof(u32));		if (rc < 0)			goto bad;		nel2 = le32_to_cpu(buf[0]);		for (j = 0; j < nel2; j++) {			rc = next_entry(buf, fp, sizeof(u32));			if (rc < 0)				goto bad;			len = le32_to_cpu(buf[0]);			newc = kzalloc(sizeof(*newc), GFP_KERNEL);			if (!newc) {				rc = -ENOMEM;				goto bad;			}			newc->u.name = kmalloc(len + 1,GFP_KERNEL);			if (!newc->u.name) {				rc = -ENOMEM;				goto bad_newc;			}			rc = next_entry(newc->u.name, fp, len);			if (rc < 0)				goto bad_newc;			newc->u.name[len] = 0;			rc = next_entry(buf, fp, sizeof(u32));			if (rc < 0)				goto bad_newc;			newc->v.sclass = le32_to_cpu(buf[0]);			if (context_read_and_validate(&newc->context[0], p, fp))				goto bad_newc;			for (l = NULL, c = newgenfs->head; c;			     l = c, c = c->next) {				if (!strcmp(newc->u.name, c->u.name) &&				    (!c->v.sclass || !newc->v.sclass ||				     newc->v.sclass == c->v.sclass)) {					printk(KERN_ERR "security:  dup genfs "					       "entry (%s,%s)\n",					       newgenfs->fstype, c->u.name);					goto bad_newc;				}				len = strlen(newc->u.name);				len2 = strlen(c->u.name);				if (len > len2)					break;			}			newc->next = c;			if (l)				l->next = newc;			else				newgenfs->head = newc;		}	}	if (p->policyvers >= POLICYDB_VERSION_MLS) {		int new_rangetr = p->policyvers >= POLICYDB_VERSION_RANGETRANS;		rc = next_entry(buf, fp, sizeof(u32));		if (rc < 0)			goto bad;		nel = le32_to_cpu(buf[0]);		lrt = NULL;		for (i = 0; i < nel; i++) {			rt = kzalloc(sizeof(*rt), GFP_KERNEL);			if (!rt) {				rc = -ENOMEM;				goto bad;			}			if (lrt)				lrt->next = rt;			else				p->range_tr = rt;			rc = next_entry(buf, fp, (sizeof(u32) * 2));			if (rc < 0)				goto bad;			rt->source_type = le32_to_cpu(buf[0]);			rt->target_type = le32_to_cpu(buf[1]);			if (new_rangetr) {				rc = next_entry(buf, fp, sizeof(u32));				if (rc < 0)					goto bad;				rt->target_class = le32_to_cpu(buf[0]);			} else				rt->target_class = SECCLASS_PROCESS;			if (!policydb_type_isvalid(p, rt->source_type) ||			    !policydb_type_isvalid(p, rt->target_type) ||			    !policydb_class_isvalid(p, rt->target_class)) {				rc = -EINVAL;				goto bad;			}			rc = mls_read_range_helper(&rt->target_range, fp);			if (rc)				goto bad;			if (!mls_range_isvalid(p, &rt->target_range)) {				printk(KERN_WARNING "security:  rangetrans:  invalid range\n");				goto bad;			}			lrt = rt;		}	}	p->type_attr_map = kmalloc(p->p_types.nprim*sizeof(struct ebitmap), GFP_KERNEL);	if (!p->type_attr_map)		goto bad;	for (i = 0; i < p->p_types.nprim; i++) {		ebitmap_init(&p->type_attr_map[i]);		if (p->policyvers >= POLICYDB_VERSION_AVTAB) {			if (ebitmap_read(&p->type_attr_map[i], fp))				goto bad;		}		/* add the type itself as the degenerate case */		if (ebitmap_set_bit(&p->type_attr_map[i], i, 1))				goto bad;	}	rc = 0;out:	return rc;bad_newc:	ocontext_destroy(newc,OCON_FSUSE);bad:	if (!rc)		rc = -EINVAL;	policydb_destroy(p);	goto out;}

⌨️ 快捷键说明

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