diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2010-06-16 22:57:16 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2010-06-17 20:49:05 +0200 |
commit | 6b060c1dc5486cbf51f13d168c442e7df116b26c (patch) | |
tree | 45ab36ae9f4a405c22dc082b226c361e886fe726 | |
parent | 5797051e8b1f3ac4d6cc5edf181a04536b496d3d (diff) | |
download | kernel-crypto-6b060c1dc5486cbf51f13d168c442e7df116b26c.tar.gz kernel-crypto-6b060c1dc5486cbf51f13d168c442e7df116b26c.tar.xz kernel-crypto-6b060c1dc5486cbf51f13d168c442e7df116b26c.zip |
Use current_euid() and task_pid_nr(current) to get identifiers for owners (for imposed limits).
-rw-r--r-- | ncr-data.c | 11 | ||||
-rw-r--r-- | ncr-key.c | 9 | ||||
-rw-r--r-- | ncr-limits.c | 32 | ||||
-rw-r--r-- | ncr.c | 16 | ||||
-rw-r--r-- | ncr_int.h | 18 | ||||
-rw-r--r-- | userspace/setkey.c | 63 |
6 files changed, 107 insertions, 42 deletions
diff --git a/ncr-data.c b/ncr-data.c index ce9635c0956..a0d7ca9dea4 100644 --- a/ncr-data.c +++ b/ncr-data.c @@ -92,19 +92,19 @@ static void* data_alloc(size_t size) void _ncr_data_item_put( struct data_item_st* item) { if (atomic_dec_and_test(&item->refcnt)) { - ncr_limits_remove(item->filp, LIMIT_TYPE_DATA); + ncr_limits_remove(item->uid, item->pid, LIMIT_TYPE_DATA); kfree(item->data); kfree(item); } } -int ncr_data_init(struct file *filp, struct list_sem_st* lst, void __user* arg) +int ncr_data_init(struct list_sem_st* lst, void __user* arg) { struct ncr_data_init_st init; struct data_item_st* data; int ret; - ret = ncr_limits_add_and_check(filp, LIMIT_TYPE_DATA); + ret = ncr_limits_add_and_check(current_euid(), task_pid_nr(current), LIMIT_TYPE_DATA); if (ret < 0) { err(); return ret; @@ -121,7 +121,9 @@ int ncr_data_init(struct file *filp, struct list_sem_st* lst, void __user* arg) memset(data, 0, sizeof(*data)); data->flags = init.flags; - data->filp = filp; + data->uid = current_euid(); + data->pid = task_pid_nr(current); + atomic_set(&data->refcnt, 1); data->data = data_alloc(init.max_object_size); @@ -140,7 +142,6 @@ int ncr_data_init(struct file *filp, struct list_sem_st* lst, void __user* arg) down(&lst->sem); data->desc = _ncr_data_get_new_desc(lst); - data->filp = filp; list_add(&data->list, &lst->list); diff --git a/ncr-key.c b/ncr-key.c index fd5b48976bd..339ce0c41fb 100644 --- a/ncr-key.c +++ b/ncr-key.c @@ -81,18 +81,18 @@ struct key_item_st* item; void _ncr_key_item_put( struct key_item_st* item) { if (atomic_dec_and_test(&item->refcnt)) { - ncr_limits_remove(item->filp, LIMIT_TYPE_KEY); + ncr_limits_remove(item->uid, item->pid, LIMIT_TYPE_KEY); kfree(item); } } -int ncr_key_init(struct file *filp, struct list_sem_st* lst, void __user* arg) +int ncr_key_init(struct list_sem_st* lst, void __user* arg) { ncr_key_t desc; struct key_item_st* key; int ret; - ret = ncr_limits_add_and_check(filp, LIMIT_TYPE_KEY); + ret = ncr_limits_add_and_check(current_euid(), task_pid_nr(current), LIMIT_TYPE_KEY); if (ret < 0) { err(); return ret; @@ -113,7 +113,8 @@ int ncr_key_init(struct file *filp, struct list_sem_st* lst, void __user* arg) down(&lst->sem); key->desc = _ncr_key_get_new_desc(lst); - key->filp = filp; + key->uid = current_euid(); + key->pid = task_pid_nr(current); list_add(&key->list, &lst->list); diff --git a/ncr-limits.c b/ncr-limits.c index 857fc2e3538..378233c99ca 100644 --- a/ncr-limits.c +++ b/ncr-limits.c @@ -51,7 +51,7 @@ struct limit_user_item_st { struct limit_process_item_st { struct list_head list; - struct pid * pid; + pid_t pid; limits_type_t type; atomic_t cnt; }; @@ -93,21 +93,12 @@ struct limit_user_item_st* uitem, *utmp; } -int ncr_limits_add_and_check(struct file *filp, limits_type_t type) +int ncr_limits_add_and_check(uid_t uid, pid_t pid, limits_type_t type) { struct limit_process_item_st* pitem; struct limit_user_item_st* uitem; -uid_t uid; int add = 1; -/* FIXME: is this uid ok? - */ -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27) - uid = filp->f_uid; -#else - uid = filp->f_cred->fsuid; -#endif - down(&limits.users.sem); list_for_each_entry(uitem, &limits.users.list, list) { if (uitem->uid == uid && uitem->type == type) { @@ -139,7 +130,7 @@ int add = 1; /* check process limits */ down(&limits.processes.sem); list_for_each_entry(pitem, &limits.processes.list, list) { - if (pitem->pid == filp->f_owner.pid && pitem->type == type) { + if (pitem->pid == pid && pitem->type == type) { add = 0; if (atomic_add_unless(&pitem->cnt, 1, max_per_process[type])==0) { err(); @@ -156,7 +147,7 @@ int add = 1; err(); return -ENOMEM; } - pitem->pid = filp->f_owner.pid; + pitem->pid = task_pid_nr(current); pitem->type = type; atomic_set(&pitem->cnt, 1); @@ -167,19 +158,10 @@ int add = 1; return 0; } -void ncr_limits_remove(struct file *filp, limits_type_t type) +void ncr_limits_remove(uid_t uid, pid_t pid, limits_type_t type) { struct limit_process_item_st* pitem; struct limit_user_item_st* uitem; -uid_t uid; - -/* FIXME: is this uid ok? - */ -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27) - uid = filp->f_uid; -#else - uid = filp->f_cred->fsuid; -#endif down(&limits.users.sem); list_for_each_entry(uitem, &limits.users.list, list) { @@ -192,11 +174,11 @@ uid_t uid; /* check process limits */ down(&limits.processes.sem); list_for_each_entry(pitem, &limits.processes.list, list) { - if (pitem->pid == filp->f_owner.pid && pitem->type == type) { + if (pitem->pid == pid && pitem->type == type) { atomic_dec(&pitem->cnt); } } - up(&limits.processes.sem); + up(&limits.processes.sem); return; } @@ -27,6 +27,8 @@ #include <asm/uaccess.h> #include <asm/ioctl.h> #include <linux/scatterlist.h> +#include <linux/cred.h> +#include <linux/capability.h> #include "ncr.h" #include "ncr_int.h" @@ -76,6 +78,12 @@ void ncr_master_key_reset(void) static int ncr_master_key_set(void* __user arg) { struct ncr_master_key_st st; + + if (current_euid() != 0 && !capable(CAP_SYS_ADMIN)) { + err(); + return -EPERM; + } + copy_from_user(&st, arg, sizeof(st)); if (st.key_size > sizeof(master_key.key.secret.data)) { @@ -83,6 +91,10 @@ struct ncr_master_key_st st; return -EINVAL; } + if (master_key.type != NCR_KEY_TYPE_INVALID) { + dprintk(0, KERN_DEBUG, "Master key was previously initialized.\n"); + } + master_key.type = NCR_KEY_TYPE_SECRET; memcpy(master_key.key.secret.data, st.key, st.key_size); @@ -101,7 +113,7 @@ ncr_ioctl(struct ncr_lists* lst, struct file *filp, switch (cmd) { case NCRIO_DATA_INIT: - return ncr_data_init(filp, &lst->data, (void*)arg); + return ncr_data_init(&lst->data, (void*)arg); case NCRIO_DATA_GET: return ncr_data_get(&lst->data, (void*)arg); case NCRIO_DATA_SET: @@ -110,7 +122,7 @@ ncr_ioctl(struct ncr_lists* lst, struct file *filp, return ncr_data_deinit(&lst->data, (void*)arg); case NCRIO_KEY_INIT: - return ncr_key_init(filp, &lst->key, (void*)arg); + return ncr_key_init(&lst->key, (void*)arg); case NCRIO_KEY_DEINIT: return ncr_key_deinit(&lst->key, (void*)arg); case NCRIO_KEY_GENERATE: diff --git a/ncr_int.h b/ncr_int.h index 52fff2b97f1..892787b7cea 100644 --- a/ncr_int.h +++ b/ncr_int.h @@ -32,7 +32,10 @@ struct data_item_st { unsigned int flags; atomic_t refcnt; - struct file *filp; /* who has it */ + /* owner. The one charged with this */ + uid_t uid; + pid_t pid; + ncr_data_t desc; }; @@ -55,7 +58,10 @@ struct key_item_st { atomic_t refcnt; - struct file *filp; /* who has it */ + /* owner. The one charged with this */ + uid_t uid; + pid_t pid; + ncr_key_t desc; }; @@ -84,12 +90,12 @@ int ncr_ioctl(struct ncr_lists*, struct file *filp, int ncr_data_set(struct list_sem_st*, void __user* arg); int ncr_data_get(struct list_sem_st*, void __user* arg); int ncr_data_deinit(struct list_sem_st*, void __user* arg); -int ncr_data_init(struct file* filp, struct list_sem_st*, void __user* arg); +int ncr_data_init(struct list_sem_st*, void __user* arg); void ncr_data_list_deinit(struct list_sem_st*); struct data_item_st* ncr_data_item_get( struct list_sem_st* lst, ncr_data_t desc); void _ncr_data_item_put( struct data_item_st* item); -int ncr_key_init(struct file* filp, struct list_sem_st*, void __user* arg); +int ncr_key_init(struct list_sem_st*, void __user* arg); int ncr_key_deinit(struct list_sem_st*, void __user* arg); int ncr_key_export(struct list_sem_st* data_lst, struct list_sem_st* key_lst,void __user* arg); @@ -111,8 +117,8 @@ typedef enum { LIMIT_TYPE_DATA } limits_type_t; -void ncr_limits_remove(struct file *filp, limits_type_t type); -int ncr_limits_add_and_check(struct file *filp, limits_type_t type); +void ncr_limits_remove(uid_t uid, pid_t pid, limits_type_t type); +int ncr_limits_add_and_check(uid_t uid, pid_t pid, limits_type_t type); void ncr_limits_init(void); void ncr_limits_deinit(void); diff --git a/userspace/setkey.c b/userspace/setkey.c new file mode 100644 index 00000000000..2642b902c3a --- /dev/null +++ b/userspace/setkey.c @@ -0,0 +1,63 @@ +/* + * Demo on how to use /dev/crypto device for HMAC. + * + * Placed under public domain. + * + */ +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <time.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "../ncr.h" +#include <stdlib.h> + + + +int main(int argc, char** argv) +{ + int fd = -1; + FILE* fp; + struct ncr_master_key_st key; + int size; + + if (argc != 2) { + fprintf(stderr, "Usage: setkey [filename]\n"); + exit(1); + } + + memset(&key, 0, sizeof(key)); + fp = fopen(argv[1], "r"); + size = fread(key.key, 1, sizeof(key.key), fp); + if (size < 16) { + fprintf(stderr, "Illegal key!\n"); + exit(1); + } + fclose(fp); + key.key_size = size; + + /* Open the crypto device */ + fd = open("/dev/crypto", O_RDWR, 0); + if (fd < 0) { + perror("open(/dev/crypto)"); + return 1; + } + + /* encrypt */ + + if (ioctl(fd, NCRIO_MASTER_KEY_SET, &key)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_MASTER_KEY_SET)"); + return 1; + } + /* Close the original descriptor */ + if (close(fd)) { + perror("close(fd)"); + return 1; + } + + return 0; +} |