1 /* procfs files for key database enumeration 2 * 3 * Copyright (C) 2004 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/fs.h> 16 #include <linux/proc_fs.h> 17 #include <linux/seq_file.h> 18 #include <asm/errno.h> 19 #include "internal.h" 20 21 #ifdef CONFIG_KEYS_DEBUG_PROC_KEYS 22 static int proc_keys_open(struct inode *inode, struct file *file); 23 static void *proc_keys_start(struct seq_file *p, loff_t *_pos); 24 static void *proc_keys_next(struct seq_file *p, void *v, loff_t *_pos); 25 static void proc_keys_stop(struct seq_file *p, void *v); 26 static int proc_keys_show(struct seq_file *m, void *v); 27 28 static const struct seq_operations proc_keys_ops = { 29 .start = proc_keys_start, 30 .next = proc_keys_next, 31 .stop = proc_keys_stop, 32 .show = proc_keys_show, 33 }; 34 35 static const struct file_operations proc_keys_fops = { 36 .open = proc_keys_open, 37 .read = seq_read, 38 .llseek = seq_lseek, 39 .release = seq_release, 40 }; 41 #endif 42 43 static int proc_key_users_open(struct inode *inode, struct file *file); 44 static void *proc_key_users_start(struct seq_file *p, loff_t *_pos); 45 static void *proc_key_users_next(struct seq_file *p, void *v, loff_t *_pos); 46 static void proc_key_users_stop(struct seq_file *p, void *v); 47 static int proc_key_users_show(struct seq_file *m, void *v); 48 49 static const struct seq_operations proc_key_users_ops = { 50 .start = proc_key_users_start, 51 .next = proc_key_users_next, 52 .stop = proc_key_users_stop, 53 .show = proc_key_users_show, 54 }; 55 56 static const struct file_operations proc_key_users_fops = { 57 .open = proc_key_users_open, 58 .read = seq_read, 59 .llseek = seq_lseek, 60 .release = seq_release, 61 }; 62 63 /* 64 * Declare the /proc files. 65 */ 66 static int __init key_proc_init(void) 67 { 68 struct proc_dir_entry *p; 69 70 #ifdef CONFIG_KEYS_DEBUG_PROC_KEYS 71 p = proc_create("keys", 0, NULL, &proc_keys_fops); 72 if (!p) 73 panic("Cannot create /proc/keys\n"); 74 #endif 75 76 p = proc_create("key-users", 0, NULL, &proc_key_users_fops); 77 if (!p) 78 panic("Cannot create /proc/key-users\n"); 79 80 return 0; 81 } 82 83 __initcall(key_proc_init); 84 85 /* 86 * Implement "/proc/keys" to provide a list of the keys on the system that 87 * grant View permission to the caller. 88 */ 89 #ifdef CONFIG_KEYS_DEBUG_PROC_KEYS 90 91 static struct rb_node *key_serial_next(struct seq_file *p, struct rb_node *n) 92 { 93 struct user_namespace *user_ns = seq_user_ns(p); 94 95 n = rb_next(n); 96 while (n) { 97 struct key *key = rb_entry(n, struct key, serial_node); 98 if (kuid_has_mapping(user_ns, key->user->uid)) 99 break; 100 n = rb_next(n); 101 } 102 return n; 103 } 104 105 static int proc_keys_open(struct inode *inode, struct file *file) 106 { 107 return seq_open(file, &proc_keys_ops); 108 } 109 110 static struct key *find_ge_key(struct seq_file *p, key_serial_t id) 111 { 112 struct user_namespace *user_ns = seq_user_ns(p); 113 struct rb_node *n = key_serial_tree.rb_node; 114 struct key *minkey = NULL; 115 116 while (n) { 117 struct key *key = rb_entry(n, struct key, serial_node); 118 if (id < key->serial) { 119 if (!minkey || minkey->serial > key->serial) 120 minkey = key; 121 n = n->rb_left; 122 } else if (id > key->serial) { 123 n = n->rb_right; 124 } else { 125 minkey = key; 126 break; 127 } 128 key = NULL; 129 } 130 131 if (!minkey) 132 return NULL; 133 134 for (;;) { 135 if (kuid_has_mapping(user_ns, minkey->user->uid)) 136 return minkey; 137 n = rb_next(&minkey->serial_node); 138 if (!n) 139 return NULL; 140 minkey = rb_entry(n, struct key, serial_node); 141 } 142 } 143 144 static void *proc_keys_start(struct seq_file *p, loff_t *_pos) 145 __acquires(key_serial_lock) 146 { 147 key_serial_t pos = *_pos; 148 struct key *key; 149 150 spin_lock(&key_serial_lock); 151 152 if (*_pos > INT_MAX) 153 return NULL; 154 key = find_ge_key(p, pos); 155 if (!key) 156 return NULL; 157 *_pos = key->serial; 158 return &key->serial_node; 159 } 160 161 static inline key_serial_t key_node_serial(struct rb_node *n) 162 { 163 struct key *key = rb_entry(n, struct key, serial_node); 164 return key->serial; 165 } 166 167 static void *proc_keys_next(struct seq_file *p, void *v, loff_t *_pos) 168 { 169 struct rb_node *n; 170 171 n = key_serial_next(p, v); 172 if (n) 173 *_pos = key_node_serial(n); 174 return n; 175 } 176 177 static void proc_keys_stop(struct seq_file *p, void *v) 178 __releases(key_serial_lock) 179 { 180 spin_unlock(&key_serial_lock); 181 } 182 183 static int proc_keys_show(struct seq_file *m, void *v) 184 { 185 struct rb_node *_p = v; 186 struct key *key = rb_entry(_p, struct key, serial_node); 187 struct timespec now; 188 unsigned long timo; 189 key_ref_t key_ref, skey_ref; 190 char xbuf[12]; 191 int rc; 192 193 struct keyring_search_context ctx = { 194 .index_key.type = key->type, 195 .index_key.description = key->description, 196 .cred = current_cred(), 197 .match = lookup_user_key_possessed, 198 .match_data = key, 199 .flags = (KEYRING_SEARCH_NO_STATE_CHECK | 200 KEYRING_SEARCH_LOOKUP_DIRECT), 201 }; 202 203 key_ref = make_key_ref(key, 0); 204 205 /* determine if the key is possessed by this process (a test we can 206 * skip if the key does not indicate the possessor can view it 207 */ 208 if (key->perm & KEY_POS_VIEW) { 209 skey_ref = search_my_process_keyrings(&ctx); 210 if (!IS_ERR(skey_ref)) { 211 key_ref_put(skey_ref); 212 key_ref = make_key_ref(key, 1); 213 } 214 } 215 216 /* check whether the current task is allowed to view the key (assuming 217 * non-possession) 218 * - the caller holds a spinlock, and thus the RCU read lock, making our 219 * access to __current_cred() safe 220 */ 221 rc = key_task_permission(key_ref, ctx.cred, KEY_VIEW); 222 if (rc < 0) 223 return 0; 224 225 now = current_kernel_time(); 226 227 rcu_read_lock(); 228 229 /* come up with a suitable timeout value */ 230 if (key->expiry == 0) { 231 memcpy(xbuf, "perm", 5); 232 } else if (now.tv_sec >= key->expiry) { 233 memcpy(xbuf, "expd", 5); 234 } else { 235 timo = key->expiry - now.tv_sec; 236 237 if (timo < 60) 238 sprintf(xbuf, "%lus", timo); 239 else if (timo < 60*60) 240 sprintf(xbuf, "%lum", timo / 60); 241 else if (timo < 60*60*24) 242 sprintf(xbuf, "%luh", timo / (60*60)); 243 else if (timo < 60*60*24*7) 244 sprintf(xbuf, "%lud", timo / (60*60*24)); 245 else 246 sprintf(xbuf, "%luw", timo / (60*60*24*7)); 247 } 248 249 #define showflag(KEY, LETTER, FLAG) \ 250 (test_bit(FLAG, &(KEY)->flags) ? LETTER : '-') 251 252 seq_printf(m, "%08x %c%c%c%c%c%c%c %5d %4s %08x %5d %5d %-9.9s ", 253 key->serial, 254 showflag(key, 'I', KEY_FLAG_INSTANTIATED), 255 showflag(key, 'R', KEY_FLAG_REVOKED), 256 showflag(key, 'D', KEY_FLAG_DEAD), 257 showflag(key, 'Q', KEY_FLAG_IN_QUOTA), 258 showflag(key, 'U', KEY_FLAG_USER_CONSTRUCT), 259 showflag(key, 'N', KEY_FLAG_NEGATIVE), 260 showflag(key, 'i', KEY_FLAG_INVALIDATED), 261 atomic_read(&key->usage), 262 xbuf, 263 key->perm, 264 from_kuid_munged(seq_user_ns(m), key->uid), 265 from_kgid_munged(seq_user_ns(m), key->gid), 266 key->type->name); 267 268 #undef showflag 269 270 if (key->type->describe) 271 key->type->describe(key, m); 272 seq_putc(m, '\n'); 273 274 rcu_read_unlock(); 275 return 0; 276 } 277 278 #endif /* CONFIG_KEYS_DEBUG_PROC_KEYS */ 279 280 static struct rb_node *__key_user_next(struct user_namespace *user_ns, struct rb_node *n) 281 { 282 while (n) { 283 struct key_user *user = rb_entry(n, struct key_user, node); 284 if (kuid_has_mapping(user_ns, user->uid)) 285 break; 286 n = rb_next(n); 287 } 288 return n; 289 } 290 291 static struct rb_node *key_user_next(struct user_namespace *user_ns, struct rb_node *n) 292 { 293 return __key_user_next(user_ns, rb_next(n)); 294 } 295 296 static struct rb_node *key_user_first(struct user_namespace *user_ns, struct rb_root *r) 297 { 298 struct rb_node *n = rb_first(r); 299 return __key_user_next(user_ns, n); 300 } 301 302 /* 303 * Implement "/proc/key-users" to provides a list of the key users and their 304 * quotas. 305 */ 306 static int proc_key_users_open(struct inode *inode, struct file *file) 307 { 308 return seq_open(file, &proc_key_users_ops); 309 } 310 311 static void *proc_key_users_start(struct seq_file *p, loff_t *_pos) 312 __acquires(key_user_lock) 313 { 314 struct rb_node *_p; 315 loff_t pos = *_pos; 316 317 spin_lock(&key_user_lock); 318 319 _p = key_user_first(seq_user_ns(p), &key_user_tree); 320 while (pos > 0 && _p) { 321 pos--; 322 _p = key_user_next(seq_user_ns(p), _p); 323 } 324 325 return _p; 326 } 327 328 static void *proc_key_users_next(struct seq_file *p, void *v, loff_t *_pos) 329 { 330 (*_pos)++; 331 return key_user_next(seq_user_ns(p), (struct rb_node *)v); 332 } 333 334 static void proc_key_users_stop(struct seq_file *p, void *v) 335 __releases(key_user_lock) 336 { 337 spin_unlock(&key_user_lock); 338 } 339 340 static int proc_key_users_show(struct seq_file *m, void *v) 341 { 342 struct rb_node *_p = v; 343 struct key_user *user = rb_entry(_p, struct key_user, node); 344 unsigned maxkeys = uid_eq(user->uid, GLOBAL_ROOT_UID) ? 345 key_quota_root_maxkeys : key_quota_maxkeys; 346 unsigned maxbytes = uid_eq(user->uid, GLOBAL_ROOT_UID) ? 347 key_quota_root_maxbytes : key_quota_maxbytes; 348 349 seq_printf(m, "%5u: %5d %d/%d %d/%d %d/%d\n", 350 from_kuid_munged(seq_user_ns(m), user->uid), 351 atomic_read(&user->usage), 352 atomic_read(&user->nkeys), 353 atomic_read(&user->nikeys), 354 user->qnkeys, 355 maxkeys, 356 user->qnbytes, 357 maxbytes); 358 359 return 0; 360 } 361