示例#1
0
/**
 * netlbl_cfg_unlbl_map_add - Add a new unlabeled mapping
 * @domain: the domain mapping to add
 * @family: address family
 * @addr: IP address
 * @mask: IP address mask
 * @audit_info: NetLabel audit information
 *
 * Description:
 * Adds a new unlabeled NetLabel/LSM domain mapping.  A @domain value of NULL
 * causes a new default domain mapping to be added.  Returns zero on success,
 * negative values on failure.
 *
 */
int netlbl_cfg_unlbl_map_add(const char *domain,
			     u16 family,
			     const void *addr,
			     const void *mask,
			     struct netlbl_audit *audit_info)
{
	int ret_val = -ENOMEM;
	struct netlbl_dom_map *entry;
	struct netlbl_domaddr_map *addrmap = NULL;
	struct netlbl_domaddr4_map *map4 = NULL;
	struct netlbl_domaddr6_map *map6 = NULL;

	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
	if (entry == NULL)
		return -ENOMEM;
	if (domain != NULL) {
		entry->domain = kstrdup(domain, GFP_ATOMIC);
		if (entry->domain == NULL)
			goto cfg_unlbl_map_add_failure;
	}

	if (addr == NULL && mask == NULL)
		entry->type = NETLBL_NLTYPE_UNLABELED;
	else if (addr != NULL && mask != NULL) {
		addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC);
		if (addrmap == NULL)
			goto cfg_unlbl_map_add_failure;
		INIT_LIST_HEAD(&addrmap->list4);
		INIT_LIST_HEAD(&addrmap->list6);

		switch (family) {
		case AF_INET: {
			const struct in_addr *addr4 = addr;
			const struct in_addr *mask4 = mask;
			map4 = kzalloc(sizeof(*map4), GFP_ATOMIC);
			if (map4 == NULL)
				goto cfg_unlbl_map_add_failure;
			map4->type = NETLBL_NLTYPE_UNLABELED;
			map4->list.addr = addr4->s_addr & mask4->s_addr;
			map4->list.mask = mask4->s_addr;
			map4->list.valid = 1;
			ret_val = netlbl_af4list_add(&map4->list,
						     &addrmap->list4);
			if (ret_val != 0)
				goto cfg_unlbl_map_add_failure;
			break;
			}
#if IS_ENABLED(CONFIG_IPV6)
		case AF_INET6: {
			const struct in6_addr *addr6 = addr;
			const struct in6_addr *mask6 = mask;
			map6 = kzalloc(sizeof(*map6), GFP_ATOMIC);
			if (map6 == NULL)
				goto cfg_unlbl_map_add_failure;
			map6->type = NETLBL_NLTYPE_UNLABELED;
			map6->list.addr = *addr6;
			map6->list.addr.s6_addr32[0] &= mask6->s6_addr32[0];
			map6->list.addr.s6_addr32[1] &= mask6->s6_addr32[1];
			map6->list.addr.s6_addr32[2] &= mask6->s6_addr32[2];
			map6->list.addr.s6_addr32[3] &= mask6->s6_addr32[3];
			map6->list.mask = *mask6;
			map6->list.valid = 1;
			ret_val = netlbl_af6list_add(&map6->list,
						     &addrmap->list6);
			if (ret_val != 0)
				goto cfg_unlbl_map_add_failure;
			break;
			}
#endif /* IPv6 */
		default:
			goto cfg_unlbl_map_add_failure;
			break;
		}

		entry->type_def.addrsel = addrmap;
		entry->type = NETLBL_NLTYPE_ADDRSELECT;
	} else {
		ret_val = -EINVAL;
		goto cfg_unlbl_map_add_failure;
	}

	ret_val = netlbl_domhsh_add(entry, audit_info);
	if (ret_val != 0)
		goto cfg_unlbl_map_add_failure;

	return 0;

cfg_unlbl_map_add_failure:
	kfree(entry->domain);
	kfree(entry);
	kfree(addrmap);
	kfree(map4);
	kfree(map6);
	return ret_val;
}
示例#2
0
/**
 * netlbl_cfg_calipso_map_add - Add a new CALIPSO DOI mapping
 * @doi: the CALIPSO DOI
 * @domain: the domain mapping to add
 * @addr: IP address
 * @mask: IP address mask
 * @audit_info: NetLabel audit information
 *
 * Description:
 * Add a new NetLabel/LSM domain mapping for the given CALIPSO DOI to the
 * NetLabel subsystem.  A @domain value of NULL adds a new default domain
 * mapping.  Returns zero on success, negative values on failure.
 *
 */
int netlbl_cfg_calipso_map_add(u32 doi,
			       const char *domain,
			       const struct in6_addr *addr,
			       const struct in6_addr *mask,
			       struct netlbl_audit *audit_info)
{
#if IS_ENABLED(CONFIG_IPV6)
	int ret_val = -ENOMEM;
	struct calipso_doi *doi_def;
	struct netlbl_dom_map *entry;
	struct netlbl_domaddr_map *addrmap = NULL;
	struct netlbl_domaddr6_map *addrinfo = NULL;

	doi_def = calipso_doi_getdef(doi);
	if (doi_def == NULL)
		return -ENOENT;

	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
	if (entry == NULL)
		goto out_entry;
	entry->family = AF_INET6;
	if (domain != NULL) {
		entry->domain = kstrdup(domain, GFP_ATOMIC);
		if (entry->domain == NULL)
			goto out_domain;
	}

	if (addr == NULL && mask == NULL) {
		entry->def.calipso = doi_def;
		entry->def.type = NETLBL_NLTYPE_CALIPSO;
	} else if (addr != NULL && mask != NULL) {
		addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC);
		if (addrmap == NULL)
			goto out_addrmap;
		INIT_LIST_HEAD(&addrmap->list4);
		INIT_LIST_HEAD(&addrmap->list6);

		addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC);
		if (addrinfo == NULL)
			goto out_addrinfo;
		addrinfo->def.calipso = doi_def;
		addrinfo->def.type = NETLBL_NLTYPE_CALIPSO;
		addrinfo->list.addr = *addr;
		addrinfo->list.addr.s6_addr32[0] &= mask->s6_addr32[0];
		addrinfo->list.addr.s6_addr32[1] &= mask->s6_addr32[1];
		addrinfo->list.addr.s6_addr32[2] &= mask->s6_addr32[2];
		addrinfo->list.addr.s6_addr32[3] &= mask->s6_addr32[3];
		addrinfo->list.mask = *mask;
		addrinfo->list.valid = 1;
		ret_val = netlbl_af6list_add(&addrinfo->list, &addrmap->list6);
		if (ret_val != 0)
			goto cfg_calipso_map_add_failure;

		entry->def.addrsel = addrmap;
		entry->def.type = NETLBL_NLTYPE_ADDRSELECT;
	} else {
		ret_val = -EINVAL;
		goto out_addrmap;
	}

	ret_val = netlbl_domhsh_add(entry, audit_info);
	if (ret_val != 0)
		goto cfg_calipso_map_add_failure;

	return 0;

cfg_calipso_map_add_failure:
	kfree(addrinfo);
out_addrinfo:
	kfree(addrmap);
out_addrmap:
	kfree(entry->domain);
out_domain:
	kfree(entry);
out_entry:
	calipso_doi_putdef(doi_def);
	return ret_val;
#else /* IPv6 */
	return -ENOSYS;
#endif /* IPv6 */
}