int sp, psp, kix; 
int sp, kix; 
struct key *keyring_search_aux(struct key *keyring,			       struct key_type *type,			       const void *description,			       key_match_func_t match){	struct {		struct key *keyring;		int kix;	} stack[KEYRING_SEARCH_MAX_DEPTH];	struct keyring_list *keylist;	struct timespec now;	struct key *key;	long err;	int sp, psp, kix;	key_check(keyring);	/* top keyring must have search permission to begin the search */	key = ERR_PTR(-EACCES);	if (!key_permission(keyring, KEY_SEARCH))		goto error;	key = ERR_PTR(-ENOTDIR);	if (keyring->type != &key_type_keyring)		goto error;	now = current_kernel_time();	err = -EAGAIN;	sp = 0;	/* start processing a new keyring */ descend:	read_lock(&keyring->lock);	if (keyring->flags & KEY_FLAG_REVOKED)		goto not_this_keyring;	keylist = keyring->payload.subscriptions;	if (!keylist)		goto not_this_keyring;	/* iterate through the keys in this keyring first */	for (kix = 0; kix < keylist->nkeys; kix++) {		key = keylist->keys[kix];		/* ignore keys not of this type */		if (key->type != type)			continue;		/* skip revoked keys and expired keys */		if (key->flags & KEY_FLAG_REVOKED)			continue;		if (key->expiry && now.tv_sec >= key->expiry)			continue;		/* keys that don't match */		if (!match(key, description))			continue;		/* key must have search permissions */		if (!key_permission(key, KEY_SEARCH))			continue;		/* we set a different error code if we find a negative key */		if (key->flags & KEY_FLAG_NEGATIVE) {			err = -ENOKEY;			continue;		}		goto found;	}	/* search through the keyrings nested in this one */	kix = 0; ascend:	while (kix < keylist->nkeys) {		key = keylist->keys[kix];		if (key->type != &key_type_keyring)			goto next;		/* recursively search nested keyrings		 * - only search keyrings for which we have search permission		 */		if (sp >= KEYRING_SEARCH_MAX_DEPTH)			goto next;		if (!key_permission(key, KEY_SEARCH))			goto next;		/* evade loops in the keyring tree */		for (psp = 0; psp < sp; psp++)			if (stack[psp].keyring == keyring)				goto next;		/* stack the current position */		stack[sp].keyring = keyring;		stack[sp].kix = kix;		sp++;		/* begin again with the new keyring */		keyring = key;		goto descend;	next:		kix++;	}	/* the keyring we're looking at was disqualified or didn't contain a	 * matching key */ not_this_keyring:	read_unlock(&keyring->lock);	if (sp > 0) {		/* resume the processing of a keyring higher up in the tree */		sp--;		keyring = stack[sp].keyring;		keylist = keyring->payload.subscriptions;		kix = stack[sp].kix + 1;		goto ascend;	}	key = ERR_PTR(err);	goto error;	/* we found a viable match */ found:	atomic_inc(&key->usage);	read_unlock(&keyring->lock);	/* unwind the keyring stack */	while (sp > 0) {		sp--;		read_unlock(&stack[sp].keyring->lock);	}	key_check(key); error:	return key;} /* end keyring_search_aux() */
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/76d8aeabfeb1c42641a81c44280177b9a08670d8/keyring.c/clean/security/keys/keyring.c