]> code.ossystems Code Review - meta-freescale.git/blob
67e4a89d393d03926bac53cadff20226aa185d6f
[meta-freescale.git] /
1 From 294abaaa4540ec340ed6046a784c9789c8724420 Mon Sep 17 00:00:00 2001
2 From: Cristian Stoica <cristian.stoica@nxp.com>
3 Date: Mon, 11 Jan 2016 17:45:50 +0200
4 Subject: [PATCH 29/38] fix clean-up on error path for crypto_create_session
5
6 This patch fixes clean-up on error path for failed allocations of
7 ses_new->pages or ses_new->sg. In these cases, allocations made in
8 cryptodev_hash_init have not been undone resulting in possible memory
9 leaks.
10
11 We take advantage of the initializations with zeros of the session
12 structure to trim the code to a single clean-up path.
13
14 Signed-off-by: Cristian Stoica <cristian.stoica@nxp.com>
15 ---
16  ioctl.c | 28 +++++++++++++++-------------
17  1 file changed, 15 insertions(+), 13 deletions(-)
18
19 diff --git a/ioctl.c b/ioctl.c
20 index b23f5fd..c781f9d 100644
21 --- a/ioctl.c
22 +++ b/ioctl.c
23 @@ -228,7 +228,8 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
24                 return -EINVAL;
25         }
26  
27 -       /* Create a session and put it to the list. */
28 +       /* Create a session and put it to the list. Zeroing the structure helps
29 +        * also with a single exit point in case of errors */
30         ses_new = kzalloc(sizeof(*ses_new), GFP_KERNEL);
31         if (!ses_new)
32                 return -ENOMEM;
33 @@ -240,19 +241,19 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
34                 if (unlikely(ret < 0)) {
35                         ddebug(1, "Setting key failed for %s-%zu.",
36                                 alg_name, (size_t)sop->keylen*8);
37 -                       goto error_cipher;
38 +                       goto session_error;
39                 }
40  
41                 ret = cryptodev_get_cipher_key(keys.ckey, sop, aead);
42                 if (unlikely(ret < 0))
43 -                       goto error_cipher;
44 +                       goto session_error;
45  
46                 ret = cryptodev_cipher_init(&ses_new->cdata, alg_name, keys.ckey,
47                                                 keylen, stream, aead);
48                 if (ret < 0) {
49                         ddebug(1, "Failed to load cipher for %s", alg_name);
50                         ret = -EINVAL;
51 -                       goto error_cipher;
52 +                       goto session_error;
53                 }
54         }
55  
56 @@ -261,13 +262,13 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
57                         ddebug(1, "Setting key failed for %s-%zu.",
58                                 hash_name, (size_t)sop->mackeylen*8);
59                         ret = -EINVAL;
60 -                       goto error_hash;
61 +                       goto session_error;
62                 }
63  
64                 if (sop->mackey && unlikely(copy_from_user(keys.mkey, sop->mackey,
65                                             sop->mackeylen))) {
66                         ret = -EFAULT;
67 -                       goto error_hash;
68 +                       goto session_error;
69                 }
70  
71                 ret = cryptodev_hash_init(&ses_new->hdata, hash_name, hmac_mode,
72 @@ -275,7 +276,7 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
73                 if (ret != 0) {
74                         ddebug(1, "Failed to load hash for %s", hash_name);
75                         ret = -EINVAL;
76 -                       goto error_hash;
77 +                       goto session_error;
78                 }
79         }
80  
81 @@ -292,7 +293,7 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
82         if (ses_new->sg == NULL || ses_new->pages == NULL) {
83                 ddebug(0, "Memory error");
84                 ret = -ENOMEM;
85 -               goto error_hash;
86 +               goto session_error;
87         }
88  
89         /* put the new session to the list */
90 @@ -316,18 +317,19 @@ restart:
91  
92         /* Fill in some values for the user. */
93         sop->ses = ses_new->sid;
94 -
95         return 0;
96  
97 -error_hash:
98 +       /* We count on ses_new to be initialized with zeroes
99 +        * Since hdata and cdata are embedded within ses_new, it follows that
100 +        * hdata->init and cdata->init are either zero or one as they have been
101 +        * initialized or not */
102 +session_error:
103 +       cryptodev_hash_deinit(&ses_new->hdata);
104         cryptodev_cipher_deinit(&ses_new->cdata);
105         kfree(ses_new->sg);
106         kfree(ses_new->pages);
107 -error_cipher:
108         kfree(ses_new);
109 -
110         return ret;
111 -
112  }
113  
114  /* Everything that needs to be done when remowing a session. */
115 -- 
116 2.7.0
117