1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* General persistent per-UID keyrings register
4 * Copyright (C) 2013 Red Hat, Inc. All Rights Reserved.
5 * Written by David Howells (dhowells@redhat.com)
8 #include <linux/user_namespace.h>
9 #include <linux/cred.h>
13 unsigned persistent_keyring_expiry
= 3 * 24 * 3600; /* Expire after 3 days of non-use */
16 * Create the persistent keyring register for the current user namespace.
18 * Called with the namespace's sem locked for writing.
20 static int key_create_persistent_register(struct user_namespace
*ns
)
22 struct key
*reg
= keyring_alloc(".persistent_register",
23 KUIDT_INIT(0), KGIDT_INIT(0),
25 ((KEY_POS_ALL
& ~KEY_POS_SETATTR
) |
26 KEY_USR_VIEW
| KEY_USR_READ
),
27 KEY_ALLOC_NOT_IN_QUOTA
, NULL
, NULL
);
31 ns
->persistent_keyring_register
= reg
;
36 * Create the persistent keyring for the specified user.
38 * Called with the namespace's sem locked for writing.
40 static key_ref_t
key_create_persistent(struct user_namespace
*ns
, kuid_t uid
,
41 struct keyring_index_key
*index_key
)
43 struct key
*persistent
;
44 key_ref_t reg_ref
, persistent_ref
;
46 if (!ns
->persistent_keyring_register
) {
47 long err
= key_create_persistent_register(ns
);
51 reg_ref
= make_key_ref(ns
->persistent_keyring_register
, true);
52 persistent_ref
= find_key_to_update(reg_ref
, index_key
);
54 return persistent_ref
;
57 persistent
= keyring_alloc(index_key
->description
,
58 uid
, INVALID_GID
, current_cred(),
59 ((KEY_POS_ALL
& ~KEY_POS_SETATTR
) |
60 KEY_USR_VIEW
| KEY_USR_READ
),
61 KEY_ALLOC_NOT_IN_QUOTA
, NULL
,
62 ns
->persistent_keyring_register
);
63 if (IS_ERR(persistent
))
64 return ERR_CAST(persistent
);
66 return make_key_ref(persistent
, true);
70 * Get the persistent keyring for a specific UID and link it to the nominated
73 static long key_get_persistent(struct user_namespace
*ns
, kuid_t uid
,
76 struct keyring_index_key index_key
;
77 struct key
*persistent
;
78 key_ref_t reg_ref
, persistent_ref
;
82 /* Look in the register if it exists */
83 memset(&index_key
, 0, sizeof(index_key
));
84 index_key
.type
= &key_type_keyring
;
85 index_key
.description
= buf
;
86 index_key
.desc_len
= sprintf(buf
, "_persistent.%u", from_kuid(ns
, uid
));
87 key_set_index_key(&index_key
);
89 if (ns
->persistent_keyring_register
) {
90 reg_ref
= make_key_ref(ns
->persistent_keyring_register
, true);
91 down_read(&ns
->keyring_sem
);
92 persistent_ref
= find_key_to_update(reg_ref
, &index_key
);
93 up_read(&ns
->keyring_sem
);
99 /* It wasn't in the register, so we'll need to create it. We might
100 * also need to create the register.
102 down_write(&ns
->keyring_sem
);
103 persistent_ref
= key_create_persistent(ns
, uid
, &index_key
);
104 up_write(&ns
->keyring_sem
);
105 if (!IS_ERR(persistent_ref
))
108 return PTR_ERR(persistent_ref
);
111 ret
= key_task_permission(persistent_ref
, current_cred(), KEY_NEED_LINK
);
113 persistent
= key_ref_to_ptr(persistent_ref
);
114 ret
= key_link(key_ref_to_ptr(dest_ref
), persistent
);
116 key_set_timeout(persistent
, persistent_keyring_expiry
);
117 ret
= persistent
->serial
;
121 key_ref_put(persistent_ref
);
126 * Get the persistent keyring for a specific UID and link it to the nominated
129 long keyctl_get_persistent(uid_t _uid
, key_serial_t destid
)
131 struct user_namespace
*ns
= current_user_ns();
136 /* -1 indicates the current user */
137 if (_uid
== (uid_t
)-1) {
140 uid
= make_kuid(ns
, _uid
);
144 /* You can only see your own persistent cache if you're not
145 * sufficiently privileged.
147 if (!uid_eq(uid
, current_uid()) &&
148 !uid_eq(uid
, current_euid()) &&
149 !ns_capable(ns
, CAP_SETUID
))
153 /* There must be a destination keyring */
154 dest_ref
= lookup_user_key(destid
, KEY_LOOKUP_CREATE
, KEY_NEED_WRITE
);
155 if (IS_ERR(dest_ref
))
156 return PTR_ERR(dest_ref
);
157 if (key_ref_to_ptr(dest_ref
)->type
!= &key_type_keyring
) {
162 ret
= key_get_persistent(ns
, uid
, dest_ref
);
165 key_ref_put(dest_ref
);