root/security/keys/proc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. key_proc_init
  2. key_serial_next
  3. find_ge_key
  4. proc_keys_start
  5. key_node_serial
  6. proc_keys_next
  7. proc_keys_stop
  8. proc_keys_show
  9. __key_user_next
  10. key_user_next
  11. key_user_first
  12. proc_key_users_start
  13. proc_key_users_next
  14. proc_key_users_stop
  15. proc_key_users_show

   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(key_serial_lock)
 114 {
 115         key_serial_t pos = *_pos;
 116         struct key *key;
 117 
 118         spin_lock(&key_serial_lock);
 119 
 120         if (*_pos > INT_MAX)
 121                 return NULL;
 122         key = find_ge_key(p, pos);
 123         if (!key)
 124                 return NULL;
 125         *_pos = key->serial;
 126         return &key->serial_node;
 127 }
 128 
 129 static inline key_serial_t key_node_serial(struct rb_node *n)
 130 {
 131         struct key *key = rb_entry(n, struct key, serial_node);
 132         return key->serial;
 133 }
 134 
 135 static void *proc_keys_next(struct seq_file *p, void *v, loff_t *_pos)
 136 {
 137         struct rb_node *n;
 138 
 139         n = key_serial_next(p, v);
 140         if (n)
 141                 *_pos = key_node_serial(n);
 142         else
 143                 (*_pos)++;
 144         return n;
 145 }
 146 
 147 static void proc_keys_stop(struct seq_file *p, void *v)
 148         __releases(key_serial_lock)
 149 {
 150         spin_unlock(&key_serial_lock);
 151 }
 152 
 153 static int proc_keys_show(struct seq_file *m, void *v)
 154 {
 155         struct rb_node *_p = v;
 156         struct key *key = rb_entry(_p, struct key, serial_node);
 157         unsigned long flags;
 158         key_ref_t key_ref, skey_ref;
 159         time64_t now, expiry;
 160         char xbuf[16];
 161         short state;
 162         u64 timo;
 163         int rc;
 164 
 165         struct keyring_search_context ctx = {
 166                 .index_key              = key->index_key,
 167                 .cred                   = m->file->f_cred,
 168                 .match_data.cmp         = lookup_user_key_possessed,
 169                 .match_data.raw_data    = key,
 170                 .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
 171                 .flags                  = (KEYRING_SEARCH_NO_STATE_CHECK |
 172                                            KEYRING_SEARCH_RECURSE),
 173         };
 174 
 175         key_ref = make_key_ref(key, 0);
 176 
 177         /* determine if the key is possessed by this process (a test we can
 178          * skip if the key does not indicate the possessor can view it
 179          */
 180         if (key->perm & KEY_POS_VIEW) {
 181                 rcu_read_lock();
 182                 skey_ref = search_cred_keyrings_rcu(&ctx);
 183                 rcu_read_unlock();
 184                 if (!IS_ERR(skey_ref)) {
 185                         key_ref_put(skey_ref);
 186                         key_ref = make_key_ref(key, 1);
 187                 }
 188         }
 189 
 190         /* check whether the current task is allowed to view the key */
 191         rc = key_task_permission(key_ref, ctx.cred, KEY_NEED_VIEW);
 192         if (rc < 0)
 193                 return 0;
 194 
 195         now = ktime_get_real_seconds();
 196 
 197         rcu_read_lock();
 198 
 199         /* come up with a suitable timeout value */
 200         expiry = READ_ONCE(key->expiry);
 201         if (expiry == 0) {
 202                 memcpy(xbuf, "perm", 5);
 203         } else if (now >= expiry) {
 204                 memcpy(xbuf, "expd", 5);
 205         } else {
 206                 timo = expiry - now;
 207 
 208                 if (timo < 60)
 209                         sprintf(xbuf, "%llus", timo);
 210                 else if (timo < 60*60)
 211                         sprintf(xbuf, "%llum", div_u64(timo, 60));
 212                 else if (timo < 60*60*24)
 213                         sprintf(xbuf, "%lluh", div_u64(timo, 60 * 60));
 214                 else if (timo < 60*60*24*7)
 215                         sprintf(xbuf, "%llud", div_u64(timo, 60 * 60 * 24));
 216                 else
 217                         sprintf(xbuf, "%lluw", div_u64(timo, 60 * 60 * 24 * 7));
 218         }
 219 
 220         state = key_read_state(key);
 221 
 222 #define showflag(FLAGS, LETTER, FLAG) \
 223         ((FLAGS & (1 << FLAG)) ? LETTER : '-')
 224 
 225         flags = READ_ONCE(key->flags);
 226         seq_printf(m, "%08x %c%c%c%c%c%c%c %5d %4s %08x %5d %5d %-9.9s ",
 227                    key->serial,
 228                    state != KEY_IS_UNINSTANTIATED ? 'I' : '-',
 229                    showflag(flags, 'R', KEY_FLAG_REVOKED),
 230                    showflag(flags, 'D', KEY_FLAG_DEAD),
 231                    showflag(flags, 'Q', KEY_FLAG_IN_QUOTA),
 232                    showflag(flags, 'U', KEY_FLAG_USER_CONSTRUCT),
 233                    state < 0 ? 'N' : '-',
 234                    showflag(flags, 'i', KEY_FLAG_INVALIDATED),
 235                    refcount_read(&key->usage),
 236                    xbuf,
 237                    key->perm,
 238                    from_kuid_munged(seq_user_ns(m), key->uid),
 239                    from_kgid_munged(seq_user_ns(m), key->gid),
 240                    key->type->name);
 241 
 242 #undef showflag
 243 
 244         if (key->type->describe)
 245                 key->type->describe(key, m);
 246         seq_putc(m, '\n');
 247 
 248         rcu_read_unlock();
 249         return 0;
 250 }
 251 
 252 static struct rb_node *__key_user_next(struct user_namespace *user_ns, struct rb_node *n)
 253 {
 254         while (n) {
 255                 struct key_user *user = rb_entry(n, struct key_user, node);
 256                 if (kuid_has_mapping(user_ns, user->uid))
 257                         break;
 258                 n = rb_next(n);
 259         }
 260         return n;
 261 }
 262 
 263 static struct rb_node *key_user_next(struct user_namespace *user_ns, struct rb_node *n)
 264 {
 265         return __key_user_next(user_ns, rb_next(n));
 266 }
 267 
 268 static struct rb_node *key_user_first(struct user_namespace *user_ns, struct rb_root *r)
 269 {
 270         struct rb_node *n = rb_first(r);
 271         return __key_user_next(user_ns, n);
 272 }
 273 
 274 static void *proc_key_users_start(struct seq_file *p, loff_t *_pos)
 275         __acquires(key_user_lock)
 276 {
 277         struct rb_node *_p;
 278         loff_t pos = *_pos;
 279 
 280         spin_lock(&key_user_lock);
 281 
 282         _p = key_user_first(seq_user_ns(p), &key_user_tree);
 283         while (pos > 0 && _p) {
 284                 pos--;
 285                 _p = key_user_next(seq_user_ns(p), _p);
 286         }
 287 
 288         return _p;
 289 }
 290 
 291 static void *proc_key_users_next(struct seq_file *p, void *v, loff_t *_pos)
 292 {
 293         (*_pos)++;
 294         return key_user_next(seq_user_ns(p), (struct rb_node *)v);
 295 }
 296 
 297 static void proc_key_users_stop(struct seq_file *p, void *v)
 298         __releases(key_user_lock)
 299 {
 300         spin_unlock(&key_user_lock);
 301 }
 302 
 303 static int proc_key_users_show(struct seq_file *m, void *v)
 304 {
 305         struct rb_node *_p = v;
 306         struct key_user *user = rb_entry(_p, struct key_user, node);
 307         unsigned maxkeys = uid_eq(user->uid, GLOBAL_ROOT_UID) ?
 308                 key_quota_root_maxkeys : key_quota_maxkeys;
 309         unsigned maxbytes = uid_eq(user->uid, GLOBAL_ROOT_UID) ?
 310                 key_quota_root_maxbytes : key_quota_maxbytes;
 311 
 312         seq_printf(m, "%5u: %5d %d/%d %d/%d %d/%d\n",
 313                    from_kuid_munged(seq_user_ns(m), user->uid),
 314                    refcount_read(&user->usage),
 315                    atomic_read(&user->nkeys),
 316                    atomic_read(&user->nikeys),
 317                    user->qnkeys,
 318                    maxkeys,
 319                    user->qnbytes,
 320                    maxbytes);
 321 
 322         return 0;
 323 }

/* [<][>][^][v][top][bottom][index][help] */