1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* procfs files for key database enumeration 3 * 4 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 5 * Written by David Howells (dhowells@redhat.com) 6 */ 7 8 #include <linux/init.h> 9 #include <linux/sched.h> 10 #include <linux/fs.h> 11 #include <linux/proc_fs.h> 12 #include <linux/seq_file.h> 13 #include <asm/errno.h> 14 #include "internal.h" 15 16 static void *proc_keys_start(struct seq_file *p, loff_t *_pos); 17 static void *proc_keys_next(struct seq_file *p, void *v, loff_t *_pos); 18 static void proc_keys_stop(struct seq_file *p, void *v); 19 static int proc_keys_show(struct seq_file *m, void *v); 20 21 static const struct seq_operations proc_keys_ops = { 22 .start = proc_keys_start, 23 .next = proc_keys_next, 24 .stop = proc_keys_stop, 25 .show = proc_keys_show, 26 }; 27 28 static void *proc_key_users_start(struct seq_file *p, loff_t *_pos); 29 static void *proc_key_users_next(struct seq_file *p, void *v, loff_t *_pos); 30 static void proc_key_users_stop(struct seq_file *p, void *v); 31 static int proc_key_users_show(struct seq_file *m, void *v); 32 33 static const struct seq_operations proc_key_users_ops = { 34 .start = proc_key_users_start, 35 .next = proc_key_users_next, 36 .stop = proc_key_users_stop, 37 .show = proc_key_users_show, 38 }; 39 40 /* 41 * Declare the /proc files. 42 */ 43 static int __init key_proc_init(void) 44 { 45 struct proc_dir_entry *p; 46 47 p = proc_create_seq("keys", 0, NULL, &proc_keys_ops); 48 if (!p) 49 panic("Cannot create /proc/keys\n"); 50 51 p = proc_create_seq("key-users", 0, NULL, &proc_key_users_ops); 52 if (!p) 53 panic("Cannot create /proc/key-users\n"); 54 55 return 0; 56 } 57 58 __initcall(key_proc_init); 59 60 /* 61 * Implement "/proc/keys" to provide a list of the keys on the system that 62 * grant View permission to the caller. 63 */ 64 static struct rb_node *key_serial_next(struct seq_file *p, struct rb_node *n) 65 { 66 struct user_namespace *user_ns = seq_user_ns(p); 67 68 n = rb_next(n); 69 while (n) { 70 struct key *key = rb_entry(n, struct key, serial_node); 71 if (kuid_has_mapping(user_ns, key->user->uid)) 72 break; 73 n = rb_next(n); 74 } 75 return n; 76 } 77 78 static struct key *find_ge_key(struct seq_file *p, key_serial_t id) 79 { 80 struct user_namespace *user_ns = seq_user_ns(p); 81 struct rb_node *n = key_serial_tree.rb_node; 82 struct key *minkey = NULL; 83 84 while (n) { 85 struct key *key = rb_entry(n, struct key, serial_node); 86 if (id < key->serial) { 87 if (!minkey || minkey->serial > key->serial) 88 minkey = key; 89 n = n->rb_left; 90 } else if (id > key->serial) { 91 n = n->rb_right; 92 } else { 93 minkey = key; 94 break; 95 } 96 key = NULL; 97 } 98 99 if (!minkey) 100 return NULL; 101 102 for (;;) { 103 if (kuid_has_mapping(user_ns, minkey->user->uid)) 104 return minkey; 105 n = rb_next(&minkey->serial_node); 106 if (!n) 107 return NULL; 108 minkey = rb_entry(n, struct key, serial_node); 109 } 110 } 111 112 static void *proc_keys_start(struct seq_file *p, loff_t *_pos) 113 __acquires(rcu) 114 __acquires(key_serial_lock) 115 { 116 key_serial_t pos = *_pos; 117 struct key *key; 118 119 rcu_read_lock(); 120 spin_lock(&key_serial_lock); 121 122 if (*_pos > INT_MAX) 123 return NULL; 124 key = find_ge_key(p, pos); 125 if (!key) 126 return NULL; 127 *_pos = key->serial; 128 return &key->serial_node; 129 } 130 131 static inline key_serial_t key_node_serial(struct rb_node *n) 132 { 133 struct key *key = rb_entry(n, struct key, serial_node); 134 return key->serial; 135 } 136 137 static void *proc_keys_next(struct seq_file *p, void *v, loff_t *_pos) 138 { 139 struct rb_node *n; 140 141 n = key_serial_next(p, v); 142 if (n) 143 *_pos = key_node_serial(n); 144 return n; 145 } 146 147 static void proc_keys_stop(struct seq_file *p, void *v) 148 __releases(key_serial_lock) 149 __releases(rcu) 150 { 151 spin_unlock(&key_serial_lock); 152 rcu_read_unlock(); 153 } 154 155 static int proc_keys_show(struct seq_file *m, void *v) 156 { 157 const struct key_acl *acl; 158 struct rb_node *_p = v; 159 struct key *key = rb_entry(_p, struct key, serial_node); 160 unsigned long flags; 161 key_ref_t key_ref, skey_ref; 162 time64_t now, expiry; 163 char xbuf[16]; 164 short state; 165 bool check_pos; 166 u64 timo; 167 int rc; 168 169 struct keyring_search_context ctx = { 170 .index_key = key->index_key, 171 .cred = m->file->f_cred, 172 .match_data.cmp = lookup_user_key_possessed, 173 .match_data.raw_data = key, 174 .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, 175 .flags = (KEYRING_SEARCH_NO_STATE_CHECK | 176 KEYRING_SEARCH_RECURSE), 177 }; 178 179 acl = rcu_dereference(key->acl); 180 check_pos = acl->possessor_viewable; 181 182 /* determine if the key is possessed by this process (a test we can 183 * skip if the key does not indicate the possessor can view it 184 */ 185 key_ref = make_key_ref(key, 0); 186 if (check_pos) { 187 skey_ref = search_cred_keyrings_rcu(&ctx); 188 if (!IS_ERR(skey_ref)) { 189 key_ref_put(skey_ref); 190 key_ref = make_key_ref(key, 1); 191 } 192 } 193 194 /* check whether the current task is allowed to view the key */ 195 rc = key_task_permission(key_ref, ctx.cred, KEY_NEED_VIEW); 196 if (rc < 0) 197 goto out; 198 199 now = ktime_get_real_seconds(); 200 201 /* come up with a suitable timeout value */ 202 expiry = READ_ONCE(key->expiry); 203 if (expiry == 0) { 204 memcpy(xbuf, "perm", 5); 205 } else if (now >= expiry) { 206 memcpy(xbuf, "expd", 5); 207 } else { 208 timo = expiry - now; 209 210 if (timo < 60) 211 sprintf(xbuf, "%llus", timo); 212 else if (timo < 60*60) 213 sprintf(xbuf, "%llum", div_u64(timo, 60)); 214 else if (timo < 60*60*24) 215 sprintf(xbuf, "%lluh", div_u64(timo, 60 * 60)); 216 else if (timo < 60*60*24*7) 217 sprintf(xbuf, "%llud", div_u64(timo, 60 * 60 * 24)); 218 else 219 sprintf(xbuf, "%lluw", div_u64(timo, 60 * 60 * 24 * 7)); 220 } 221 222 state = key_read_state(key); 223 224 #define showflag(FLAGS, LETTER, FLAG) \ 225 ((FLAGS & (1 << FLAG)) ? LETTER : '-') 226 227 flags = READ_ONCE(key->flags); 228 seq_printf(m, "%08x %c%c%c%c%c%c%c %5d %4s %08x %5d %5d %-9.9s ", 229 key->serial, 230 state != KEY_IS_UNINSTANTIATED ? 'I' : '-', 231 showflag(flags, 'R', KEY_FLAG_REVOKED), 232 showflag(flags, 'D', KEY_FLAG_DEAD), 233 showflag(flags, 'Q', KEY_FLAG_IN_QUOTA), 234 showflag(flags, 'U', KEY_FLAG_USER_CONSTRUCT), 235 state < 0 ? 'N' : '-', 236 showflag(flags, 'i', KEY_FLAG_INVALIDATED), 237 refcount_read(&key->usage), 238 xbuf, 239 key_acl_to_perm(acl), 240 from_kuid_munged(seq_user_ns(m), key->uid), 241 from_kgid_munged(seq_user_ns(m), key->gid), 242 key->type->name); 243 244 #undef showflag 245 246 if (key->type->describe) 247 key->type->describe(key, m); 248 seq_putc(m, '\n'); 249 250 out: 251 return 0; 252 } 253 254 static struct rb_node *__key_user_next(struct user_namespace *user_ns, struct rb_node *n) 255 { 256 while (n) { 257 struct key_user *user = rb_entry(n, struct key_user, node); 258 if (kuid_has_mapping(user_ns, user->uid)) 259 break; 260 n = rb_next(n); 261 } 262 return n; 263 } 264 265 static struct rb_node *key_user_next(struct user_namespace *user_ns, struct rb_node *n) 266 { 267 return __key_user_next(user_ns, rb_next(n)); 268 } 269 270 static struct rb_node *key_user_first(struct user_namespace *user_ns, struct rb_root *r) 271 { 272 struct rb_node *n = rb_first(r); 273 return __key_user_next(user_ns, n); 274 } 275 276 static void *proc_key_users_start(struct seq_file *p, loff_t *_pos) 277 __acquires(key_user_lock) 278 { 279 struct rb_node *_p; 280 loff_t pos = *_pos; 281 282 spin_lock(&key_user_lock); 283 284 _p = key_user_first(seq_user_ns(p), &key_user_tree); 285 while (pos > 0 && _p) { 286 pos--; 287 _p = key_user_next(seq_user_ns(p), _p); 288 } 289 290 return _p; 291 } 292 293 static void *proc_key_users_next(struct seq_file *p, void *v, loff_t *_pos) 294 { 295 (*_pos)++; 296 return key_user_next(seq_user_ns(p), (struct rb_node *)v); 297 } 298 299 static void proc_key_users_stop(struct seq_file *p, void *v) 300 __releases(key_user_lock) 301 { 302 spin_unlock(&key_user_lock); 303 } 304 305 static int proc_key_users_show(struct seq_file *m, void *v) 306 { 307 struct rb_node *_p = v; 308 struct key_user *user = rb_entry(_p, struct key_user, node); 309 unsigned maxkeys = uid_eq(user->uid, GLOBAL_ROOT_UID) ? 310 key_quota_root_maxkeys : key_quota_maxkeys; 311 unsigned maxbytes = uid_eq(user->uid, GLOBAL_ROOT_UID) ? 312 key_quota_root_maxbytes : key_quota_maxbytes; 313 314 seq_printf(m, "%5u: %5d %d/%d %d/%d %d/%d\n", 315 from_kuid_munged(seq_user_ns(m), user->uid), 316 refcount_read(&user->usage), 317 atomic_read(&user->nkeys), 318 atomic_read(&user->nikeys), 319 user->qnkeys, 320 maxkeys, 321 user->qnbytes, 322 maxbytes); 323 324 return 0; 325 } 326