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 const struct cred *cred = current_cred(); 186 struct rb_node *_p = v; 187 struct key *key = rb_entry(_p, struct key, serial_node); 188 struct timespec now; 189 unsigned long timo; 190 key_ref_t key_ref, skey_ref; 191 char xbuf[12]; 192 int rc; 193 194 key_ref = make_key_ref(key, 0); 195 196 /* determine if the key is possessed by this process (a test we can 197 * skip if the key does not indicate the possessor can view it 198 */ 199 if (key->perm & KEY_POS_VIEW) { 200 skey_ref = search_my_process_keyrings(key->type, key, 201 lookup_user_key_possessed, 202 true, cred); 203 if (!IS_ERR(skey_ref)) { 204 key_ref_put(skey_ref); 205 key_ref = make_key_ref(key, 1); 206 } 207 } 208 209 /* check whether the current task is allowed to view the key (assuming 210 * non-possession) 211 * - the caller holds a spinlock, and thus the RCU read lock, making our 212 * access to __current_cred() safe 213 */ 214 rc = key_task_permission(key_ref, cred, KEY_VIEW); 215 if (rc < 0) 216 return 0; 217 218 now = current_kernel_time(); 219 220 rcu_read_lock(); 221 222 /* come up with a suitable timeout value */ 223 if (key->expiry == 0) { 224 memcpy(xbuf, "perm", 5); 225 } else if (now.tv_sec >= key->expiry) { 226 memcpy(xbuf, "expd", 5); 227 } else { 228 timo = key->expiry - now.tv_sec; 229 230 if (timo < 60) 231 sprintf(xbuf, "%lus", timo); 232 else if (timo < 60*60) 233 sprintf(xbuf, "%lum", timo / 60); 234 else if (timo < 60*60*24) 235 sprintf(xbuf, "%luh", timo / (60*60)); 236 else if (timo < 60*60*24*7) 237 sprintf(xbuf, "%lud", timo / (60*60*24)); 238 else 239 sprintf(xbuf, "%luw", timo / (60*60*24*7)); 240 } 241 242 #define showflag(KEY, LETTER, FLAG) \ 243 (test_bit(FLAG, &(KEY)->flags) ? LETTER : '-') 244 245 seq_printf(m, "%08x %c%c%c%c%c%c%c %5d %4s %08x %5d %5d %-9.9s ", 246 key->serial, 247 showflag(key, 'I', KEY_FLAG_INSTANTIATED), 248 showflag(key, 'R', KEY_FLAG_REVOKED), 249 showflag(key, 'D', KEY_FLAG_DEAD), 250 showflag(key, 'Q', KEY_FLAG_IN_QUOTA), 251 showflag(key, 'U', KEY_FLAG_USER_CONSTRUCT), 252 showflag(key, 'N', KEY_FLAG_NEGATIVE), 253 showflag(key, 'i', KEY_FLAG_INVALIDATED), 254 atomic_read(&key->usage), 255 xbuf, 256 key->perm, 257 from_kuid_munged(seq_user_ns(m), key->uid), 258 from_kgid_munged(seq_user_ns(m), key->gid), 259 key->type->name); 260 261 #undef showflag 262 263 if (key->type->describe) 264 key->type->describe(key, m); 265 seq_putc(m, '\n'); 266 267 rcu_read_unlock(); 268 return 0; 269 } 270 271 #endif /* CONFIG_KEYS_DEBUG_PROC_KEYS */ 272 273 static struct rb_node *__key_user_next(struct user_namespace *user_ns, struct rb_node *n) 274 { 275 while (n) { 276 struct key_user *user = rb_entry(n, struct key_user, node); 277 if (kuid_has_mapping(user_ns, user->uid)) 278 break; 279 n = rb_next(n); 280 } 281 return n; 282 } 283 284 static struct rb_node *key_user_next(struct user_namespace *user_ns, struct rb_node *n) 285 { 286 return __key_user_next(user_ns, rb_next(n)); 287 } 288 289 static struct rb_node *key_user_first(struct user_namespace *user_ns, struct rb_root *r) 290 { 291 struct rb_node *n = rb_first(r); 292 return __key_user_next(user_ns, n); 293 } 294 295 /* 296 * Implement "/proc/key-users" to provides a list of the key users and their 297 * quotas. 298 */ 299 static int proc_key_users_open(struct inode *inode, struct file *file) 300 { 301 return seq_open(file, &proc_key_users_ops); 302 } 303 304 static void *proc_key_users_start(struct seq_file *p, loff_t *_pos) 305 __acquires(key_user_lock) 306 { 307 struct rb_node *_p; 308 loff_t pos = *_pos; 309 310 spin_lock(&key_user_lock); 311 312 _p = key_user_first(seq_user_ns(p), &key_user_tree); 313 while (pos > 0 && _p) { 314 pos--; 315 _p = key_user_next(seq_user_ns(p), _p); 316 } 317 318 return _p; 319 } 320 321 static void *proc_key_users_next(struct seq_file *p, void *v, loff_t *_pos) 322 { 323 (*_pos)++; 324 return key_user_next(seq_user_ns(p), (struct rb_node *)v); 325 } 326 327 static void proc_key_users_stop(struct seq_file *p, void *v) 328 __releases(key_user_lock) 329 { 330 spin_unlock(&key_user_lock); 331 } 332 333 static int proc_key_users_show(struct seq_file *m, void *v) 334 { 335 struct rb_node *_p = v; 336 struct key_user *user = rb_entry(_p, struct key_user, node); 337 unsigned maxkeys = uid_eq(user->uid, GLOBAL_ROOT_UID) ? 338 key_quota_root_maxkeys : key_quota_maxkeys; 339 unsigned maxbytes = uid_eq(user->uid, GLOBAL_ROOT_UID) ? 340 key_quota_root_maxbytes : key_quota_maxbytes; 341 342 seq_printf(m, "%5u: %5d %d/%d %d/%d %d/%d\n", 343 from_kuid_munged(seq_user_ns(m), user->uid), 344 atomic_read(&user->usage), 345 atomic_read(&user->nkeys), 346 atomic_read(&user->nikeys), 347 user->qnkeys, 348 maxkeys, 349 user->qnbytes, 350 maxbytes); 351 352 return 0; 353 } 354