summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ncr-data.c11
-rw-r--r--ncr-key.c9
-rw-r--r--ncr-limits.c32
-rw-r--r--ncr.c16
-rw-r--r--ncr_int.h18
-rw-r--r--userspace/setkey.c63
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;
}
diff --git a/ncr.c b/ncr.c
index da2144bd316..c7f54942df3 100644
--- a/ncr.c
+++ b/ncr.c
@@ -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;
+}