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