summaryrefslogtreecommitdiffstats
path: root/ncr-key.c
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 /ncr-key.c
parent4dabb1704fda63f6afde68275fa7027dc8d61ba7 (diff)
downloadkernel-crypto-ce9ad0144a1a40e149f0efa9def2faf02c7a7694.tar.gz
kernel-crypto-ce9ad0144a1a40e149f0efa9def2faf02c7a7694.tar.xz
kernel-crypto-ce9ad0144a1a40e149f0efa9def2faf02c7a7694.zip
Free data on error its descriptor to user-space
Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
Diffstat (limited to 'ncr-key.c')
-rw-r--r--ncr-key.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/ncr-key.c b/ncr-key.c
index 5693bdd3e6c..4c8287e2346 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;
}
}