} if (x->type->init_state(x, NULL)) { err = -EINVAL; goto out; } 
static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr, 						void **ext_hdrs){	struct xfrm_state *x; 	struct sadb_lifetime *lifetime;	struct sadb_sa *sa;	struct sadb_key *key;	uint16_t proto;	int err;		sa = (struct sadb_sa *) ext_hdrs[SADB_EXT_SA-1];	if (!sa ||	    !present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],				     ext_hdrs[SADB_EXT_ADDRESS_DST-1]))		return ERR_PTR(-EINVAL);	if (hdr->sadb_msg_satype == SADB_SATYPE_ESP &&	    !ext_hdrs[SADB_EXT_KEY_ENCRYPT-1])		return ERR_PTR(-EINVAL);	if (hdr->sadb_msg_satype == SADB_SATYPE_AH &&	    !ext_hdrs[SADB_EXT_KEY_AUTH-1])		return ERR_PTR(-EINVAL);	if (!!ext_hdrs[SADB_EXT_LIFETIME_HARD-1] !=	    !!ext_hdrs[SADB_EXT_LIFETIME_SOFT-1])		return ERR_PTR(-EINVAL);	proto = pfkey_satype2proto(hdr->sadb_msg_satype);	if (proto == 0)		return ERR_PTR(-EINVAL);	/* default error is no buffer space */	err = -ENOBUFS;	/* RFC2367:   Only SADB_SASTATE_MATURE SAs may be submitted in an SADB_ADD message.   SADB_SASTATE_LARVAL SAs are created by SADB_GETSPI and it is not   sensible to add a new SA in the DYING or SADB_SASTATE_DEAD state.   Therefore, the sadb_sa_state field of all submitted SAs MUST be   SADB_SASTATE_MATURE and the kernel MUST return an error if this is   not true.           However, KAME setkey always uses SADB_SASTATE_LARVAL.	   Hence, we have to _ignore_ sadb_sa_state, which is also reasonable.	 */	if (sa->sadb_sa_auth > SADB_AALG_MAX ||	    (hdr->sadb_msg_satype == SADB_X_SATYPE_IPCOMP &&	     sa->sadb_sa_encrypt > SADB_X_CALG_MAX) ||	    sa->sadb_sa_encrypt > SADB_EALG_MAX)		return ERR_PTR(-EINVAL);	key = (struct sadb_key*) ext_hdrs[SADB_EXT_KEY_AUTH-1];	if (key != NULL &&	    sa->sadb_sa_auth != SADB_X_AALG_NULL &&	    ((key->sadb_key_bits+7) / 8 == 0 ||	     (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t)))		return ERR_PTR(-EINVAL);	key = ext_hdrs[SADB_EXT_KEY_ENCRYPT-1];	if (key != NULL &&	    sa->sadb_sa_encrypt != SADB_EALG_NULL &&	    ((key->sadb_key_bits+7) / 8 == 0 ||	     (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t)))		return ERR_PTR(-EINVAL);	x = xfrm_state_alloc();	if (x == NULL)		return ERR_PTR(-ENOBUFS);	x->id.proto = proto;	x->id.spi = sa->sadb_sa_spi;	x->props.replay_window = sa->sadb_sa_replay;	if (sa->sadb_sa_flags & SADB_SAFLAGS_NOECN)		x->props.flags |= XFRM_STATE_NOECN;	if (sa->sadb_sa_flags & SADB_SAFLAGS_DECAP_DSCP)		x->props.flags |= XFRM_STATE_DECAP_DSCP;	lifetime = (struct sadb_lifetime*) ext_hdrs[SADB_EXT_LIFETIME_HARD-1];	if (lifetime != NULL) {		x->lft.hard_packet_limit = _KEY2X(lifetime->sadb_lifetime_allocations);		x->lft.hard_byte_limit = _KEY2X(lifetime->sadb_lifetime_bytes);		x->lft.hard_add_expires_seconds = lifetime->sadb_lifetime_addtime;		x->lft.hard_use_expires_seconds = lifetime->sadb_lifetime_usetime;	}	lifetime = (struct sadb_lifetime*) ext_hdrs[SADB_EXT_LIFETIME_SOFT-1];	if (lifetime != NULL) {		x->lft.soft_packet_limit = _KEY2X(lifetime->sadb_lifetime_allocations);		x->lft.soft_byte_limit = _KEY2X(lifetime->sadb_lifetime_bytes);		x->lft.soft_add_expires_seconds = lifetime->sadb_lifetime_addtime;		x->lft.soft_use_expires_seconds = lifetime->sadb_lifetime_usetime;	}	key = (struct sadb_key*) ext_hdrs[SADB_EXT_KEY_AUTH-1];	if (sa->sadb_sa_auth) {		int keysize = 0;		struct xfrm_algo_desc *a = xfrm_aalg_get_byid(sa->sadb_sa_auth);		if (!a) {			err = -ENOSYS;			goto out;		}		if (key)			keysize = (key->sadb_key_bits + 7) / 8;		x->aalg = kmalloc(sizeof(*x->aalg) + keysize, GFP_KERNEL);		if (!x->aalg)			goto out;		strcpy(x->aalg->alg_name, a->name);		x->aalg->alg_key_len = 0;		if (key) {			x->aalg->alg_key_len = key->sadb_key_bits;			memcpy(x->aalg->alg_key, key+1, keysize);		}		x->props.aalgo = sa->sadb_sa_auth;		/* x->algo.flags = sa->sadb_sa_flags; */	}	if (sa->sadb_sa_encrypt) {		if (hdr->sadb_msg_satype == SADB_X_SATYPE_IPCOMP) {			struct xfrm_algo_desc *a = xfrm_calg_get_byid(sa->sadb_sa_encrypt);			if (!a) {				err = -ENOSYS;				goto out;			}			x->calg = kmalloc(sizeof(*x->calg), GFP_KERNEL);			if (!x->calg)				goto out;			strcpy(x->calg->alg_name, a->name);			x->props.calgo = sa->sadb_sa_encrypt;		} else {			int keysize = 0;			struct xfrm_algo_desc *a = xfrm_ealg_get_byid(sa->sadb_sa_encrypt);			if (!a) {				err = -ENOSYS;				goto out;			}			key = (struct sadb_key*) ext_hdrs[SADB_EXT_KEY_ENCRYPT-1];			if (key)				keysize = (key->sadb_key_bits + 7) / 8;			x->ealg = kmalloc(sizeof(*x->ealg) + keysize, GFP_KERNEL);			if (!x->ealg)				goto out;			strcpy(x->ealg->alg_name, a->name);			x->ealg->alg_key_len = 0;			if (key) {				x->ealg->alg_key_len = key->sadb_key_bits;				memcpy(x->ealg->alg_key, key+1, keysize);			}			x->props.ealgo = sa->sadb_sa_encrypt;		}	}	/* x->algo.flags = sa->sadb_sa_flags; */	x->props.family = pfkey_sadb_addr2xfrm_addr((struct sadb_address *) ext_hdrs[SADB_EXT_ADDRESS_SRC-1], 						    &x->props.saddr);	if (!x->props.family) {		err = -EAFNOSUPPORT;		goto out;	}	pfkey_sadb_addr2xfrm_addr((struct sadb_address *) ext_hdrs[SADB_EXT_ADDRESS_DST-1], 				  &x->id.daddr);	if (ext_hdrs[SADB_X_EXT_SA2-1]) {		struct sadb_x_sa2 *sa2 = (void*)ext_hdrs[SADB_X_EXT_SA2-1];		x->props.mode = sa2->sadb_x_sa2_mode;		if (x->props.mode)			x->props.mode--;		x->props.reqid = sa2->sadb_x_sa2_reqid;	}	if (ext_hdrs[SADB_EXT_ADDRESS_PROXY-1]) {		struct sadb_address *addr = ext_hdrs[SADB_EXT_ADDRESS_PROXY-1];		/* Nobody uses this, but we try. */		x->sel.family = pfkey_sadb_addr2xfrm_addr(addr, &x->sel.saddr);		x->sel.prefixlen_s = addr->sadb_address_prefixlen;	}	if (ext_hdrs[SADB_X_EXT_NAT_T_TYPE-1]) {		struct sadb_x_nat_t_type* n_type;		struct xfrm_encap_tmpl *natt;		x->encap = kmalloc(sizeof(*x->encap), GFP_KERNEL);		if (!x->encap)			goto out;		natt = x->encap;		n_type = ext_hdrs[SADB_X_EXT_NAT_T_TYPE-1];		natt->encap_type = n_type->sadb_x_nat_t_type_type;		if (ext_hdrs[SADB_X_EXT_NAT_T_SPORT-1]) {			struct sadb_x_nat_t_port* n_port =				ext_hdrs[SADB_X_EXT_NAT_T_SPORT-1];			natt->encap_sport = n_port->sadb_x_nat_t_port_port;		}		if (ext_hdrs[SADB_X_EXT_NAT_T_DPORT-1]) {			struct sadb_x_nat_t_port* n_port =				ext_hdrs[SADB_X_EXT_NAT_T_DPORT-1];			natt->encap_dport = n_port->sadb_x_nat_t_port_port;		}	}	x->type = xfrm_get_type(proto, x->props.family);	if (x->type == NULL) {		err = -ENOPROTOOPT;		goto out;	}	if (x->type->init_state(x, NULL)) {		err = -EINVAL;		goto out;	}	x->km.seq = hdr->sadb_msg_seq;	x->km.state = XFRM_STATE_VALID;	return x;out:	x->km.state = XFRM_STATE_DEAD;	xfrm_state_put(x);	return ERR_PTR(err);}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/72cb6962a91f2af9eef69a06198e1949c10259ae/af_key.c/buggy/net/key/af_key.c