summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiloslav Trmač <mitr@redhat.com>2010-07-09 09:15:04 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2010-07-19 09:25:50 +0200
commitce9ad0144a1a40e149f0efa9def2faf02c7a7694 (patch)
tree7e9c3d574d4bfe408bdf3acc27a988a42da13ba1
parent4dabb1704fda63f6afde68275fa7027dc8d61ba7 (diff)
downloadcryptodev-linux-ce9ad0144a1a40e149f0efa9def2faf02c7a7694.tar.gz
cryptodev-linux-ce9ad0144a1a40e149f0efa9def2faf02c7a7694.tar.xz
cryptodev-linux-ce9ad0144a1a40e149f0efa9def2faf02c7a7694.zip
Free data on error its descriptor to user-space
Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
-rw-r--r--cryptodev_main.c14
-rw-r--r--ncr-data.c22
-rw-r--r--ncr-key.c22
-rw-r--r--ncr-sessions.c8
4 files changed, 53 insertions, 13 deletions
diff --git a/cryptodev_main.c b/cryptodev_main.c
index d677d5b..d481a66 100644
--- a/cryptodev_main.c
+++ b/cryptodev_main.c
@@ -619,7 +619,12 @@ cryptodev_ioctl(struct inode *inode, struct file *filp,
ret = crypto_create_session(fcr, &sop);
if (unlikely(ret))
return ret;
- return copy_to_user((void*)arg, &sop, sizeof(sop));
+ ret = copy_to_user((void*)arg, &sop, sizeof(sop));
+ if (unlikely(ret)) {
+ crypto_finish_session(fcr, sop.ses);
+ return -EFAULT;
+ }
+ return ret;
case CIOCFSESSION:
get_user(ses, (uint32_t*)arg);
ret = crypto_finish_session(fcr, ses);
@@ -727,8 +732,13 @@ cryptodev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return ret;
session_op_to_compat(&sop, &compat_sop);
- return copy_to_user((void*)arg,
+ ret = copy_to_user((void*)arg,
&compat_sop, sizeof(compat_sop));
+ if (unlikely(ret)) {
+ crypto_finish_session(fcr, sop.ses);
+ return -EFAULT;
+ }
+ return ret;
case COMPAT_CIOCCRYPT:
ret = copy_from_user(&compat_cop,
diff --git a/ncr-data.c b/ncr-data.c
index 6a45e4d..82db6e8 100644
--- a/ncr-data.c
+++ b/ncr-data.c
@@ -29,6 +29,13 @@
#include "ncr.h"
#include "ncr_int.h"
+/* must be called with data semaphore down */
+static void _ncr_data_unlink_item(struct data_item_st *item)
+{
+ list_del(&item->list);
+ _ncr_data_item_put( item); /* decrement ref count */
+}
+
void ncr_data_list_deinit(struct list_sem_st* lst)
{
if(lst) {
@@ -37,8 +44,7 @@ void ncr_data_list_deinit(struct list_sem_st* lst)
down(&lst->sem);
list_for_each_entry_safe(item, tmp, &lst->list, list) {
- list_del(&item->list);
- _ncr_data_item_put( item); /* decrement ref count */
+ _ncr_data_unlink_item(item);
}
up(&lst->sem);
@@ -160,7 +166,14 @@ int ncr_data_init(struct list_sem_st* lst, void __user* arg)
up(&lst->sem);
init.desc = data->desc;
- return copy_to_user(arg, &init, sizeof(init));
+ ret = copy_to_user(arg, &init, sizeof(init));
+ if (unlikely(ret)) {
+ down(&lst->sem);
+ _ncr_data_unlink_item(data);
+ up(&lst->sem);
+ return -EFAULT;
+ }
+ return ret;
err_data:
kfree(data);
@@ -186,8 +199,7 @@ int ncr_data_deinit(struct list_sem_st* lst, void __user* arg)
list_for_each_entry_safe(item, tmp, &lst->list, list) {
if(item->desc == desc) {
- list_del(&item->list);
- _ncr_data_item_put( item); /* decrement ref count */
+ _ncr_data_unlink_item(item);
break;
}
}
diff --git a/ncr-key.c b/ncr-key.c
index 5693bdd..4c8287e 100644
--- a/ncr-key.c
+++ b/ncr-key.c
@@ -30,6 +30,13 @@
static void ncr_key_clear(struct key_item_st* item);
+/* must be called with data semaphore down */
+static void _ncr_key_unlink_item(struct key_item_st *item)
+{
+ list_del(&item->list);
+ _ncr_key_item_put( item); /* decrement ref count */
+}
+
void ncr_key_list_deinit(struct list_sem_st* lst)
{
if(lst) {
@@ -38,8 +45,7 @@ void ncr_key_list_deinit(struct list_sem_st* lst)
down(&lst->sem);
list_for_each_entry_safe(item, tmp, &lst->list, list) {
- list_del(&item->list);
- _ncr_key_item_put( item); /* decrement ref count */
+ _ncr_key_unlink_item(item);
}
up(&lst->sem);
}
@@ -183,7 +189,14 @@ int ncr_key_init(struct list_sem_st* lst, void __user* arg)
up(&lst->sem);
desc = key->desc;
- return copy_to_user(arg, &desc, sizeof(desc));
+ ret = copy_to_user(arg, &desc, sizeof(desc));
+ if (unlikely(ret)) {
+ down(&lst->sem);
+ _ncr_key_unlink_item(key);
+ up(&lst->sem);
+ return -EFAULT;
+ }
+ return ret;
err_limits:
ncr_limits_remove(current_euid(), task_pid_nr(current), LIMIT_TYPE_KEY);
@@ -207,8 +220,7 @@ int ncr_key_deinit(struct list_sem_st* lst, void __user* arg)
list_for_each_entry_safe(item, tmp, &lst->list, list) {
if(item->desc == desc) {
- list_del(&item->list);
- _ncr_key_item_put( item); /* decrement ref count */
+ _ncr_key_unlink_item(item);
break;
}
}
diff --git a/ncr-sessions.c b/ncr-sessions.c
index 834fd3d..b973bda 100644
--- a/ncr-sessions.c
+++ b/ncr-sessions.c
@@ -461,7 +461,13 @@ int ncr_session_init(struct ncr_lists* lists, void __user* arg)
return ret;
}
- return copy_to_user( arg, &session, sizeof(session));
+ ret = copy_to_user( arg, &session, sizeof(session));
+ if (unlikely(ret)) {
+ err();
+ _ncr_session_remove(&lists->sessions, session.ses);
+ return -EFAULT;
+ }
+ return ret;
}
/* Main update function