Print this page
9644 Double-free in crypto tests on failure
Reviewed by: Dan McDonald <danmcd@joyent.com>
Reviewed by: Mike Zeller <mike.zeller@joyent.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/test/crypto-tests/tests/common/cryptotest_kcf.c
+++ new/usr/src/test/crypto-tests/tests/common/cryptotest_kcf.c
1 1 /*
2 2 * This file and its contents are supplied under the terms of the
3 3 * Common Development and Distribution License ("CDDL"), version 1.0.
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
4 4 * You may only use this file in accordance with the terms of version
5 5 * 1.0 of the CDDL.
6 6 *
7 7 * A full copy of the text of the CDDL should have accompanied this
8 8 * source. A copy of the CDDL is also available via the Internet at
9 9 * http://www.illumos.org/license/CDDL.
10 10 */
11 11
12 12 /*
13 13 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
14 + * Copyright 2018, Joyent, Inc.
14 15 */
15 16
16 17 #include <fcntl.h>
17 18 #include <strings.h>
18 19 #include <unistd.h>
19 20 #include <errno.h>
20 21 #include <stdio.h>
21 22 #include <stdlib.h>
22 23
23 24 #include "cryptotest.h"
24 25
25 26 struct crypto_op {
26 27 char *in;
27 28 char *out;
28 29 char *key;
29 30 char *param;
30 31
31 32 size_t inlen;
32 33 size_t outlen;
33 34 size_t keylen;
34 35 size_t paramlen;
35 36 size_t updatelen;
36 37
37 38 char *mechname;
38 39
39 40 /* internal */
40 41 crypto_mech_type_t mech;
41 42 crypto_session_id_t hsession;
42 43 crypto_func_group_t fg;
43 44 };
44 45
45 46 static int fd;
46 47 static const char CRYPTO_DEVICE[] = "/dev/crypto";
47 48
48 49 int
49 50 kcf_do_ioctl(int opcode, uint_t *arg, char *opstr)
50 51 {
51 52 int ret;
52 53
53 54 while ((ret = ioctl(fd, opcode, arg)) < 0) {
54 55 if (errno != EINTR)
55 56 break;
56 57 }
57 58
58 59 if (ret < 0 || *arg != CRYPTO_SUCCESS)
59 60 (void) fprintf(stderr, "%s: Error = %d %d 0x%02x\n",
60 61 (opstr == NULL) ? "ioctl" : opstr,
61 62 ret, errno, *arg);
62 63
63 64 if (ret < 0)
64 65 return (errno);
65 66
66 67 return (*arg);
67 68 }
68 69
69 70 crypto_op_t *
70 71 cryptotest_init(cryptotest_t *arg, crypto_func_group_t fg)
71 72 {
72 73 crypto_op_t *op = malloc(sizeof (*op));
73 74
74 75 if (op == NULL)
75 76 return (NULL);
76 77
77 78 while ((fd = open(CRYPTO_DEVICE, O_RDWR)) < 0) {
78 79 if (errno != EINTR)
79 80 return (NULL);
80 81 }
81 82
82 83 op->in = (char *)arg->in;
83 84 op->out = (char *)arg->out;
84 85 op->key = (char *)arg->key;
85 86 op->param = (char *)arg->param;
86 87
87 88 op->inlen = arg->inlen;
88 89 op->outlen = arg->outlen;
89 90 op->keylen = arg->keylen * 8; /* kcf uses keylen in bits */
90 91 op->paramlen = arg->plen;
91 92 op->updatelen = arg->updatelen;
92 93
93 94 op->mechname = arg->mechname;
94 95
95 96 op->hsession = CRYPTO_INVALID_SESSION;
96 97 op->fg = fg;
97 98
98 99 if (op->out == NULL)
99 100 op->outlen = op->inlen;
100 101 return (op);
101 102 }
102 103
103 104 int
104 105 cryptotest_close_session(crypto_session_id_t session)
105 106 {
106 107 crypto_close_session_t cs;
107 108
108 109 cs.cs_session = session;
109 110 return (kcf_do_ioctl(CRYPTO_CLOSE_SESSION, (uint_t *)&cs, "session"));
110 111 }
111 112
112 113 int
113 114 cryptotest_close(crypto_op_t *op)
114 115 {
115 116 if (op->hsession != CRYPTO_INVALID_SESSION)
116 117 (void) cryptotest_close_session(op->hsession);
117 118 free(op);
118 119 if (fd >= 0)
119 120 return (close(fd));
120 121 return (0);
121 122 }
122 123
123 124 int
124 125 get_mech_info(crypto_op_t *op)
125 126 {
126 127 crypto_get_mechanism_number_t get_number;
↓ open down ↓ |
103 lines elided |
↑ open up ↑ |
127 128
128 129 bzero(&get_number, sizeof (get_number));
129 130
130 131 get_number.pn_mechanism_string = op->mechname;
131 132 get_number.pn_mechanism_len = strlen(op->mechname) + 1;
132 133
133 134 if (kcf_do_ioctl(CRYPTO_GET_MECHANISM_NUMBER,
134 135 (uint_t *)&get_number, "get_mech_info") != CRYPTO_SUCCESS) {
135 136 (void) fprintf(stderr, "failed to resolve mechanism name %s\n",
136 137 op->mechname);
137 - (void) cryptotest_close(op);
138 138 return (CTEST_NAME_RESOLVE_FAILED);
139 139 }
140 140 op->mech = get_number.pn_internal_number;
141 141 return (CRYPTO_SUCCESS);
142 142 }
143 143
144 144 int
145 145 get_hsession_by_mech(crypto_op_t *op)
146 146 {
147 147 crypto_by_mech_t mech;
148 148 int rv;
149 149
150 150 mech.mech_keylen = op->keylen;
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
151 151 mech.mech_type = op->mech;
152 152 mech.mech_fg = op->fg;
153 153
154 154 rv = kcf_do_ioctl(CRYPTO_GET_PROVIDER_BY_MECH, (uint_t *)&mech,
155 155 "get_hsession_by_mech");
156 156
157 157 if (rv != 0 || mech.rv != CRYPTO_SUCCESS) {
158 158 (void) fprintf(stderr,
159 159 "could not find provider for mechanism %llu\n",
160 160 mech.mech_type);
161 - (void) cryptotest_close(op);
162 161 return (CTEST_MECH_NO_PROVIDER);
163 162 }
164 163
165 164 op->hsession = mech.session_id;
166 165
167 166 return (CRYPTO_SUCCESS);
168 167 }
169 168
170 169 /*
171 170 * CRYPTO_MAC_* functions
172 171 */
173 172 int
174 173 mac_init(crypto_op_t *op)
175 174 {
176 175 crypto_mac_init_t init;
177 176
178 177 bzero((void *)&init, sizeof (init));
179 178
180 179 init.mi_session = op->hsession;
181 180
182 181 init.mi_key.ck_data = op->key;
183 182 init.mi_key.ck_format = CRYPTO_KEY_RAW; /* must be this */
184 183 init.mi_key.ck_length = op->keylen;
185 184
186 185 init.mi_mech.cm_type = op->mech;
187 186 init.mi_mech.cm_param = NULL;
188 187 init.mi_mech.cm_param_len = 0;
189 188
190 189 return (kcf_do_ioctl(CRYPTO_MAC_INIT, (uint_t *)&init, "init"));
191 190 }
192 191
193 192 int
194 193 mac_single(crypto_op_t *op)
195 194 {
196 195 crypto_mac_t mac;
197 196
198 197 bzero(&mac, sizeof (mac));
199 198 mac.cm_session = op->hsession;
200 199 mac.cm_datalen = op->inlen;
201 200 mac.cm_databuf = op->in;
202 201 mac.cm_maclen = op->outlen;
203 202 mac.cm_macbuf = op->out;
204 203
205 204 return (kcf_do_ioctl(CRYPTO_MAC, (uint_t *)&mac, "single"));
206 205 }
207 206
208 207 int
209 208 mac_update(crypto_op_t *op, int offset)
210 209 {
211 210 crypto_mac_update_t update;
212 211
213 212 bzero((void *)&update, sizeof (update));
214 213
215 214 update.mu_session = op->hsession;
216 215 update.mu_databuf = op->in + offset;
217 216 update.mu_datalen = op->updatelen;
218 217
219 218 return (kcf_do_ioctl(CRYPTO_MAC_UPDATE, (uint_t *)&update, "update"));
220 219 }
221 220
222 221 int
223 222 mac_final(crypto_op_t *op)
224 223 {
225 224 crypto_mac_final_t final;
226 225
227 226 bzero((void *)&final, sizeof (final));
228 227
229 228 final.mf_session = op->hsession;
230 229 final.mf_maclen = op->outlen;
231 230 final.mf_macbuf = op->out;
232 231
233 232 return (kcf_do_ioctl(CRYPTO_MAC_FINAL, (uint_t *)&final, "final"));
234 233 }
235 234
236 235
237 236 /*
238 237 * CRYPTO_ENCRYPT_* functions
239 238 */
240 239
241 240 int
242 241 encrypt_init(crypto_op_t *op)
243 242 {
244 243 crypto_encrypt_init_t init;
245 244
246 245 bzero((void *)&init, sizeof (init));
247 246
248 247 init.ei_session = op->hsession;
249 248
250 249 init.ei_key.ck_data = op->key;
251 250 init.ei_key.ck_format = CRYPTO_KEY_RAW; /* must be this */
252 251 init.ei_key.ck_length = op->keylen;
253 252
254 253 init.ei_mech.cm_type = op->mech;
255 254 init.ei_mech.cm_param = op->param;
256 255 init.ei_mech.cm_param_len = op->paramlen;
257 256
258 257 return (kcf_do_ioctl(CRYPTO_ENCRYPT_INIT, (uint_t *)&init, "init"));
259 258 }
260 259
261 260 int
262 261 encrypt_single(crypto_op_t *op)
263 262 {
264 263 crypto_encrypt_t encrypt;
265 264
266 265 bzero(&encrypt, sizeof (encrypt));
267 266 encrypt.ce_session = op->hsession;
268 267 encrypt.ce_datalen = op->inlen;
269 268 encrypt.ce_databuf = op->in;
270 269 encrypt.ce_encrlen = op->outlen;
271 270 encrypt.ce_encrbuf = op->out;
272 271
273 272 return (kcf_do_ioctl(CRYPTO_ENCRYPT, (uint_t *)&encrypt, "single"));
274 273 }
275 274
276 275 int
277 276 encrypt_update(crypto_op_t *op, int offset, size_t *encrlen)
278 277 {
279 278 crypto_encrypt_update_t update;
280 279 int ret;
281 280 bzero((void *)&update, sizeof (update));
282 281
283 282 update.eu_session = op->hsession;
284 283 update.eu_databuf = op->in + offset;
285 284 update.eu_datalen = op->updatelen;
286 285 update.eu_encrlen = op->outlen - *encrlen;
287 286 update.eu_encrbuf = op->out + *encrlen;
288 287
289 288 ret = kcf_do_ioctl(CRYPTO_ENCRYPT_UPDATE, (uint_t *)&update, "update");
290 289 *encrlen += update.eu_encrlen;
291 290 return (ret);
292 291 }
293 292
294 293 int
295 294 encrypt_final(crypto_op_t *op, size_t encrlen)
296 295 {
297 296 crypto_encrypt_final_t final;
298 297
299 298 bzero((void *)&final, sizeof (final));
300 299
301 300 final.ef_session = op->hsession;
302 301 final.ef_encrlen = op->outlen - encrlen;
303 302 final.ef_encrbuf = op->out + encrlen;
304 303
305 304 return (kcf_do_ioctl(CRYPTO_ENCRYPT_FINAL, (uint_t *)&final, "final"));
306 305 }
307 306
308 307 /*
309 308 * CRYPTO_DECRYPT_* functions
310 309 */
311 310
312 311 int
313 312 decrypt_init(crypto_op_t *op)
314 313 {
315 314 crypto_decrypt_init_t init;
316 315
317 316 bzero((void *)&init, sizeof (init));
318 317
319 318 init.di_session = op->hsession;
320 319
321 320 init.di_key.ck_data = op->key;
322 321 init.di_key.ck_format = CRYPTO_KEY_RAW; /* must be this */
323 322 init.di_key.ck_length = op->keylen;
324 323
325 324 init.di_mech.cm_type = op->mech;
326 325 init.di_mech.cm_param = op->param;
327 326 init.di_mech.cm_param_len = op->paramlen;
328 327
329 328 return (kcf_do_ioctl(CRYPTO_DECRYPT_INIT, (uint_t *)&init, "init"));
330 329 }
331 330
332 331 int
333 332 decrypt_single(crypto_op_t *op)
334 333 {
335 334 crypto_decrypt_t decrypt;
336 335
337 336 bzero(&decrypt, sizeof (decrypt));
338 337 decrypt.cd_session = op->hsession;
339 338 decrypt.cd_datalen = op->outlen;
340 339 decrypt.cd_databuf = op->out;
341 340 decrypt.cd_encrlen = op->inlen;
342 341 decrypt.cd_encrbuf = op->in;
343 342
344 343 return (kcf_do_ioctl(CRYPTO_DECRYPT, (uint_t *)&decrypt, "single"));
345 344 }
346 345
347 346 int
348 347 decrypt_update(crypto_op_t *op, int offset, size_t *encrlen)
349 348 {
350 349 crypto_decrypt_update_t update;
351 350 int ret;
352 351
353 352 bzero((void *)&update, sizeof (update));
354 353
355 354 update.du_session = op->hsession;
356 355 update.du_databuf = op->out + *encrlen;
357 356 update.du_datalen = op->outlen - *encrlen;
358 357 update.du_encrlen = op->updatelen;
359 358 update.du_encrbuf = op->in + offset;
360 359
361 360 ret = kcf_do_ioctl(CRYPTO_DECRYPT_UPDATE, (uint_t *)&update, "update");
362 361 *encrlen += update.du_datalen;
363 362 return (ret);
364 363 }
365 364
366 365 int
367 366 decrypt_final(crypto_op_t *op, size_t encrlen)
368 367 {
369 368 crypto_decrypt_final_t final;
370 369
371 370 bzero((void *)&final, sizeof (final));
372 371
373 372 final.df_session = op->hsession;
374 373 final.df_datalen = op->outlen - encrlen;
375 374 final.df_databuf = op->out + encrlen;
376 375
377 376 return (kcf_do_ioctl(CRYPTO_DECRYPT_FINAL, (uint_t *)&final, "final"));
378 377 }
↓ open down ↓ |
207 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX