Print this page
10124 smatch fixes for cryptoadm
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/cmd-crypto/cryptoadm/adm_kef_ioctl.c
+++ new/usr/src/cmd/cmd-crypto/cryptoadm/adm_kef_ioctl.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
23 23 */
24 24 /*
25 25 * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
26 + * Copyright (c) 2018, Joyent, Inc.
26 27 */
27 28
28 29 #include <fcntl.h>
29 30 #include <stdio.h>
30 31 #include <stdlib.h>
31 32 #include <strings.h>
32 33 #include <unistd.h>
33 34 #include <locale.h>
34 35 #include <libgen.h>
35 36 #include <sys/types.h>
36 37 #include <sys/varargs.h>
37 38 #include <zone.h>
38 39 #include <sys/crypto/ioctladmin.h>
39 40 #include "cryptoadm.h"
40 41
41 42 #define DEFAULT_DEV_NUM 5
42 43 #define DEFAULT_SOFT_NUM 10
43 44
44 45 static crypto_get_soft_info_t *setup_get_soft_info(char *, int);
45 46
46 47 /*
47 48 * Prepare the argument for the LOAD_SOFT_CONFIG ioctl call for the
48 49 * provider pointed by pent. Return NULL if out of memory.
49 50 */
50 51 crypto_load_soft_config_t *
51 52 setup_soft_conf(entry_t *pent)
52 53 {
53 54 crypto_load_soft_config_t *pload_soft_conf;
54 55 mechlist_t *plist;
55 56 uint_t sup_count;
56 57 size_t extra_mech_size = 0;
57 58 int i;
58 59
59 60 if (pent == NULL) {
60 61 return (NULL);
61 62 }
62 63
63 64 sup_count = pent->sup_count;
64 65 if (sup_count > 1) {
65 66 extra_mech_size = sizeof (crypto_mech_name_t) *
66 67 (sup_count - 1);
67 68 }
68 69
69 70 pload_soft_conf = malloc(sizeof (crypto_load_soft_config_t) +
70 71 extra_mech_size);
71 72 if (pload_soft_conf == NULL) {
72 73 cryptodebug("out of memory.");
73 74 return (NULL);
74 75 }
75 76
76 77 (void) strlcpy(pload_soft_conf->sc_name, pent->name, MAXNAMELEN);
77 78 pload_soft_conf->sc_count = sup_count;
78 79
79 80 i = 0;
80 81 plist = pent->suplist;
81 82 while (i < sup_count) {
82 83 (void) strlcpy(pload_soft_conf->sc_list[i++],
83 84 plist->name, CRYPTO_MAX_MECH_NAME);
84 85 plist = plist->next;
85 86 }
86 87
87 88 return (pload_soft_conf);
88 89 }
89 90
90 91
91 92 /*
92 93 * Prepare the argument for the LOAD_SOFT_DISABLED ioctl call for the
93 94 * provider pointed by pent. Return NULL if out of memory.
94 95 */
95 96 crypto_load_soft_disabled_t *
96 97 setup_soft_dis(entry_t *pent)
97 98 {
98 99 crypto_load_soft_disabled_t *pload_soft_dis = NULL;
99 100 mechlist_t *plist = NULL;
100 101 size_t extra_mech_size = 0;
101 102 uint_t dis_count;
102 103 int i;
103 104
104 105 if (pent == NULL) {
105 106 return (NULL);
106 107 }
107 108
108 109 dis_count = pent->dis_count;
109 110 if (dis_count > 1) {
110 111 extra_mech_size = sizeof (crypto_mech_name_t) *
111 112 (dis_count - 1);
112 113 }
113 114
114 115 pload_soft_dis = malloc(sizeof (crypto_load_soft_disabled_t) +
115 116 extra_mech_size);
116 117 if (pload_soft_dis == NULL) {
117 118 cryptodebug("out of memory.");
118 119 return (NULL);
119 120 }
120 121
121 122 (void) strlcpy(pload_soft_dis->sd_name, pent->name, MAXNAMELEN);
122 123 pload_soft_dis->sd_count = dis_count;
123 124
124 125 i = 0;
125 126 plist = pent->dislist;
126 127 while (i < dis_count) {
127 128 (void) strlcpy(pload_soft_dis->sd_list[i++],
128 129 plist->name, CRYPTO_MAX_MECH_NAME);
129 130 plist = plist->next;
130 131 }
131 132
132 133 return (pload_soft_dis);
133 134 }
134 135
135 136
136 137 /*
137 138 * Prepare the argument for the LOAD_DEV_DISABLED ioctl call for the
138 139 * provider pointed by pent. Return NULL if out of memory.
139 140 */
140 141 crypto_load_dev_disabled_t *
141 142 setup_dev_dis(entry_t *pent)
142 143 {
143 144 crypto_load_dev_disabled_t *pload_dev_dis = NULL;
144 145 mechlist_t *plist = NULL;
145 146 size_t extra_mech_size = 0;
146 147 uint_t dis_count;
147 148 int i;
148 149 char pname[MAXNAMELEN];
149 150 int inst_num;
150 151
151 152 if (pent == NULL) {
152 153 return (NULL);
153 154 }
154 155
155 156 /* get the device name and the instance number */
156 157 if (split_hw_provname(pent->name, pname, &inst_num) == FAILURE) {
157 158 return (NULL);
158 159 }
159 160
160 161 /* allocate space for pload_dev_des */
161 162 dis_count = pent->dis_count;
162 163 if (dis_count > 1) {
163 164 extra_mech_size = sizeof (crypto_mech_name_t) *
164 165 (dis_count - 1);
165 166 }
166 167
167 168 pload_dev_dis = malloc(sizeof (crypto_load_dev_disabled_t) +
168 169 extra_mech_size);
169 170 if (pload_dev_dis == NULL) {
170 171 cryptodebug("out of memory.");
171 172 return (NULL);
172 173 }
173 174
174 175 /* set the values for pload_dev_dis */
175 176 (void) strlcpy(pload_dev_dis->dd_dev_name, pname, MAXNAMELEN);
176 177 pload_dev_dis->dd_dev_instance = inst_num;
177 178 pload_dev_dis->dd_count = dis_count;
178 179
179 180 i = 0;
180 181 plist = pent->dislist;
181 182 while (i < dis_count) {
182 183 (void) strlcpy(pload_dev_dis->dd_list[i++],
183 184 plist->name, CRYPTO_MAX_MECH_NAME);
184 185 plist = plist->next;
185 186 }
186 187
187 188 return (pload_dev_dis);
188 189 }
189 190
190 191
191 192 /*
192 193 * Prepare the calling argument of the UNLOAD_SOFT_MODULE ioctl call for the
193 194 * provider pointed by pent. Return NULL if out of memory.
194 195 */
195 196 crypto_unload_soft_module_t *
196 197 setup_unload_soft(entry_t *pent)
197 198 {
198 199 crypto_unload_soft_module_t *punload_soft;
199 200
200 201 if (pent == NULL) {
201 202 return (NULL);
202 203 }
203 204
204 205 punload_soft = malloc(sizeof (crypto_unload_soft_module_t));
205 206 if (punload_soft == NULL) {
206 207 cryptodebug("out of memory.");
207 208 return (NULL);
208 209 }
209 210
210 211 (void) strlcpy(punload_soft->sm_name, pent->name, MAXNAMELEN);
211 212
212 213 return (punload_soft);
213 214 }
214 215
215 216
216 217 /*
217 218 * Prepare the calling argument for the GET_SOFT_INFO call for the provider
218 219 * with the number of mechanisms specified in the second argument.
219 220 *
220 221 * Called by get_soft_info().
221 222 */
222 223 static crypto_get_soft_info_t *
223 224 setup_get_soft_info(char *provname, int count)
224 225 {
225 226 crypto_get_soft_info_t *psoft_info;
226 227 size_t extra_mech_size = 0;
227 228
228 229 if (provname == NULL) {
229 230 return (NULL);
230 231 }
231 232
232 233 if (count > 1) {
233 234 extra_mech_size = sizeof (crypto_mech_name_t) * (count - 1);
234 235 }
235 236
236 237 psoft_info = malloc(sizeof (crypto_get_soft_info_t) + extra_mech_size);
237 238 if (psoft_info == NULL) {
238 239 cryptodebug("out of memory.");
239 240 return (NULL);
240 241 }
241 242
242 243 (void) strlcpy(psoft_info->si_name, provname, MAXNAMELEN);
243 244 psoft_info->si_count = count;
244 245
245 246 return (psoft_info);
246 247 }
247 248
248 249
249 250 /*
250 251 * Get the device list from kernel.
251 252 */
252 253 int
253 254 get_dev_list(crypto_get_dev_list_t **ppdevlist)
254 255 {
255 256 crypto_get_dev_list_t *pdevlist;
256 257 int fd = -1;
257 258 int count = DEFAULT_DEV_NUM;
258 259
↓ open down ↓ |
223 lines elided |
↑ open up ↑ |
259 260 pdevlist = malloc(sizeof (crypto_get_dev_list_t) +
260 261 sizeof (crypto_dev_list_entry_t) * (count - 1));
261 262 if (pdevlist == NULL) {
262 263 cryptodebug("out of memory.");
263 264 return (FAILURE);
264 265 }
265 266
266 267 if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDONLY)) == -1) {
267 268 cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"),
268 269 ADMIN_IOCTL_DEVICE, strerror(errno));
270 + free(pdevlist);
269 271 return (FAILURE);
270 272 }
271 273
272 274 pdevlist->dl_dev_count = count;
273 275 if (ioctl(fd, CRYPTO_GET_DEV_LIST, pdevlist) == -1) {
274 276 cryptodebug("CRYPTO_GET_DEV_LIST ioctl failed: %s",
275 277 strerror(errno));
276 278 free(pdevlist);
277 279 (void) close(fd);
278 280 return (FAILURE);
279 281 }
280 282
281 283 /* BUFFER is too small, get the number of devices and retry it. */
282 284 if (pdevlist->dl_return_value == CRYPTO_BUFFER_TOO_SMALL) {
283 285 count = pdevlist->dl_dev_count;
284 286 free(pdevlist);
285 287 pdevlist = malloc(sizeof (crypto_get_dev_list_t) +
286 288 sizeof (crypto_dev_list_entry_t) * (count - 1));
287 289 if (pdevlist == NULL) {
288 290 cryptodebug("out of memory.");
289 291 (void) close(fd);
290 292 return (FAILURE);
291 293 }
292 294
293 295 if (ioctl(fd, CRYPTO_GET_DEV_LIST, pdevlist) == -1) {
294 296 cryptodebug("CRYPTO_GET_DEV_LIST ioctl failed: %s",
295 297 strerror(errno));
296 298 free(pdevlist);
297 299 (void) close(fd);
298 300 return (FAILURE);
299 301 }
300 302 }
301 303
302 304 if (pdevlist->dl_return_value != CRYPTO_SUCCESS) {
303 305 cryptodebug("CRYPTO_GET_DEV_LIST ioctl failed, "
304 306 "return_value = %d", pdevlist->dl_return_value);
305 307 free(pdevlist);
306 308 (void) close(fd);
307 309 return (FAILURE);
308 310 }
309 311
310 312 *ppdevlist = pdevlist;
311 313 (void) close(fd);
312 314 return (SUCCESS);
313 315 }
314 316
315 317
316 318 /*
317 319 * Get all the mechanisms supported by the hardware provider.
318 320 * The result will be stored in the second argument.
319 321 */
320 322 int
321 323 get_dev_info(char *devname, int inst_num, int count, mechlist_t **ppmechlist)
322 324 {
323 325 crypto_get_dev_info_t *dev_info;
324 326 mechlist_t *phead;
325 327 mechlist_t *pcur;
326 328 mechlist_t *pmech;
327 329 int fd = -1;
328 330 int i;
329 331 int rc;
330 332
331 333 if (devname == NULL || count < 1) {
332 334 cryptodebug("get_dev_info(): devname is NULL or bogus count");
333 335 return (FAILURE);
334 336 }
335 337
336 338 /* Set up the argument for the CRYPTO_GET_DEV_INFO ioctl call */
337 339 dev_info = malloc(sizeof (crypto_get_dev_info_t) +
338 340 sizeof (crypto_mech_name_t) * (count - 1));
339 341 if (dev_info == NULL) {
340 342 cryptodebug("out of memory.");
341 343 return (FAILURE);
342 344 }
343 345 (void) strlcpy(dev_info->di_dev_name, devname, MAXNAMELEN);
344 346 dev_info->di_dev_instance = inst_num;
345 347 dev_info->di_count = count;
346 348
347 349 /* Open the ioctl device */
348 350 if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDONLY)) == -1) {
349 351 cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"),
350 352 ADMIN_IOCTL_DEVICE, strerror(errno));
351 353 free(dev_info);
352 354 return (FAILURE);
353 355 }
354 356
355 357 if (ioctl(fd, CRYPTO_GET_DEV_INFO, dev_info) == -1) {
356 358 cryptodebug("CRYPTO_GET_DEV_INFO ioctl failed: %s",
357 359 strerror(errno));
358 360 free(dev_info);
359 361 (void) close(fd);
360 362 return (FAILURE);
361 363 }
362 364
363 365 if (dev_info->di_return_value != CRYPTO_SUCCESS) {
364 366 cryptodebug("CRYPTO_GET_DEV_INFO ioctl failed, "
365 367 "return_value = %d", dev_info->di_return_value);
366 368 free(dev_info);
367 369 (void) close(fd);
368 370 return (FAILURE);
369 371 }
370 372
371 373 phead = pcur = NULL;
372 374 rc = SUCCESS;
373 375 for (i = 0; i < dev_info->di_count; i++) {
374 376 pmech = create_mech(&dev_info->di_list[i][0]);
375 377 if (pmech == NULL) {
376 378 rc = FAILURE;
377 379 break;
378 380 } else {
379 381 if (phead == NULL) {
380 382 phead = pcur = pmech;
381 383 } else {
382 384 pcur->next = pmech;
383 385 pcur = pmech;
384 386 }
385 387 }
386 388 }
387 389
388 390 if (rc == SUCCESS) {
389 391 *ppmechlist = phead;
390 392 } else {
391 393 free_mechlist(phead);
392 394 }
393 395
394 396 free(dev_info);
395 397 (void) close(fd);
396 398 return (rc);
397 399 }
398 400
399 401
400 402 /*
401 403 * Get the supported mechanism list of the software provider from kernel.
402 404 *
403 405 * Parameters phardlist and psoftlist are supplied by get_kcfconf_info().
404 406 * If NULL, this function calls get_kcfconf_info() internally.
405 407 */
406 408 int
407 409 get_soft_info(char *provname, mechlist_t **ppmechlist,
408 410 entrylist_t *phardlist, entrylist_t *psoftlist)
409 411 {
410 412 boolean_t in_kernel = B_FALSE;
411 413 crypto_get_soft_info_t *psoft_info;
412 414 mechlist_t *phead;
413 415 mechlist_t *pmech;
414 416 mechlist_t *pcur;
415 417 entry_t *pent = NULL;
416 418 int count;
417 419 int fd = -1;
418 420 int rc;
419 421 int i;
420 422
421 423 if (provname == NULL) {
422 424 return (FAILURE);
423 425 }
424 426
425 427 if (getzoneid() == GLOBAL_ZONEID) {
426 428 /* use kcf.conf for kernel software providers in global zone */
427 429 if ((pent = getent_kef(provname, phardlist, psoftlist)) ==
428 430 NULL) {
429 431
430 432 /* No kcf.conf entry for this provider */
431 433 if (check_kernel_for_soft(provname, NULL, &in_kernel)
432 434 == FAILURE) {
433 435 return (FAILURE);
434 436 } else if (in_kernel == B_FALSE) {
435 437 cryptoerror(LOG_STDERR,
436 438 gettext("%s does not exist."), provname);
437 439 return (FAILURE);
438 440 }
439 441
440 442 /*
441 443 * Set mech count to 1. It will be reset to the
442 444 * correct value later if the setup buffer is too small.
443 445 */
444 446 count = 1;
445 447 } else {
446 448 count = pent->sup_count;
447 449 free_entry(pent);
448 450 }
449 451 } else {
450 452 /*
451 453 * kcf.conf not there in non-global zone: set mech count to 1.
452 454 * It will be reset to the correct value later if the setup
453 455 * buffer is too small.
454 456 */
455 457 count = 1;
456 458 }
457 459
458 460 if ((psoft_info = setup_get_soft_info(provname, count)) == NULL) {
459 461 return (FAILURE);
460 462 }
461 463
462 464 if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDONLY)) == -1) {
463 465 cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"),
464 466 ADMIN_IOCTL_DEVICE, strerror(errno));
465 467 free(psoft_info);
466 468 return (FAILURE);
467 469 }
468 470
469 471 /* make GET_SOFT_INFO ioctl call */
470 472 if ((rc = ioctl(fd, CRYPTO_GET_SOFT_INFO, psoft_info)) == -1) {
471 473 cryptodebug("CRYPTO_GET_SOFT_INFO ioctl failed: %s",
472 474 strerror(errno));
473 475 (void) close(fd);
474 476 free(psoft_info);
475 477 return (FAILURE);
476 478 }
477 479
478 480 /* BUFFER is too small, get the number of mechanisms and retry it. */
479 481 if (psoft_info->si_return_value == CRYPTO_BUFFER_TOO_SMALL) {
480 482 count = psoft_info->si_count;
481 483 free(psoft_info);
482 484 if ((psoft_info = setup_get_soft_info(provname, count))
483 485 == NULL) {
484 486 (void) close(fd);
485 487 return (FAILURE);
486 488 } else {
487 489 rc = ioctl(fd, CRYPTO_GET_SOFT_INFO, psoft_info);
488 490 if (rc == -1) {
489 491 cryptodebug("CRYPTO_GET_SOFT_INFO ioctl "
490 492 "failed: %s", strerror(errno));
491 493 (void) close(fd);
492 494 free(psoft_info);
493 495 return (FAILURE);
494 496 }
495 497 }
496 498 }
497 499
498 500 (void) close(fd);
499 501 if (psoft_info->si_return_value != CRYPTO_SUCCESS) {
500 502 cryptodebug("CRYPTO_GET_SOFT_INFO ioctl failed, "
501 503 "return_value = %d", psoft_info->si_return_value);
502 504 free(psoft_info);
503 505 return (FAILURE);
504 506 }
505 507
506 508
507 509 /* Build the mechanism linked list and return it */
508 510 rc = SUCCESS;
509 511 phead = pcur = NULL;
510 512 for (i = 0; i < psoft_info->si_count; i++) {
511 513 pmech = create_mech(&psoft_info->si_list[i][0]);
512 514 if (pmech == NULL) {
513 515 rc = FAILURE;
514 516 break;
515 517 } else {
516 518 if (phead == NULL) {
517 519 phead = pcur = pmech;
518 520 } else {
519 521 pcur->next = pmech;
520 522 pcur = pmech;
521 523 }
522 524 }
523 525 }
524 526
525 527 if (rc == FAILURE) {
526 528 free_mechlist(phead);
527 529 } else {
528 530 *ppmechlist = phead;
529 531 }
530 532
531 533 free(psoft_info);
532 534 return (rc);
533 535 }
534 536
535 537
536 538 /*
537 539 * Get the kernel software provider list from kernel.
538 540 */
539 541 int
540 542 get_soft_list(crypto_get_soft_list_t **ppsoftlist)
541 543 {
542 544 crypto_get_soft_list_t *psoftlist = NULL;
543 545 int count = DEFAULT_SOFT_NUM;
544 546 int len;
545 547 int fd = -1;
546 548
547 549 if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDONLY)) == -1) {
548 550 cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"),
549 551 ADMIN_IOCTL_DEVICE, strerror(errno));
550 552 return (FAILURE);
551 553 }
552 554
553 555 len = MAXNAMELEN * count;
554 556 psoftlist = malloc(sizeof (crypto_get_soft_list_t) + len);
555 557 if (psoftlist == NULL) {
556 558 cryptodebug("out of memory.");
557 559 (void) close(fd);
558 560 return (FAILURE);
559 561 }
560 562 psoftlist->sl_soft_names = (caddr_t)(psoftlist + 1);
561 563 psoftlist->sl_soft_count = count;
562 564 psoftlist->sl_soft_len = len;
563 565
564 566 if (ioctl(fd, CRYPTO_GET_SOFT_LIST, psoftlist) == -1) {
565 567 cryptodebug("CRYPTO_GET_SOFT_LIST ioctl failed: %s",
566 568 strerror(errno));
567 569 free(psoftlist);
568 570 (void) close(fd);
569 571 return (FAILURE);
570 572 }
571 573
572 574 /*
573 575 * if BUFFER is too small, get the number of software providers and
574 576 * the minimum length needed for names and length and retry it.
575 577 */
576 578 if (psoftlist->sl_return_value == CRYPTO_BUFFER_TOO_SMALL) {
577 579 count = psoftlist->sl_soft_count;
578 580 len = psoftlist->sl_soft_len;
579 581 free(psoftlist);
580 582 psoftlist = malloc(sizeof (crypto_get_soft_list_t) + len);
581 583 if (psoftlist == NULL) {
582 584 cryptodebug("out of memory.");
583 585 (void) close(fd);
584 586 return (FAILURE);
585 587 }
586 588 psoftlist->sl_soft_names = (caddr_t)(psoftlist + 1);
587 589 psoftlist->sl_soft_count = count;
588 590 psoftlist->sl_soft_len = len;
589 591
590 592 if (ioctl(fd, CRYPTO_GET_SOFT_LIST, psoftlist) == -1) {
591 593 cryptodebug("CRYPTO_GET_SOFT_LIST ioctl failed:"
592 594 "%s", strerror(errno));
593 595 free(psoftlist);
594 596 (void) close(fd);
595 597 return (FAILURE);
596 598 }
597 599 }
598 600
599 601 if (psoftlist->sl_return_value != CRYPTO_SUCCESS) {
600 602 cryptodebug("CRYPTO_GET_SOFT_LIST ioctl failed, "
601 603 "return_value = %d", psoftlist->sl_return_value);
602 604 free(psoftlist);
603 605 (void) close(fd);
604 606 return (FAILURE);
605 607 }
606 608
607 609 *ppsoftlist = psoftlist;
608 610 (void) close(fd);
609 611 return (SUCCESS);
610 612 }
↓ open down ↓ |
332 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX