From 39d973eceff62b72f950e28d75f2b568790271a4 Mon Sep 17 00:00:00 2001 From: "Serge E. Hallyn" Date: Wed, 2 Sep 2009 09:14:05 +0100 Subject: [PATCH] --- yaml --- r: 157343 b: refs/heads/master c: ad73a717e0fc6949c44e587ca5d63c273a30e6f5 h: refs/heads/master i: 157341: f9c3aa263d24608fc288745db74ce35b7acad266 157339: 973295e4d4440e86a5b714882729713d829fddbb 157335: b69b382a745dde38bd04c83e5cdf585295c983de 157327: b8fba86410dc61ca22649fd27a04eb2f5919973e 157311: a73562f22c3563ca81e62962a7d6dfecd007ffc2 v: v3 --- [refs] | 2 +- trunk/security/keys/proc.c | 77 +++++++++++++++++++++++++++----------- 2 files changed, 56 insertions(+), 23 deletions(-) diff --git a/[refs] b/[refs] index 591a7015e8ec..914b656bb4e8 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 5d135440faf7db8d566de0c6fab36b16cf9cfc3b +refs/heads/master: ad73a717e0fc6949c44e587ca5d63c273a30e6f5 diff --git a/trunk/security/keys/proc.c b/trunk/security/keys/proc.c index 39793c774f33..624c650c2efd 100644 --- a/trunk/security/keys/proc.c +++ b/trunk/security/keys/proc.c @@ -91,57 +91,90 @@ __initcall(key_proc_init); */ #ifdef CONFIG_KEYS_DEBUG_PROC_KEYS -static struct rb_node *__key_serial_next(struct rb_node *n) +static struct rb_node *key_serial_next(struct rb_node *n) { + struct user_namespace *user_ns = current_user_ns(); + + n = rb_next(n); while (n) { struct key *key = rb_entry(n, struct key, serial_node); - if (key->user->user_ns == current_user_ns()) + if (key->user->user_ns == user_ns) break; n = rb_next(n); } return n; } -static struct rb_node *key_serial_next(struct rb_node *n) +static int proc_keys_open(struct inode *inode, struct file *file) { - return __key_serial_next(rb_next(n)); + return seq_open(file, &proc_keys_ops); } -static struct rb_node *key_serial_first(struct rb_root *r) +static struct key *find_ge_key(key_serial_t id) { - struct rb_node *n = rb_first(r); - return __key_serial_next(n); -} + struct user_namespace *user_ns = current_user_ns(); + struct rb_node *n = key_serial_tree.rb_node; + struct key *minkey = NULL; -static int proc_keys_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &proc_keys_ops); + while (n) { + struct key *key = rb_entry(n, struct key, serial_node); + if (id < key->serial) { + if (!minkey || minkey->serial > key->serial) + minkey = key; + n = n->rb_left; + } else if (id > key->serial) { + n = n->rb_right; + } else { + minkey = key; + break; + } + key = NULL; + } + if (!minkey) + return NULL; + + for (;;) { + if (minkey->user->user_ns == user_ns) + return minkey; + n = rb_next(&minkey->serial_node); + if (!n) + return NULL; + minkey = rb_entry(n, struct key, serial_node); + } } static void *proc_keys_start(struct seq_file *p, loff_t *_pos) __acquires(key_serial_lock) { - struct rb_node *_p; - loff_t pos = *_pos; + key_serial_t pos = *_pos; + struct key *key; spin_lock(&key_serial_lock); - _p = key_serial_first(&key_serial_tree); - while (pos > 0 && _p) { - pos--; - _p = key_serial_next(_p); - } - - return _p; + if (*_pos > INT_MAX) + return NULL; + key = find_ge_key(pos); + if (!key) + return NULL; + *_pos = key->serial; + return &key->serial_node; +} +static inline key_serial_t key_node_serial(struct rb_node *n) +{ + struct key *key = rb_entry(n, struct key, serial_node); + return key->serial; } static void *proc_keys_next(struct seq_file *p, void *v, loff_t *_pos) { - (*_pos)++; - return key_serial_next((struct rb_node *) v); + struct rb_node *n; + n = key_serial_next(v); + if (n) + *_pos = key_node_serial(n); + return n; } static void proc_keys_stop(struct seq_file *p, void *v)