diff options
author | Miloslav Trmač <mitr@redhat.com> | 2010-07-09 09:15:04 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2010-07-19 09:25:50 +0200 |
commit | ce9ad0144a1a40e149f0efa9def2faf02c7a7694 (patch) | |
tree | 7e9c3d574d4bfe408bdf3acc27a988a42da13ba1 | |
parent | 4dabb1704fda63f6afde68275fa7027dc8d61ba7 (diff) | |
download | cryptodev-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.c | 14 | ||||
-rw-r--r-- | ncr-data.c | 22 | ||||
-rw-r--r-- | ncr-key.c | 22 | ||||
-rw-r--r-- | ncr-sessions.c | 8 |
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, @@ -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; } } @@ -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 |