Exemple #1
0
static int
ipsec_sa_wipe(struct ipsec_sa *ips)
{
	if(ips == NULL) {
		return -ENODATA;
	}

	/* paranoid clean up */
	if(ips->ips_addr_s != NULL) {
		memset((caddr_t)(ips->ips_addr_s), 0, ips->ips_addr_s_size);
		kfree(ips->ips_addr_s);
	}
	ips->ips_addr_s = NULL;

	if(ips->ips_addr_d != NULL) {
		memset((caddr_t)(ips->ips_addr_d), 0, ips->ips_addr_d_size);
		kfree(ips->ips_addr_d);
	}
	ips->ips_addr_d = NULL;

	if(ips->ips_addr_p != NULL) {
		memset((caddr_t)(ips->ips_addr_p), 0, ips->ips_addr_p_size);
		kfree(ips->ips_addr_p);
	}
	ips->ips_addr_p = NULL;

#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
	if(ips->ips_natt_oa) {
		memset((caddr_t)(ips->ips_natt_oa), 0, ips->ips_natt_oa_size);
		kfree(ips->ips_natt_oa);
	}
	ips->ips_natt_oa = NULL;
#endif

	if(ips->ips_key_a != NULL) {
		memset((caddr_t)(ips->ips_key_a), 0, ips->ips_key_a_size);
		kfree(ips->ips_key_a);
	}
	ips->ips_key_a = NULL;

	if(ips->ips_key_e != NULL) {
		if (ips->ips_alg_enc &&
		    ips->ips_alg_enc->ixt_e_destroy_key)
		{
			ips->ips_alg_enc->ixt_e_destroy_key(ips->ips_alg_enc, 
							    ips->ips_key_e);
		} else
		{
			memset((caddr_t)(ips->ips_key_e), 0, ips->ips_key_e_size);
			kfree(ips->ips_key_e);
		}
	}
	ips->ips_key_e = NULL;

	if(ips->ips_iv != NULL) {
		memset((caddr_t)(ips->ips_iv), 0, ips->ips_iv_size);
		kfree(ips->ips_iv);
	}
	ips->ips_iv = NULL;

	if(ips->ips_ident_s.data != NULL) {
		memset((caddr_t)(ips->ips_ident_s.data),
                       0,
		       ips->ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
		kfree(ips->ips_ident_s.data);
        }
	ips->ips_ident_s.data = NULL;
	
	if(ips->ips_ident_d.data != NULL) {
		memset((caddr_t)(ips->ips_ident_d.data),
                       0,
		       ips->ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
		kfree(ips->ips_ident_d.data);
        }
	ips->ips_ident_d.data = NULL;

	if (ips->ips_alg_enc||ips->ips_alg_auth) {
		ipsec_alg_sa_wipe(ips);
	}
	
	BUG_ON(atomic_read(&ips->ips_refcount) != 0);

	memset((caddr_t)ips, 0, sizeof(*ips));
	kfree(ips);
	ips = NULL;

	return 0;
}
Exemple #2
0
int ipsec_sa_wipe(struct ipsec_sa *ips)
{
	int hashval;
	struct ipsec_sa **tpp;

	if (ips == NULL)
		return -ENODATA;

#if IPSEC_SA_REF_CODE
	/* remove me from the SArefTable */
	if (debug_xform) {
		char sa[SATOT_BUF];
		size_t sa_len;
		struct IPsecSArefSubTable *subtable = NULL;

		if (IPsecSAref2table(IPsecSA2SAref(ips)) <
		    IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES &&
		    ipsec_sadb.refTable != NULL)
			subtable = ipsec_sadb.refTable[
				IPsecSAref2table(IPsecSA2SAref(ips))];

		sa_len = KLIPS_SATOT(debug_xform, &ips->ips_said, 0, sa,
				     sizeof(sa));
		KLIPS_PRINT(debug_xform,
			    "klips_debug:ipsec_sa_wipe: "
			    "removing SA=%s(0p%p), SAref=%d, table=%d(0p%p), entry=%d from the refTable.\n",
			    sa_len ? sa : " (error)",
			    ips,
			    ips->ips_ref,
			    IPsecSAref2table(IPsecSA2SAref(ips)),
			    subtable,
			    subtable ? IPsecSAref2entry(IPsecSA2SAref(ips)) : 0);
	}

	if (ips->ips_ref != IPSEC_SAREF_NULL) {
		struct IPsecSArefSubTable *subtable = NULL;
		int ref_table = IPsecSAref2table(IPsecSA2SAref(ips));
		int ref_entry = IPsecSAref2entry(IPsecSA2SAref(ips));

		if (ref_table < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES) {
			subtable = ipsec_sadb.refTable[ref_table];
			if (subtable != NULL && subtable->entry[ref_entry] ==
			    ips) {

				subtable->entry[ref_entry] = NULL;
			}
		}
		ips->ips_ref = IPSEC_SAREF_NULL;
	}
#endif  /* IPSEC_SA_REF_CODE */

	/* paranoid clean up */
	if (ips->ips_addr_s != NULL) {
		memset((caddr_t)(ips->ips_addr_s), 0, ips->ips_addr_s_size);
		kfree(ips->ips_addr_s);
	}
	ips->ips_addr_s = NULL;

	if (ips->ips_addr_d != NULL) {
		memset((caddr_t)(ips->ips_addr_d), 0, ips->ips_addr_d_size);
		kfree(ips->ips_addr_d);
	}
	ips->ips_addr_d = NULL;

	if (ips->ips_addr_p != NULL) {
		memset((caddr_t)(ips->ips_addr_p), 0, ips->ips_addr_p_size);
		kfree(ips->ips_addr_p);
	}
	ips->ips_addr_p = NULL;

	if (ips->ips_natt_oa) {
		memset((caddr_t)(ips->ips_natt_oa), 0, ips->ips_natt_oa_size);
		kfree(ips->ips_natt_oa);
	}
	ips->ips_natt_oa = NULL;

	if (ips->ips_key_a != NULL) {
#ifdef CONFIG_KLIPS_ALG
		if (ips->ips_alg_auth &&
		    ips->ips_alg_auth->ixt_a_destroy_key)
		{
			ips->ips_alg_auth->ixt_a_destroy_key(ips->ips_alg_auth, 
							     ips->ips_key_a);
		} else
#endif
		{
			memset((caddr_t)(ips->ips_key_a), 0, ips->ips_key_a_size);
			kfree(ips->ips_key_a);
		}
	}
	ips->ips_key_a = NULL;

	if (ips->ips_key_e != NULL) {
#ifdef CONFIG_KLIPS_ALG
		if (ips->ips_alg_enc &&
		    ips->ips_alg_enc->ixt_e_destroy_key) {
			ips->ips_alg_enc->ixt_e_destroy_key(ips->ips_alg_enc,
							    ips->ips_key_e);
		} else
#endif
		{
			memset((caddr_t)(ips->ips_key_e), 0,
			       ips->ips_key_e_size);
			kfree(ips->ips_key_e);
		}
	}
	ips->ips_key_e = NULL;

	if (ips->ips_iv != NULL) {
		memset((caddr_t)(ips->ips_iv), 0, ips->ips_iv_size);
		kfree(ips->ips_iv);
	}
	ips->ips_iv = NULL;

#ifdef CONFIG_KLIPS_OCF
	if (ips->ocf_in_use)
		ipsec_ocf_sa_free(ips);
#endif

	if (ips->ips_ident_s.data != NULL) {
		memset((caddr_t)(ips->ips_ident_s.data),
		       0,
		       ips->ips_ident_s.len * IPSEC_PFKEYv2_ALIGN -
		       sizeof(struct sadb_ident));
		kfree(ips->ips_ident_s.data);
	}
	ips->ips_ident_s.data = NULL;

	if (ips->ips_ident_d.data != NULL) {
		memset((caddr_t)(ips->ips_ident_d.data),
		       0,
		       ips->ips_ident_d.len * IPSEC_PFKEYv2_ALIGN -
		       sizeof(struct sadb_ident));
		kfree(ips->ips_ident_d.data);
	}
	ips->ips_ident_d.data = NULL;

#ifdef CONFIG_KLIPS_ALG
	if (ips->ips_alg_enc || ips->ips_alg_auth)
		ipsec_alg_sa_wipe(ips);
	ips->ips_alg_enc = NULL;
	ips->ips_alg_auth = NULL;

#endif
	if (ips->ips_prev)
		ips->ips_prev->ips_next = ips->ips_next;
	if (ips->ips_next) {
		ips->ips_next->ips_prev = ips->ips_prev;
		ipsec_sa_put(ips->ips_next, IPSEC_REFALLOC);
	}
	ips->ips_next = NULL;
	ips->ips_prev = NULL;

	hashval = IPS_HASH(&ips->ips_said);
	tpp = &ipsec_sadb_hash[hashval];
	while (*tpp) {
		if (*tpp == ips)
			*tpp = ips->ips_hnext;
		else
			tpp = &((*tpp)->ips_hnext);
	}
	if (ips->ips_hnext)
		ipsec_sa_put(ips->ips_hnext, IPSEC_REFALLOC);
	ips->ips_hnext = NULL;

	BUG_ON(atomic_read(&ips->ips_refcount) != 0);

#ifdef IPSEC_SA_RECOUNT_DEBUG
	if (ips == ipsec_sa_raw) {
		ipsec_sa_raw = ips->ips_raw;
	} else {
		struct ipsec_sa *raw = ipsec_sa_raw;
		while (raw) {
			if (raw->ips_raw == ips) {
				raw->ips_raw = ips->ips_raw;
				break;
			}
			raw = raw->ips_raw;
		}
	}
#endif
	if (ips->ips_out != NULL) {
		ipsec_dev_put(ips->ips_out);
		ips->ips_out = NULL;
	}

	memset((caddr_t)ips, 0, sizeof(*ips));
	kfree(ips);
	ips = NULL;

	return 0;
}
Exemple #3
0
int
ipsec_sa_wipe(struct ipsec_sa *ips)
{
	if(!ips) {
		return -ENODATA;
	}

	if(ips->ips_addr_s) {
		memset((caddr_t)(ips->ips_addr_s), 0, ips->ips_addr_s_size);
		kfree(ips->ips_addr_s);
	}
	ips->ips_addr_s = NULL;

	if(ips->ips_addr_d) {
		memset((caddr_t)(ips->ips_addr_d), 0, ips->ips_addr_d_size);
		kfree(ips->ips_addr_d);
	}
	ips->ips_addr_d = NULL;

	if(ips->ips_addr_p) {
		memset((caddr_t)(ips->ips_addr_p), 0, ips->ips_addr_p_size);
		kfree(ips->ips_addr_p);
	}
	ips->ips_addr_p = NULL;

#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
	if(ips->ips_natt_oa) {
		memset((caddr_t)(ips->ips_natt_oa), 0, ips->ips_natt_oa_size);
		kfree(ips->ips_natt_oa);
	}
	ips->ips_natt_oa = NULL;
#endif

	if(ips->ips_key_a) {
		memset((caddr_t)(ips->ips_key_a), 0, ips->ips_key_a_size);
		kfree(ips->ips_key_a);
	}
	ips->ips_key_a = NULL;

	if(ips->ips_key_e) {
		memset((caddr_t)(ips->ips_key_e), 0, ips->ips_key_e_size);
		kfree(ips->ips_key_e);
	}
	ips->ips_key_e = NULL;

	if(ips->ips_iv) {
		memset((caddr_t)(ips->ips_iv), 0, ips->ips_iv_size);
		kfree(ips->ips_iv);
	}
	ips->ips_iv = NULL;

	if(ips->ips_ident_s.data) {
		memset((caddr_t)(ips->ips_ident_s.data),
                       0,
		       ips->ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
		kfree(ips->ips_ident_s.data);
        }
	ips->ips_ident_s.data = NULL;
	
	if(ips->ips_ident_d.data) {
		memset((caddr_t)(ips->ips_ident_d.data),
                       0,
		       ips->ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
		kfree(ips->ips_ident_d.data);
        }
	ips->ips_ident_d.data = NULL;

	if (IPSEC_ALG_SA_ESP_ENC(ips)||IPSEC_ALG_SA_ESP_AUTH(ips)) {
		ipsec_alg_sa_wipe(ips);
	}
	
	memset((caddr_t)ips, 0, sizeof(*ips));
	kfree(ips);
	ips = NULL;

	return 0;
}