diff options
Diffstat (limited to 'security/keys/internal.h')
| -rw-r--r-- | security/keys/internal.h | 215 |
1 files changed, 165 insertions, 50 deletions
diff --git a/security/keys/internal.h b/security/keys/internal.h index e066e605795..5f20da01fd8 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h @@ -1,6 +1,6 @@ -/* internal.h: authentication token and access key management internal defs +/* Authentication token and access key management internal defs * - * Copyright (C) 2003-5 Red Hat, Inc. All Rights Reserved. + * Copyright (C) 2003-5, 2007 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * * This program is free software; you can redistribute it and/or @@ -12,113 +12,208 @@ #ifndef _INTERNAL_H #define _INTERNAL_H -#include <linux/key.h> -#include <linux/key-ui.h> +#include <linux/sched.h> +#include <linux/key-type.h> +#include <linux/task_work.h> -#if 0 -#define kenter(FMT, a...) printk("==> %s("FMT")\n",__FUNCTION__ , ## a) -#define kleave(FMT, a...) printk("<== %s()"FMT"\n",__FUNCTION__ , ## a) -#define kdebug(FMT, a...) printk(FMT"\n" , ## a) +struct iovec; + +#ifdef __KDEBUG +#define kenter(FMT, ...) \ + printk(KERN_DEBUG "==> %s("FMT")\n", __func__, ##__VA_ARGS__) +#define kleave(FMT, ...) \ + printk(KERN_DEBUG "<== %s()"FMT"\n", __func__, ##__VA_ARGS__) +#define kdebug(FMT, ...) \ + printk(KERN_DEBUG " "FMT"\n", ##__VA_ARGS__) #else -#define kenter(FMT, a...) do {} while(0) -#define kleave(FMT, a...) do {} while(0) -#define kdebug(FMT, a...) do {} while(0) +#define kenter(FMT, ...) \ + no_printk(KERN_DEBUG "==> %s("FMT")\n", __func__, ##__VA_ARGS__) +#define kleave(FMT, ...) \ + no_printk(KERN_DEBUG "<== %s()"FMT"\n", __func__, ##__VA_ARGS__) +#define kdebug(FMT, ...) \ + no_printk(KERN_DEBUG FMT"\n", ##__VA_ARGS__) #endif +extern struct key_type key_type_dead; extern struct key_type key_type_user; +extern struct key_type key_type_logon; /*****************************************************************************/ /* - * keep track of keys for a user - * - this needs to be separate to user_struct to avoid a refcount-loop - * (user_struct pins some keyrings which pin this struct) - * - this also keeps track of keys under request from userspace for this UID + * Keep track of keys for a user. + * + * This needs to be separate to user_struct to avoid a refcount-loop + * (user_struct pins some keyrings which pin this struct). + * + * We also keep track of keys under request from userspace for this UID here. */ struct key_user { struct rb_node node; - struct list_head consq; /* construction queue */ + struct mutex cons_lock; /* construction initiation lock */ spinlock_t lock; atomic_t usage; /* for accessing qnkeys & qnbytes */ atomic_t nkeys; /* number of keys */ atomic_t nikeys; /* number of instantiated keys */ - uid_t uid; + kuid_t uid; int qnkeys; /* number of keys allocated to this user */ int qnbytes; /* number of bytes allocated to this user */ }; -#define KEYQUOTA_MAX_KEYS 100 -#define KEYQUOTA_MAX_BYTES 10000 -#define KEYQUOTA_LINK_BYTES 4 /* a link in a keyring is worth 4 bytes */ - extern struct rb_root key_user_tree; extern spinlock_t key_user_lock; extern struct key_user root_key_user; -extern struct key_user *key_user_lookup(uid_t uid); +extern struct key_user *key_user_lookup(kuid_t uid); extern void key_user_put(struct key_user *user); +/* + * Key quota limits. + * - root has its own separate limits to everyone else + */ +extern unsigned key_quota_root_maxkeys; +extern unsigned key_quota_root_maxbytes; +extern unsigned key_quota_maxkeys; +extern unsigned key_quota_maxbytes; +#define KEYQUOTA_LINK_BYTES 4 /* a link in a keyring is worth 4 bytes */ + +extern struct kmem_cache *key_jar; extern struct rb_root key_serial_tree; extern spinlock_t key_serial_lock; -extern struct semaphore key_alloc_sem; -extern struct rw_semaphore key_construction_sem; +extern struct mutex key_construction_mutex; extern wait_queue_head_t request_key_conswq; -extern void keyring_publish_name(struct key *keyring); +extern struct key_type *key_type_lookup(const char *type); +extern void key_type_put(struct key_type *ktype); -extern int __key_link(struct key *keyring, struct key *key); +extern int __key_link_begin(struct key *keyring, + const struct keyring_index_key *index_key, + struct assoc_array_edit **_edit); +extern int __key_link_check_live_key(struct key *keyring, struct key *key); +extern void __key_link(struct key *key, struct assoc_array_edit **_edit); +extern void __key_link_end(struct key *keyring, + const struct keyring_index_key *index_key, + struct assoc_array_edit *edit); -extern key_ref_t __keyring_search_one(key_ref_t keyring_ref, - const struct key_type *type, - const char *description, - key_perm_t perm); +extern key_ref_t find_key_to_update(key_ref_t keyring_ref, + const struct keyring_index_key *index_key); extern struct key *keyring_search_instkey(struct key *keyring, key_serial_t target_id); +extern int iterate_over_keyring(const struct key *keyring, + int (*func)(const struct key *key, void *data), + void *data); + typedef int (*key_match_func_t)(const struct key *, const void *); +struct keyring_search_context { + struct keyring_index_key index_key; + const struct cred *cred; + key_match_func_t match; + const void *match_data; + unsigned flags; +#define KEYRING_SEARCH_LOOKUP_TYPE 0x0001 /* [as type->def_lookup_type] */ +#define KEYRING_SEARCH_NO_STATE_CHECK 0x0002 /* Skip state checks */ +#define KEYRING_SEARCH_DO_STATE_CHECK 0x0004 /* Override NO_STATE_CHECK */ +#define KEYRING_SEARCH_NO_UPDATE_TIME 0x0008 /* Don't update times */ +#define KEYRING_SEARCH_NO_CHECK_PERM 0x0010 /* Don't check permissions */ +#define KEYRING_SEARCH_DETECT_TOO_DEEP 0x0020 /* Give an error on excessive depth */ + + int (*iterator)(const void *object, void *iterator_data); + + /* Internal stuff */ + int skipped_ret; + bool possessed; + key_ref_t result; + struct timespec now; +}; + extern key_ref_t keyring_search_aux(key_ref_t keyring_ref, - struct task_struct *tsk, - struct key_type *type, - const void *description, - key_match_func_t match); + struct keyring_search_context *ctx); -extern key_ref_t search_process_keyrings(struct key_type *type, - const void *description, - key_match_func_t match, - struct task_struct *tsk); +extern key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx); +extern key_ref_t search_process_keyrings(struct keyring_search_context *ctx); -extern struct key *find_keyring_by_name(const char *name, key_serial_t bound); +extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check); -extern int install_thread_keyring(struct task_struct *tsk); -extern int install_process_keyring(struct task_struct *tsk); +extern int install_user_keyrings(void); +extern int install_thread_keyring_to_cred(struct cred *); +extern int install_process_keyring_to_cred(struct cred *); +extern int install_session_keyring_to_cred(struct cred *, struct key *); extern struct key *request_key_and_link(struct key_type *type, const char *description, - const char *callout_info, - struct key *dest_keyring); + const void *callout_info, + size_t callout_len, + void *aux, + struct key *dest_keyring, + unsigned long flags); + +extern int lookup_user_key_possessed(const struct key *key, const void *target); +extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags, + key_perm_t perm); +#define KEY_LOOKUP_CREATE 0x01 +#define KEY_LOOKUP_PARTIAL 0x02 +#define KEY_LOOKUP_FOR_UNLINK 0x04 + +extern long join_session_keyring(const char *name); +extern void key_change_session_keyring(struct callback_head *twork); + +extern struct work_struct key_gc_work; +extern unsigned key_gc_delay; +extern void keyring_gc(struct key *keyring, time_t limit); +extern void key_schedule_gc(time_t gc_at); +extern void key_schedule_gc_links(void); +extern void key_gc_keytype(struct key_type *ktype); + +extern int key_task_permission(const key_ref_t key_ref, + const struct cred *cred, + key_perm_t perm); /* - * request_key authorisation + * Check to see whether permission is granted to use a key in the desired way. + */ +static inline int key_permission(const key_ref_t key_ref, unsigned perm) +{ + return key_task_permission(key_ref, current_cred(), perm); +} + +/* + * Authorisation record for request_key(). */ struct request_key_auth { struct key *target_key; - struct task_struct *context; - const char *callout_info; + struct key *dest_keyring; + const struct cred *cred; + void *callout_info; + size_t callout_len; pid_t pid; }; extern struct key_type key_type_request_key_auth; extern struct key *request_key_auth_new(struct key *target, - const char *callout_info); + const void *callout_info, + size_t callout_len, + struct key *dest_keyring); extern struct key *key_get_instantiation_authkey(key_serial_t target_id); /* - * keyctl functions + * Determine whether a key is dead. + */ +static inline bool key_is_dead(const struct key *key, time_t limit) +{ + return + key->flags & ((1 << KEY_FLAG_DEAD) | + (1 << KEY_FLAG_INVALIDATED)) || + (key->expiry > 0 && key->expiry <= limit); +} + +/* + * keyctl() functions */ extern long keyctl_get_keyring_ID(key_serial_t, int); extern long keyctl_join_session_keyring(const char __user *); @@ -139,10 +234,30 @@ extern long keyctl_negate_key(key_serial_t, unsigned, key_serial_t); extern long keyctl_set_reqkey_keyring(int); extern long keyctl_set_timeout(key_serial_t, unsigned); extern long keyctl_assume_authority(key_serial_t); - +extern long keyctl_get_security(key_serial_t keyid, char __user *buffer, + size_t buflen); +extern long keyctl_session_to_parent(void); +extern long keyctl_reject_key(key_serial_t, unsigned, unsigned, key_serial_t); +extern long keyctl_instantiate_key_iov(key_serial_t, + const struct iovec __user *, + unsigned, key_serial_t); +extern long keyctl_invalidate_key(key_serial_t); + +extern long keyctl_instantiate_key_common(key_serial_t, + const struct iovec *, + unsigned, size_t, key_serial_t); +#ifdef CONFIG_PERSISTENT_KEYRINGS +extern long keyctl_get_persistent(uid_t, key_serial_t); +extern unsigned persistent_keyring_expiry; +#else +static inline long keyctl_get_persistent(uid_t uid, key_serial_t destring) +{ + return -EOPNOTSUPP; +} +#endif /* - * debugging key validation + * Debugging key validation */ #ifdef KEY_DEBUGGING extern void __key_check(const struct key *); |
