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