/* link the resulting key to the destination keyring */ if (dest) { ret = key_link(dest, key); if (ret < 0) goto error6; }  
asmlinkage long sys_request_key(const char __user *_type,				const char __user *_description,				const char __user *_callout_info,				key_serial_t destringid){	struct key_type *ktype;	struct key *key, *dest;	char type[32], *description, *callout_info;	long dlen, ret;	/* pull the type into kernel space */	ret = strncpy_from_user(type, _type, sizeof(type) - 1);	if (ret < 0)		goto error;	type[31] = '\0';	/* pull the description into kernel space */	ret = -EFAULT;	dlen = strnlen_user(_description, PAGE_SIZE - 1);	if (dlen <= 0)		goto error;	ret = -EINVAL;	if (dlen > PAGE_SIZE - 1)		goto error;	ret = -ENOMEM;	description = kmalloc(dlen + 1, GFP_KERNEL);	if (!description)		goto error;	ret = -EFAULT;	if (copy_from_user(description, _description, dlen + 1) != 0)		goto error2;	/* pull the callout info into kernel space */	callout_info = NULL;	if (_callout_info) {		ret = -EFAULT;		dlen = strnlen_user(_callout_info, PAGE_SIZE - 1);		if (dlen <= 0)			goto error2;		ret = -EINVAL;		if (dlen > PAGE_SIZE - 1)			goto error2;		ret = -ENOMEM;		callout_info = kmalloc(dlen + 1, GFP_KERNEL);		if (!callout_info)			goto error2;		ret = -EFAULT;		if (copy_from_user(callout_info, _callout_info, dlen + 1) != 0)			goto error3;	}	/* get the destination keyring if specified */	dest = NULL;	if (destringid) {		dest = lookup_user_key(destringid, 1, 0, KEY_WRITE);		if (IS_ERR(dest)) {			ret = PTR_ERR(dest);			goto error3;		}	}	/* find the key type */	ktype = key_type_lookup(type);	if (IS_ERR(ktype)) {		ret = PTR_ERR(ktype);		goto error4;	}	/* do the search */	key = request_key(ktype, description, callout_info);	if (IS_ERR(key)) {		ret = PTR_ERR(key);		goto error5;	}	/* link the resulting key to the destination keyring */	if (dest) {		ret = key_link(dest, key);		if (ret < 0)			goto error6;	}	ret = key->serial; error6:	key_put(key); error5:	key_type_put(ktype); error4:	key_put(dest); error3:	kfree(callout_info); error2:	kfree(description); error:	return ret;} /* end sys_request_key() */
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/3e30148c3d524a9c1c63ca28261bc24c457eb07a/keyctl.c/clean/security/keys/keyctl.c