• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/security/keys/
1/* Management of a process's keyrings
2 *
3 * Copyright (C) 2004-2005, 2008 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/sched.h>
15#include <linux/keyctl.h>
16#include <linux/fs.h>
17#include <linux/err.h>
18#include <linux/mutex.h>
19#include <linux/security.h>
20#include <linux/user_namespace.h>
21#include <asm/uaccess.h>
22#include "internal.h"
23
24/* session keyring create vs join semaphore */
25static DEFINE_MUTEX(key_session_mutex);
26
27/* user keyring creation semaphore */
28static DEFINE_MUTEX(key_user_keyring_mutex);
29
30/* the root user's tracking struct */
31struct key_user root_key_user = {
32	.usage		= ATOMIC_INIT(3),
33	.cons_lock	= __MUTEX_INITIALIZER(root_key_user.cons_lock),
34	.lock		= __SPIN_LOCK_UNLOCKED(root_key_user.lock),
35	.nkeys		= ATOMIC_INIT(2),
36	.nikeys		= ATOMIC_INIT(2),
37	.uid		= 0,
38	.user_ns	= &init_user_ns,
39};
40
41/*****************************************************************************/
42/*
43 * install user and user session keyrings for a particular UID
44 */
45int install_user_keyrings(void)
46{
47	struct user_struct *user;
48	const struct cred *cred;
49	struct key *uid_keyring, *session_keyring;
50	char buf[20];
51	int ret;
52
53	cred = current_cred();
54	user = cred->user;
55
56	kenter("%p{%u}", user, user->uid);
57
58	if (user->uid_keyring) {
59		kleave(" = 0 [exist]");
60		return 0;
61	}
62
63	mutex_lock(&key_user_keyring_mutex);
64	ret = 0;
65
66	if (!user->uid_keyring) {
67		/* get the UID-specific keyring
68		 * - there may be one in existence already as it may have been
69		 *   pinned by a session, but the user_struct pointing to it
70		 *   may have been destroyed by setuid */
71		sprintf(buf, "_uid.%u", user->uid);
72
73		uid_keyring = find_keyring_by_name(buf, true);
74		if (IS_ERR(uid_keyring)) {
75			uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1,
76						    cred, KEY_ALLOC_IN_QUOTA,
77						    NULL);
78			if (IS_ERR(uid_keyring)) {
79				ret = PTR_ERR(uid_keyring);
80				goto error;
81			}
82		}
83
84		/* get a default session keyring (which might also exist
85		 * already) */
86		sprintf(buf, "_uid_ses.%u", user->uid);
87
88		session_keyring = find_keyring_by_name(buf, true);
89		if (IS_ERR(session_keyring)) {
90			session_keyring =
91				keyring_alloc(buf, user->uid, (gid_t) -1,
92					      cred, KEY_ALLOC_IN_QUOTA, NULL);
93			if (IS_ERR(session_keyring)) {
94				ret = PTR_ERR(session_keyring);
95				goto error_release;
96			}
97
98			/* we install a link from the user session keyring to
99			 * the user keyring */
100			ret = key_link(session_keyring, uid_keyring);
101			if (ret < 0)
102				goto error_release_both;
103		}
104
105		/* install the keyrings */
106		user->uid_keyring = uid_keyring;
107		user->session_keyring = session_keyring;
108	}
109
110	mutex_unlock(&key_user_keyring_mutex);
111	kleave(" = 0");
112	return 0;
113
114error_release_both:
115	key_put(session_keyring);
116error_release:
117	key_put(uid_keyring);
118error:
119	mutex_unlock(&key_user_keyring_mutex);
120	kleave(" = %d", ret);
121	return ret;
122}
123
124/*
125 * install a fresh thread keyring directly to new credentials
126 */
127int install_thread_keyring_to_cred(struct cred *new)
128{
129	struct key *keyring;
130
131	keyring = keyring_alloc("_tid", new->uid, new->gid, new,
132				KEY_ALLOC_QUOTA_OVERRUN, NULL);
133	if (IS_ERR(keyring))
134		return PTR_ERR(keyring);
135
136	new->thread_keyring = keyring;
137	return 0;
138}
139
140/*
141 * install a fresh thread keyring, discarding the old one
142 */
143static int install_thread_keyring(void)
144{
145	struct cred *new;
146	int ret;
147
148	new = prepare_creds();
149	if (!new)
150		return -ENOMEM;
151
152	BUG_ON(new->thread_keyring);
153
154	ret = install_thread_keyring_to_cred(new);
155	if (ret < 0) {
156		abort_creds(new);
157		return ret;
158	}
159
160	return commit_creds(new);
161}
162
163/*
164 * install a process keyring directly to a credentials struct
165 * - returns -EEXIST if there was already a process keyring, 0 if one installed,
166 *   and other -ve on any other error
167 */
168int install_process_keyring_to_cred(struct cred *new)
169{
170	struct key *keyring;
171	int ret;
172
173	if (new->tgcred->process_keyring)
174		return -EEXIST;
175
176	keyring = keyring_alloc("_pid", new->uid, new->gid,
177				new, KEY_ALLOC_QUOTA_OVERRUN, NULL);
178	if (IS_ERR(keyring))
179		return PTR_ERR(keyring);
180
181	spin_lock_irq(&new->tgcred->lock);
182	if (!new->tgcred->process_keyring) {
183		new->tgcred->process_keyring = keyring;
184		keyring = NULL;
185		ret = 0;
186	} else {
187		ret = -EEXIST;
188	}
189	spin_unlock_irq(&new->tgcred->lock);
190	key_put(keyring);
191	return ret;
192}
193
194/*
195 * make sure a process keyring is installed
196 * - we
197 */
198static int install_process_keyring(void)
199{
200	struct cred *new;
201	int ret;
202
203	new = prepare_creds();
204	if (!new)
205		return -ENOMEM;
206
207	ret = install_process_keyring_to_cred(new);
208	if (ret < 0) {
209		abort_creds(new);
210		return ret != -EEXIST ?: 0;
211	}
212
213	return commit_creds(new);
214}
215
216/*
217 * install a session keyring directly to a credentials struct
218 */
219int install_session_keyring_to_cred(struct cred *cred, struct key *keyring)
220{
221	unsigned long flags;
222	struct key *old;
223
224	might_sleep();
225
226	/* create an empty session keyring */
227	if (!keyring) {
228		flags = KEY_ALLOC_QUOTA_OVERRUN;
229		if (cred->tgcred->session_keyring)
230			flags = KEY_ALLOC_IN_QUOTA;
231
232		keyring = keyring_alloc("_ses", cred->uid, cred->gid,
233					cred, flags, NULL);
234		if (IS_ERR(keyring))
235			return PTR_ERR(keyring);
236	} else {
237		atomic_inc(&keyring->usage);
238	}
239
240	/* install the keyring */
241	spin_lock_irq(&cred->tgcred->lock);
242	old = cred->tgcred->session_keyring;
243	rcu_assign_pointer(cred->tgcred->session_keyring, keyring);
244	spin_unlock_irq(&cred->tgcred->lock);
245
246	/* we're using RCU on the pointer, but there's no point synchronising
247	 * on it if it didn't previously point to anything */
248	if (old) {
249		synchronize_rcu();
250		key_put(old);
251	}
252
253	return 0;
254}
255
256/*
257 * install a session keyring, discarding the old one
258 * - if a keyring is not supplied, an empty one is invented
259 */
260static int install_session_keyring(struct key *keyring)
261{
262	struct cred *new;
263	int ret;
264
265	new = prepare_creds();
266	if (!new)
267		return -ENOMEM;
268
269	ret = install_session_keyring_to_cred(new, NULL);
270	if (ret < 0) {
271		abort_creds(new);
272		return ret;
273	}
274
275	return commit_creds(new);
276}
277
278/*****************************************************************************/
279/*
280 * the filesystem user ID changed
281 */
282void key_fsuid_changed(struct task_struct *tsk)
283{
284	/* update the ownership of the thread keyring */
285	BUG_ON(!tsk->cred);
286	if (tsk->cred->thread_keyring) {
287		down_write(&tsk->cred->thread_keyring->sem);
288		tsk->cred->thread_keyring->uid = tsk->cred->fsuid;
289		up_write(&tsk->cred->thread_keyring->sem);
290	}
291
292} /* end key_fsuid_changed() */
293
294/*****************************************************************************/
295/*
296 * the filesystem group ID changed
297 */
298void key_fsgid_changed(struct task_struct *tsk)
299{
300	/* update the ownership of the thread keyring */
301	BUG_ON(!tsk->cred);
302	if (tsk->cred->thread_keyring) {
303		down_write(&tsk->cred->thread_keyring->sem);
304		tsk->cred->thread_keyring->gid = tsk->cred->fsgid;
305		up_write(&tsk->cred->thread_keyring->sem);
306	}
307
308} /* end key_fsgid_changed() */
309
310/*****************************************************************************/
311/*
312 * search only my process keyrings for the first matching key
313 * - we use the supplied match function to see if the description (or other
314 *   feature of interest) matches
315 * - we return -EAGAIN if we didn't find any matching key
316 * - we return -ENOKEY if we found only negative matching keys
317 */
318key_ref_t search_my_process_keyrings(struct key_type *type,
319				     const void *description,
320				     key_match_func_t match,
321				     const struct cred *cred)
322{
323	key_ref_t key_ref, ret, err;
324
325	/* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
326	 * searchable, but we failed to find a key or we found a negative key;
327	 * otherwise we want to return a sample error (probably -EACCES) if
328	 * none of the keyrings were searchable
329	 *
330	 * in terms of priority: success > -ENOKEY > -EAGAIN > other error
331	 */
332	key_ref = NULL;
333	ret = NULL;
334	err = ERR_PTR(-EAGAIN);
335
336	/* search the thread keyring first */
337	if (cred->thread_keyring) {
338		key_ref = keyring_search_aux(
339			make_key_ref(cred->thread_keyring, 1),
340			cred, type, description, match);
341		if (!IS_ERR(key_ref))
342			goto found;
343
344		switch (PTR_ERR(key_ref)) {
345		case -EAGAIN: /* no key */
346			if (ret)
347				break;
348		case -ENOKEY: /* negative key */
349			ret = key_ref;
350			break;
351		default:
352			err = key_ref;
353			break;
354		}
355	}
356
357	/* search the process keyring second */
358	if (cred->tgcred->process_keyring) {
359		key_ref = keyring_search_aux(
360			make_key_ref(cred->tgcred->process_keyring, 1),
361			cred, type, description, match);
362		if (!IS_ERR(key_ref))
363			goto found;
364
365		switch (PTR_ERR(key_ref)) {
366		case -EAGAIN: /* no key */
367			if (ret)
368				break;
369		case -ENOKEY: /* negative key */
370			ret = key_ref;
371			break;
372		default:
373			err = key_ref;
374			break;
375		}
376	}
377
378	/* search the session keyring */
379	if (cred->tgcred->session_keyring) {
380		rcu_read_lock();
381		key_ref = keyring_search_aux(
382			make_key_ref(rcu_dereference(
383					     cred->tgcred->session_keyring),
384				     1),
385			cred, type, description, match);
386		rcu_read_unlock();
387
388		if (!IS_ERR(key_ref))
389			goto found;
390
391		switch (PTR_ERR(key_ref)) {
392		case -EAGAIN: /* no key */
393			if (ret)
394				break;
395		case -ENOKEY: /* negative key */
396			ret = key_ref;
397			break;
398		default:
399			err = key_ref;
400			break;
401		}
402	}
403	/* or search the user-session keyring */
404	else if (cred->user->session_keyring) {
405		key_ref = keyring_search_aux(
406			make_key_ref(cred->user->session_keyring, 1),
407			cred, type, description, match);
408		if (!IS_ERR(key_ref))
409			goto found;
410
411		switch (PTR_ERR(key_ref)) {
412		case -EAGAIN: /* no key */
413			if (ret)
414				break;
415		case -ENOKEY: /* negative key */
416			ret = key_ref;
417			break;
418		default:
419			err = key_ref;
420			break;
421		}
422	}
423
424	/* no key - decide on the error we're going to go for */
425	key_ref = ret ? ret : err;
426
427found:
428	return key_ref;
429}
430
431/*****************************************************************************/
432/*
433 * search the process keyrings for the first matching key
434 * - we use the supplied match function to see if the description (or other
435 *   feature of interest) matches
436 * - we return -EAGAIN if we didn't find any matching key
437 * - we return -ENOKEY if we found only negative matching keys
438 */
439key_ref_t search_process_keyrings(struct key_type *type,
440				  const void *description,
441				  key_match_func_t match,
442				  const struct cred *cred)
443{
444	struct request_key_auth *rka;
445	key_ref_t key_ref, ret = ERR_PTR(-EACCES), err;
446
447	might_sleep();
448
449	key_ref = search_my_process_keyrings(type, description, match, cred);
450	if (!IS_ERR(key_ref))
451		goto found;
452	err = key_ref;
453
454	/* if this process has an instantiation authorisation key, then we also
455	 * search the keyrings of the process mentioned there
456	 * - we don't permit access to request_key auth keys via this method
457	 */
458	if (cred->request_key_auth &&
459	    cred == current_cred() &&
460	    type != &key_type_request_key_auth
461	    ) {
462		/* defend against the auth key being revoked */
463		down_read(&cred->request_key_auth->sem);
464
465		if (key_validate(cred->request_key_auth) == 0) {
466			rka = cred->request_key_auth->payload.data;
467
468			key_ref = search_process_keyrings(type, description,
469							  match, rka->cred);
470
471			up_read(&cred->request_key_auth->sem);
472
473			if (!IS_ERR(key_ref))
474				goto found;
475
476			ret = key_ref;
477		} else {
478			up_read(&cred->request_key_auth->sem);
479		}
480	}
481
482	/* no key - decide on the error we're going to go for */
483	if (err == ERR_PTR(-ENOKEY) || ret == ERR_PTR(-ENOKEY))
484		key_ref = ERR_PTR(-ENOKEY);
485	else if (err == ERR_PTR(-EACCES))
486		key_ref = ret;
487	else
488		key_ref = err;
489
490found:
491	return key_ref;
492
493} /* end search_process_keyrings() */
494
495/*****************************************************************************/
496/*
497 * see if the key we're looking at is the target key
498 */
499int lookup_user_key_possessed(const struct key *key, const void *target)
500{
501	return key == target;
502
503} /* end lookup_user_key_possessed() */
504
505/*****************************************************************************/
506/*
507 * lookup a key given a key ID from userspace with a given permissions mask
508 * - don't create special keyrings unless so requested
509 * - partially constructed keys aren't found unless requested
510 */
511key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
512			  key_perm_t perm)
513{
514	struct request_key_auth *rka;
515	const struct cred *cred;
516	struct key *key;
517	key_ref_t key_ref, skey_ref;
518	int ret;
519
520try_again:
521	cred = get_current_cred();
522	key_ref = ERR_PTR(-ENOKEY);
523
524	switch (id) {
525	case KEY_SPEC_THREAD_KEYRING:
526		if (!cred->thread_keyring) {
527			if (!(lflags & KEY_LOOKUP_CREATE))
528				goto error;
529
530			ret = install_thread_keyring();
531			if (ret < 0) {
532				key_ref = ERR_PTR(ret);
533				goto error;
534			}
535			goto reget_creds;
536		}
537
538		key = cred->thread_keyring;
539		atomic_inc(&key->usage);
540		key_ref = make_key_ref(key, 1);
541		break;
542
543	case KEY_SPEC_PROCESS_KEYRING:
544		if (!cred->tgcred->process_keyring) {
545			if (!(lflags & KEY_LOOKUP_CREATE))
546				goto error;
547
548			ret = install_process_keyring();
549			if (ret < 0) {
550				key_ref = ERR_PTR(ret);
551				goto error;
552			}
553			goto reget_creds;
554		}
555
556		key = cred->tgcred->process_keyring;
557		atomic_inc(&key->usage);
558		key_ref = make_key_ref(key, 1);
559		break;
560
561	case KEY_SPEC_SESSION_KEYRING:
562		if (!cred->tgcred->session_keyring) {
563			/* always install a session keyring upon access if one
564			 * doesn't exist yet */
565			ret = install_user_keyrings();
566			if (ret < 0)
567				goto error;
568			ret = install_session_keyring(
569				cred->user->session_keyring);
570
571			if (ret < 0)
572				goto error;
573			goto reget_creds;
574		}
575
576		rcu_read_lock();
577		key = rcu_dereference(cred->tgcred->session_keyring);
578		atomic_inc(&key->usage);
579		rcu_read_unlock();
580		key_ref = make_key_ref(key, 1);
581		break;
582
583	case KEY_SPEC_USER_KEYRING:
584		if (!cred->user->uid_keyring) {
585			ret = install_user_keyrings();
586			if (ret < 0)
587				goto error;
588		}
589
590		key = cred->user->uid_keyring;
591		atomic_inc(&key->usage);
592		key_ref = make_key_ref(key, 1);
593		break;
594
595	case KEY_SPEC_USER_SESSION_KEYRING:
596		if (!cred->user->session_keyring) {
597			ret = install_user_keyrings();
598			if (ret < 0)
599				goto error;
600		}
601
602		key = cred->user->session_keyring;
603		atomic_inc(&key->usage);
604		key_ref = make_key_ref(key, 1);
605		break;
606
607	case KEY_SPEC_GROUP_KEYRING:
608		/* group keyrings are not yet supported */
609		key_ref = ERR_PTR(-EINVAL);
610		goto error;
611
612	case KEY_SPEC_REQKEY_AUTH_KEY:
613		key = cred->request_key_auth;
614		if (!key)
615			goto error;
616
617		atomic_inc(&key->usage);
618		key_ref = make_key_ref(key, 1);
619		break;
620
621	case KEY_SPEC_REQUESTOR_KEYRING:
622		if (!cred->request_key_auth)
623			goto error;
624
625		down_read(&cred->request_key_auth->sem);
626		if (cred->request_key_auth->flags & KEY_FLAG_REVOKED) {
627			key_ref = ERR_PTR(-EKEYREVOKED);
628			key = NULL;
629		} else {
630			rka = cred->request_key_auth->payload.data;
631			key = rka->dest_keyring;
632			atomic_inc(&key->usage);
633		}
634		up_read(&cred->request_key_auth->sem);
635		if (!key)
636			goto error;
637		key_ref = make_key_ref(key, 1);
638		break;
639
640	default:
641		key_ref = ERR_PTR(-EINVAL);
642		if (id < 1)
643			goto error;
644
645		key = key_lookup(id);
646		if (IS_ERR(key)) {
647			key_ref = ERR_CAST(key);
648			goto error;
649		}
650
651		key_ref = make_key_ref(key, 0);
652
653		/* check to see if we possess the key */
654		skey_ref = search_process_keyrings(key->type, key,
655						   lookup_user_key_possessed,
656						   cred);
657
658		if (!IS_ERR(skey_ref)) {
659			key_put(key);
660			key_ref = skey_ref;
661		}
662
663		break;
664	}
665
666	/* unlink does not use the nominated key in any way, so can skip all
667	 * the permission checks as it is only concerned with the keyring */
668	if (lflags & KEY_LOOKUP_FOR_UNLINK) {
669		ret = 0;
670		goto error;
671	}
672
673	if (!(lflags & KEY_LOOKUP_PARTIAL)) {
674		ret = wait_for_key_construction(key, true);
675		switch (ret) {
676		case -ERESTARTSYS:
677			goto invalid_key;
678		default:
679			if (perm)
680				goto invalid_key;
681		case 0:
682			break;
683		}
684	} else if (perm) {
685		ret = key_validate(key);
686		if (ret < 0)
687			goto invalid_key;
688	}
689
690	ret = -EIO;
691	if (!(lflags & KEY_LOOKUP_PARTIAL) &&
692	    !test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
693		goto invalid_key;
694
695	/* check the permissions */
696	ret = key_task_permission(key_ref, cred, perm);
697	if (ret < 0)
698		goto invalid_key;
699
700error:
701	put_cred(cred);
702	return key_ref;
703
704invalid_key:
705	key_ref_put(key_ref);
706	key_ref = ERR_PTR(ret);
707	goto error;
708
709	/* if we attempted to install a keyring, then it may have caused new
710	 * creds to be installed */
711reget_creds:
712	put_cred(cred);
713	goto try_again;
714
715} /* end lookup_user_key() */
716
717/*****************************************************************************/
718/*
719 * join the named keyring as the session keyring if possible, or attempt to
720 * create a new one of that name if not
721 * - if the name is NULL, an empty anonymous keyring is installed instead
722 * - named session keyring joining is done with a semaphore held
723 */
724long join_session_keyring(const char *name)
725{
726	const struct cred *old;
727	struct cred *new;
728	struct key *keyring;
729	long ret, serial;
730
731	/* only permit this if there's a single thread in the thread group -
732	 * this avoids us having to adjust the creds on all threads and risking
733	 * ENOMEM */
734	if (!current_is_single_threaded())
735		return -EMLINK;
736
737	new = prepare_creds();
738	if (!new)
739		return -ENOMEM;
740	old = current_cred();
741
742	/* if no name is provided, install an anonymous keyring */
743	if (!name) {
744		ret = install_session_keyring_to_cred(new, NULL);
745		if (ret < 0)
746			goto error;
747
748		serial = new->tgcred->session_keyring->serial;
749		ret = commit_creds(new);
750		if (ret == 0)
751			ret = serial;
752		goto okay;
753	}
754
755	/* allow the user to join or create a named keyring */
756	mutex_lock(&key_session_mutex);
757
758	/* look for an existing keyring of this name */
759	keyring = find_keyring_by_name(name, false);
760	if (PTR_ERR(keyring) == -ENOKEY) {
761		/* not found - try and create a new one */
762		keyring = keyring_alloc(name, old->uid, old->gid, old,
763					KEY_ALLOC_IN_QUOTA, NULL);
764		if (IS_ERR(keyring)) {
765			ret = PTR_ERR(keyring);
766			goto error2;
767		}
768	} else if (IS_ERR(keyring)) {
769		ret = PTR_ERR(keyring);
770		goto error2;
771	}
772
773	/* we've got a keyring - now to install it */
774	ret = install_session_keyring_to_cred(new, keyring);
775	if (ret < 0)
776		goto error2;
777
778	commit_creds(new);
779	mutex_unlock(&key_session_mutex);
780
781	ret = keyring->serial;
782	key_put(keyring);
783okay:
784	return ret;
785
786error2:
787	mutex_unlock(&key_session_mutex);
788error:
789	abort_creds(new);
790	return ret;
791}
792
793/*
794 * Replace a process's session keyring when that process resumes userspace on
795 * behalf of one of its children
796 */
797void key_replace_session_keyring(void)
798{
799	const struct cred *old;
800	struct cred *new;
801
802	if (!current->replacement_session_keyring)
803		return;
804
805	write_lock_irq(&tasklist_lock);
806	new = current->replacement_session_keyring;
807	current->replacement_session_keyring = NULL;
808	write_unlock_irq(&tasklist_lock);
809
810	if (!new)
811		return;
812
813	old = current_cred();
814	new->  uid	= old->  uid;
815	new-> euid	= old-> euid;
816	new-> suid	= old-> suid;
817	new->fsuid	= old->fsuid;
818	new->  gid	= old->  gid;
819	new-> egid	= old-> egid;
820	new-> sgid	= old-> sgid;
821	new->fsgid	= old->fsgid;
822	new->user	= get_uid(old->user);
823	new->group_info	= get_group_info(old->group_info);
824
825	new->securebits	= old->securebits;
826	new->cap_inheritable	= old->cap_inheritable;
827	new->cap_permitted	= old->cap_permitted;
828	new->cap_effective	= old->cap_effective;
829	new->cap_bset		= old->cap_bset;
830
831	new->jit_keyring	= old->jit_keyring;
832	new->thread_keyring	= key_get(old->thread_keyring);
833	new->tgcred->tgid	= old->tgcred->tgid;
834	new->tgcred->process_keyring = key_get(old->tgcred->process_keyring);
835
836	security_transfer_creds(new, old);
837
838	commit_creds(new);
839}
840