1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2021 Microsoft Corporation 4 * 5 * Author: Tushar Sugandhi <tusharsu@linux.microsoft.com> 6 * 7 * Enables IMA measurements for DM targets 8 */ 9 10 #include "dm-core.h" 11 #include "dm-ima.h" 12 13 #include <linux/ima.h> 14 #include <linux/sched/mm.h> 15 #include <crypto/hash.h> 16 #include <linux/crypto.h> 17 #include <crypto/hash_info.h> 18 19 #define DM_MSG_PREFIX "ima" 20 21 /* 22 * Internal function to prefix separator characters in input buffer with escape 23 * character, so that they don't interfere with the construction of key-value pairs, 24 * and clients can split the key1=val1,key2=val2,key3=val3; pairs properly. 25 */ 26 static void fix_separator_chars(char **buf) 27 { 28 int l = strlen(*buf); 29 int i, j, sp = 0; 30 31 for (i = 0; i < l; i++) 32 if ((*buf)[i] == '\\' || (*buf)[i] == ';' || (*buf)[i] == '=' || (*buf)[i] == ',') 33 sp++; 34 35 if (!sp) 36 return; 37 38 for (i = l-1, j = i+sp; i >= 0; i--) { 39 (*buf)[j--] = (*buf)[i]; 40 if ((*buf)[i] == '\\' || (*buf)[i] == ';' || (*buf)[i] == '=' || (*buf)[i] == ',') 41 (*buf)[j--] = '\\'; 42 } 43 } 44 45 /* 46 * Internal function to allocate memory for IMA measurements. 47 */ 48 static void *dm_ima_alloc(size_t len, bool noio) 49 { 50 unsigned int noio_flag; 51 void *ptr; 52 53 if (noio) 54 noio_flag = memalloc_noio_save(); 55 56 ptr = kzalloc(len, GFP_KERNEL); 57 58 if (noio) 59 memalloc_noio_restore(noio_flag); 60 61 return ptr; 62 } 63 64 /* 65 * Internal function to allocate and copy name and uuid for IMA measurements. 66 */ 67 static int dm_ima_alloc_and_copy_name_uuid(struct mapped_device *md, char **dev_name, 68 char **dev_uuid, bool noio) 69 { 70 int r; 71 *dev_name = dm_ima_alloc(DM_NAME_LEN*2, noio); 72 if (!(*dev_name)) { 73 r = -ENOMEM; 74 goto error; 75 } 76 77 *dev_uuid = dm_ima_alloc(DM_UUID_LEN*2, noio); 78 if (!(*dev_uuid)) { 79 r = -ENOMEM; 80 goto error; 81 } 82 83 r = dm_copy_name_and_uuid(md, *dev_name, *dev_uuid); 84 if (r) 85 goto error; 86 87 fix_separator_chars(dev_name); 88 fix_separator_chars(dev_uuid); 89 90 return 0; 91 error: 92 kfree(*dev_name); 93 kfree(*dev_uuid); 94 *dev_name = NULL; 95 *dev_uuid = NULL; 96 return r; 97 } 98 99 /* 100 * Internal function to allocate and copy device data for IMA measurements. 101 */ 102 static int dm_ima_alloc_and_copy_device_data(struct mapped_device *md, char **device_data, 103 unsigned int num_targets, bool noio) 104 { 105 char *dev_name = NULL, *dev_uuid = NULL; 106 int r; 107 108 r = dm_ima_alloc_and_copy_name_uuid(md, &dev_name, &dev_uuid, noio); 109 if (r) 110 return r; 111 112 *device_data = dm_ima_alloc(DM_IMA_DEVICE_BUF_LEN, noio); 113 if (!(*device_data)) { 114 r = -ENOMEM; 115 goto error; 116 } 117 118 scnprintf(*device_data, DM_IMA_DEVICE_BUF_LEN, 119 "name=%s,uuid=%s,major=%d,minor=%d,minor_count=%d,num_targets=%u;", 120 dev_name, dev_uuid, md->disk->major, md->disk->first_minor, 121 md->disk->minors, num_targets); 122 error: 123 kfree(dev_name); 124 kfree(dev_uuid); 125 return r; 126 } 127 128 /* 129 * Internal wrapper function to call IMA to measure DM data. 130 */ 131 static void dm_ima_measure_data(const char *event_name, const void *buf, size_t buf_len, 132 bool noio) 133 { 134 unsigned int noio_flag; 135 136 if (noio) 137 noio_flag = memalloc_noio_save(); 138 139 ima_measure_critical_data(DM_NAME, event_name, buf, buf_len, 140 false, NULL, 0); 141 142 if (noio) 143 memalloc_noio_restore(noio_flag); 144 } 145 146 /* 147 * Internal function to allocate and copy current device capacity for IMA measurements. 148 */ 149 static int dm_ima_alloc_and_copy_capacity_str(struct mapped_device *md, char **capacity_str, 150 bool noio) 151 { 152 sector_t capacity; 153 154 capacity = get_capacity(md->disk); 155 156 *capacity_str = dm_ima_alloc(DM_IMA_DEVICE_CAPACITY_BUF_LEN, noio); 157 if (!(*capacity_str)) 158 return -ENOMEM; 159 160 return scnprintf(*capacity_str, DM_IMA_DEVICE_BUF_LEN, "current_device_capacity=%llu;", 161 capacity); 162 } 163 164 /* 165 * Initialize/reset the dm ima related data structure variables. 166 */ 167 void dm_ima_reset_data(struct mapped_device *md) 168 { 169 memset(&(md->ima), 0, sizeof(md->ima)); 170 md->ima.dm_version_str_len = strlen(DM_IMA_VERSION_STR); 171 } 172 173 /* 174 * Build up the IMA data for each target, and finally measure. 175 */ 176 void dm_ima_measure_on_table_load(struct dm_table *table, unsigned int status_flags) 177 { 178 size_t device_data_buf_len, target_metadata_buf_len, target_data_buf_len, l = 0; 179 char *target_metadata_buf = NULL, *target_data_buf = NULL, *digest_buf = NULL; 180 char *ima_buf = NULL, *device_data_buf = NULL; 181 int digest_size, last_target_measured = -1, r; 182 status_type_t type = STATUSTYPE_IMA; 183 size_t cur_total_buf_len = 0; 184 unsigned int num_targets, i; 185 SHASH_DESC_ON_STACK(shash, NULL); 186 struct crypto_shash *tfm = NULL; 187 u8 *digest = NULL; 188 bool noio = false; 189 /* 190 * In below hash_alg_prefix_len assignment +1 is for the additional char (':'), 191 * when prefixing the hash value with the hash algorithm name. e.g. sha256:<hash_value>. 192 */ 193 const size_t hash_alg_prefix_len = strlen(DM_IMA_TABLE_HASH_ALG) + 1; 194 char table_load_event_name[] = "dm_table_load"; 195 196 ima_buf = dm_ima_alloc(DM_IMA_MEASUREMENT_BUF_LEN, noio); 197 if (!ima_buf) 198 return; 199 200 target_metadata_buf = dm_ima_alloc(DM_IMA_TARGET_METADATA_BUF_LEN, noio); 201 if (!target_metadata_buf) 202 goto error; 203 204 target_data_buf = dm_ima_alloc(DM_IMA_TARGET_DATA_BUF_LEN, noio); 205 if (!target_data_buf) 206 goto error; 207 208 num_targets = table->num_targets; 209 210 if (dm_ima_alloc_and_copy_device_data(table->md, &device_data_buf, num_targets, noio)) 211 goto error; 212 213 tfm = crypto_alloc_shash(DM_IMA_TABLE_HASH_ALG, 0, 0); 214 if (IS_ERR(tfm)) 215 goto error; 216 217 shash->tfm = tfm; 218 digest_size = crypto_shash_digestsize(tfm); 219 digest = dm_ima_alloc(digest_size, noio); 220 if (!digest) 221 goto error; 222 223 r = crypto_shash_init(shash); 224 if (r) 225 goto error; 226 227 memcpy(ima_buf + l, DM_IMA_VERSION_STR, table->md->ima.dm_version_str_len); 228 l += table->md->ima.dm_version_str_len; 229 230 device_data_buf_len = strlen(device_data_buf); 231 memcpy(ima_buf + l, device_data_buf, device_data_buf_len); 232 l += device_data_buf_len; 233 234 for (i = 0; i < num_targets; i++) { 235 struct dm_target *ti = dm_table_get_target(table, i); 236 237 last_target_measured = 0; 238 239 /* 240 * First retrieve the target metadata. 241 */ 242 target_metadata_buf_len = 243 scnprintf(target_metadata_buf, 244 DM_IMA_TARGET_METADATA_BUF_LEN, 245 "target_index=%d,target_begin=%llu,target_len=%llu,", 246 i, ti->begin, ti->len); 247 248 /* 249 * Then retrieve the actual target data. 250 */ 251 if (ti->type->status) 252 ti->type->status(ti, type, status_flags, target_data_buf, 253 DM_IMA_TARGET_DATA_BUF_LEN); 254 else 255 target_data_buf[0] = '\0'; 256 257 target_data_buf_len = strlen(target_data_buf); 258 259 /* 260 * Check if the total data can fit into the IMA buffer. 261 */ 262 cur_total_buf_len = l + target_metadata_buf_len + target_data_buf_len; 263 264 /* 265 * IMA measurements for DM targets are best-effort. 266 * If the total data buffered so far, including the current target, 267 * is too large to fit into DM_IMA_MEASUREMENT_BUF_LEN, measure what 268 * we have in the current buffer, and continue measuring the remaining 269 * targets by prefixing the device metadata again. 270 */ 271 if (unlikely(cur_total_buf_len >= DM_IMA_MEASUREMENT_BUF_LEN)) { 272 dm_ima_measure_data(table_load_event_name, ima_buf, l, noio); 273 r = crypto_shash_update(shash, (const u8 *)ima_buf, l); 274 if (r < 0) 275 goto error; 276 277 memset(ima_buf, 0, DM_IMA_MEASUREMENT_BUF_LEN); 278 l = 0; 279 280 /* 281 * Each new "dm_table_load" entry in IMA log should have device data 282 * prefix, so that multiple records from the same "dm_table_load" for 283 * a given device can be linked together. 284 */ 285 memcpy(ima_buf + l, DM_IMA_VERSION_STR, table->md->ima.dm_version_str_len); 286 l += table->md->ima.dm_version_str_len; 287 288 memcpy(ima_buf + l, device_data_buf, device_data_buf_len); 289 l += device_data_buf_len; 290 291 /* 292 * If this iteration of the for loop turns out to be the last target 293 * in the table, dm_ima_measure_data("dm_table_load", ...) doesn't need 294 * to be called again, just the hash needs to be finalized. 295 * "last_target_measured" tracks this state. 296 */ 297 last_target_measured = 1; 298 } 299 300 /* 301 * Fill-in all the target metadata, so that multiple targets for the same 302 * device can be linked together. 303 */ 304 memcpy(ima_buf + l, target_metadata_buf, target_metadata_buf_len); 305 l += target_metadata_buf_len; 306 307 memcpy(ima_buf + l, target_data_buf, target_data_buf_len); 308 l += target_data_buf_len; 309 } 310 311 if (!last_target_measured) { 312 dm_ima_measure_data(table_load_event_name, ima_buf, l, noio); 313 314 r = crypto_shash_update(shash, (const u8 *)ima_buf, l); 315 if (r < 0) 316 goto error; 317 } 318 319 /* 320 * Finalize the table hash, and store it in table->md->ima.inactive_table.hash, 321 * so that the table data can be verified against the future device state change 322 * events, e.g. resume, rename, remove, table-clear etc. 323 */ 324 r = crypto_shash_final(shash, digest); 325 if (r < 0) 326 goto error; 327 328 digest_buf = dm_ima_alloc((digest_size*2) + hash_alg_prefix_len + 1, noio); 329 330 if (!digest_buf) 331 goto error; 332 333 snprintf(digest_buf, hash_alg_prefix_len + 1, "%s:", DM_IMA_TABLE_HASH_ALG); 334 335 for (i = 0; i < digest_size; i++) 336 snprintf((digest_buf + hash_alg_prefix_len + (i*2)), 3, "%02x", digest[i]); 337 338 if (table->md->ima.active_table.hash != table->md->ima.inactive_table.hash) 339 kfree(table->md->ima.inactive_table.hash); 340 341 table->md->ima.inactive_table.hash = digest_buf; 342 table->md->ima.inactive_table.hash_len = strlen(digest_buf); 343 table->md->ima.inactive_table.num_targets = num_targets; 344 345 if (table->md->ima.active_table.device_metadata != 346 table->md->ima.inactive_table.device_metadata) 347 kfree(table->md->ima.inactive_table.device_metadata); 348 349 table->md->ima.inactive_table.device_metadata = device_data_buf; 350 table->md->ima.inactive_table.device_metadata_len = device_data_buf_len; 351 352 goto exit; 353 error: 354 kfree(digest_buf); 355 kfree(device_data_buf); 356 exit: 357 kfree(digest); 358 if (tfm) 359 crypto_free_shash(tfm); 360 kfree(ima_buf); 361 kfree(target_metadata_buf); 362 kfree(target_data_buf); 363 } 364 365 /* 366 * Measure IMA data on device resume. 367 */ 368 void dm_ima_measure_on_device_resume(struct mapped_device *md, bool swap) 369 { 370 char *device_table_data, *dev_name = NULL, *dev_uuid = NULL, *capacity_str = NULL; 371 char active[] = "active_table_hash="; 372 unsigned int active_len = strlen(active); 373 unsigned int l = 0; 374 bool noio = true; 375 bool nodata = true; 376 int capacity_len; 377 378 device_table_data = dm_ima_alloc(DM_IMA_DEVICE_BUF_LEN, noio); 379 if (!device_table_data) 380 return; 381 382 capacity_len = dm_ima_alloc_and_copy_capacity_str(md, &capacity_str, noio); 383 if (capacity_len < 0) 384 goto error; 385 386 memcpy(device_table_data + l, DM_IMA_VERSION_STR, md->ima.dm_version_str_len); 387 l += md->ima.dm_version_str_len; 388 389 if (swap) { 390 if (md->ima.active_table.hash != md->ima.inactive_table.hash) 391 kfree(md->ima.active_table.hash); 392 393 md->ima.active_table.hash = NULL; 394 md->ima.active_table.hash_len = 0; 395 396 if (md->ima.active_table.device_metadata != 397 md->ima.inactive_table.device_metadata) 398 kfree(md->ima.active_table.device_metadata); 399 400 md->ima.active_table.device_metadata = NULL; 401 md->ima.active_table.device_metadata_len = 0; 402 md->ima.active_table.num_targets = 0; 403 404 if (md->ima.inactive_table.hash) { 405 md->ima.active_table.hash = md->ima.inactive_table.hash; 406 md->ima.active_table.hash_len = md->ima.inactive_table.hash_len; 407 md->ima.inactive_table.hash = NULL; 408 md->ima.inactive_table.hash_len = 0; 409 } 410 411 if (md->ima.inactive_table.device_metadata) { 412 md->ima.active_table.device_metadata = 413 md->ima.inactive_table.device_metadata; 414 md->ima.active_table.device_metadata_len = 415 md->ima.inactive_table.device_metadata_len; 416 md->ima.active_table.num_targets = md->ima.inactive_table.num_targets; 417 md->ima.inactive_table.device_metadata = NULL; 418 md->ima.inactive_table.device_metadata_len = 0; 419 md->ima.inactive_table.num_targets = 0; 420 } 421 } 422 423 if (md->ima.active_table.device_metadata) { 424 memcpy(device_table_data + l, md->ima.active_table.device_metadata, 425 md->ima.active_table.device_metadata_len); 426 l += md->ima.active_table.device_metadata_len; 427 428 nodata = false; 429 } 430 431 if (md->ima.active_table.hash) { 432 memcpy(device_table_data + l, active, active_len); 433 l += active_len; 434 435 memcpy(device_table_data + l, md->ima.active_table.hash, 436 md->ima.active_table.hash_len); 437 l += md->ima.active_table.hash_len; 438 439 memcpy(device_table_data + l, ";", 1); 440 l++; 441 442 nodata = false; 443 } 444 445 if (nodata) { 446 if (dm_ima_alloc_and_copy_name_uuid(md, &dev_name, &dev_uuid, noio)) 447 goto error; 448 449 l = scnprintf(device_table_data, DM_IMA_DEVICE_BUF_LEN, 450 "%sname=%s,uuid=%s;device_resume=no_data;", 451 DM_IMA_VERSION_STR, dev_name, dev_uuid); 452 } 453 454 memcpy(device_table_data + l, capacity_str, capacity_len); 455 l += capacity_len; 456 457 dm_ima_measure_data("dm_device_resume", device_table_data, l, noio); 458 459 kfree(dev_name); 460 kfree(dev_uuid); 461 error: 462 kfree(capacity_str); 463 kfree(device_table_data); 464 } 465 466 /* 467 * Measure IMA data on remove. 468 */ 469 void dm_ima_measure_on_device_remove(struct mapped_device *md, bool remove_all) 470 { 471 char *device_table_data, *dev_name = NULL, *dev_uuid = NULL, *capacity_str = NULL; 472 char active_table_str[] = "active_table_hash="; 473 char inactive_table_str[] = "inactive_table_hash="; 474 char device_active_str[] = "device_active_metadata="; 475 char device_inactive_str[] = "device_inactive_metadata="; 476 char remove_all_str[] = "remove_all="; 477 unsigned int active_table_len = strlen(active_table_str); 478 unsigned int inactive_table_len = strlen(inactive_table_str); 479 unsigned int device_active_len = strlen(device_active_str); 480 unsigned int device_inactive_len = strlen(device_inactive_str); 481 unsigned int remove_all_len = strlen(remove_all_str); 482 unsigned int l = 0; 483 bool noio = true; 484 bool nodata = true; 485 int capacity_len; 486 487 device_table_data = dm_ima_alloc(DM_IMA_DEVICE_BUF_LEN*2, noio); 488 if (!device_table_data) 489 goto exit; 490 491 capacity_len = dm_ima_alloc_and_copy_capacity_str(md, &capacity_str, noio); 492 if (capacity_len < 0) { 493 kfree(device_table_data); 494 goto exit; 495 } 496 497 memcpy(device_table_data + l, DM_IMA_VERSION_STR, md->ima.dm_version_str_len); 498 l += md->ima.dm_version_str_len; 499 500 if (md->ima.active_table.device_metadata) { 501 memcpy(device_table_data + l, device_active_str, device_active_len); 502 l += device_active_len; 503 504 memcpy(device_table_data + l, md->ima.active_table.device_metadata, 505 md->ima.active_table.device_metadata_len); 506 l += md->ima.active_table.device_metadata_len; 507 508 nodata = false; 509 } 510 511 if (md->ima.inactive_table.device_metadata) { 512 memcpy(device_table_data + l, device_inactive_str, device_inactive_len); 513 l += device_inactive_len; 514 515 memcpy(device_table_data + l, md->ima.inactive_table.device_metadata, 516 md->ima.inactive_table.device_metadata_len); 517 l += md->ima.inactive_table.device_metadata_len; 518 519 nodata = false; 520 } 521 522 if (md->ima.active_table.hash) { 523 memcpy(device_table_data + l, active_table_str, active_table_len); 524 l += active_table_len; 525 526 memcpy(device_table_data + l, md->ima.active_table.hash, 527 md->ima.active_table.hash_len); 528 l += md->ima.active_table.hash_len; 529 530 memcpy(device_table_data + l, ",", 1); 531 l++; 532 533 nodata = false; 534 } 535 536 if (md->ima.inactive_table.hash) { 537 memcpy(device_table_data + l, inactive_table_str, inactive_table_len); 538 l += inactive_table_len; 539 540 memcpy(device_table_data + l, md->ima.inactive_table.hash, 541 md->ima.inactive_table.hash_len); 542 l += md->ima.inactive_table.hash_len; 543 544 memcpy(device_table_data + l, ",", 1); 545 l++; 546 547 nodata = false; 548 } 549 /* 550 * In case both active and inactive tables, and corresponding 551 * device metadata is cleared/missing - record the name and uuid 552 * in IMA measurements. 553 */ 554 if (nodata) { 555 if (dm_ima_alloc_and_copy_name_uuid(md, &dev_name, &dev_uuid, noio)) 556 goto error; 557 558 l = scnprintf(device_table_data, DM_IMA_DEVICE_BUF_LEN, 559 "%sname=%s,uuid=%s;device_remove=no_data;", 560 DM_IMA_VERSION_STR, dev_name, dev_uuid); 561 } 562 563 memcpy(device_table_data + l, remove_all_str, remove_all_len); 564 l += remove_all_len; 565 memcpy(device_table_data + l, remove_all ? "y;" : "n;", 2); 566 l += 2; 567 568 memcpy(device_table_data + l, capacity_str, capacity_len); 569 l += capacity_len; 570 571 dm_ima_measure_data("dm_device_remove", device_table_data, l, noio); 572 573 error: 574 kfree(device_table_data); 575 kfree(capacity_str); 576 exit: 577 kfree(md->ima.active_table.device_metadata); 578 579 if (md->ima.active_table.device_metadata != 580 md->ima.inactive_table.device_metadata) 581 kfree(md->ima.inactive_table.device_metadata); 582 583 kfree(md->ima.active_table.hash); 584 585 if (md->ima.active_table.hash != md->ima.inactive_table.hash) 586 kfree(md->ima.inactive_table.hash); 587 588 dm_ima_reset_data(md); 589 590 kfree(dev_name); 591 kfree(dev_uuid); 592 } 593 594 /* 595 * Measure ima data on table clear. 596 */ 597 void dm_ima_measure_on_table_clear(struct mapped_device *md, bool new_map) 598 { 599 unsigned int l = 0; 600 char *device_table_data = NULL, *dev_name = NULL, *dev_uuid = NULL, *capacity_str = NULL; 601 char inactive_str[] = "inactive_table_hash="; 602 unsigned int inactive_len = strlen(inactive_str); 603 bool noio = true; 604 bool nodata = true; 605 int capacity_len; 606 607 device_table_data = dm_ima_alloc(DM_IMA_DEVICE_BUF_LEN, noio); 608 if (!device_table_data) 609 return; 610 611 capacity_len = dm_ima_alloc_and_copy_capacity_str(md, &capacity_str, noio); 612 if (capacity_len < 0) 613 goto error1; 614 615 memcpy(device_table_data + l, DM_IMA_VERSION_STR, md->ima.dm_version_str_len); 616 l += md->ima.dm_version_str_len; 617 618 if (md->ima.inactive_table.device_metadata_len && 619 md->ima.inactive_table.hash_len) { 620 memcpy(device_table_data + l, md->ima.inactive_table.device_metadata, 621 md->ima.inactive_table.device_metadata_len); 622 l += md->ima.inactive_table.device_metadata_len; 623 624 memcpy(device_table_data + l, inactive_str, inactive_len); 625 l += inactive_len; 626 627 memcpy(device_table_data + l, md->ima.inactive_table.hash, 628 md->ima.inactive_table.hash_len); 629 630 l += md->ima.inactive_table.hash_len; 631 632 memcpy(device_table_data + l, ";", 1); 633 l++; 634 635 nodata = false; 636 } 637 638 if (nodata) { 639 if (dm_ima_alloc_and_copy_name_uuid(md, &dev_name, &dev_uuid, noio)) 640 goto error2; 641 642 l = scnprintf(device_table_data, DM_IMA_DEVICE_BUF_LEN, 643 "%sname=%s,uuid=%s;table_clear=no_data;", 644 DM_IMA_VERSION_STR, dev_name, dev_uuid); 645 } 646 647 memcpy(device_table_data + l, capacity_str, capacity_len); 648 l += capacity_len; 649 650 dm_ima_measure_data("dm_table_clear", device_table_data, l, noio); 651 652 if (new_map) { 653 if (md->ima.inactive_table.hash && 654 md->ima.inactive_table.hash != md->ima.active_table.hash) 655 kfree(md->ima.inactive_table.hash); 656 657 md->ima.inactive_table.hash = NULL; 658 md->ima.inactive_table.hash_len = 0; 659 660 if (md->ima.inactive_table.device_metadata && 661 md->ima.inactive_table.device_metadata != md->ima.active_table.device_metadata) 662 kfree(md->ima.inactive_table.device_metadata); 663 664 md->ima.inactive_table.device_metadata = NULL; 665 md->ima.inactive_table.device_metadata_len = 0; 666 md->ima.inactive_table.num_targets = 0; 667 668 if (md->ima.active_table.hash) { 669 md->ima.inactive_table.hash = md->ima.active_table.hash; 670 md->ima.inactive_table.hash_len = md->ima.active_table.hash_len; 671 } 672 673 if (md->ima.active_table.device_metadata) { 674 md->ima.inactive_table.device_metadata = 675 md->ima.active_table.device_metadata; 676 md->ima.inactive_table.device_metadata_len = 677 md->ima.active_table.device_metadata_len; 678 md->ima.inactive_table.num_targets = 679 md->ima.active_table.num_targets; 680 } 681 } 682 683 kfree(dev_name); 684 kfree(dev_uuid); 685 error2: 686 kfree(capacity_str); 687 error1: 688 kfree(device_table_data); 689 } 690 691 /* 692 * Measure IMA data on device rename. 693 */ 694 void dm_ima_measure_on_device_rename(struct mapped_device *md) 695 { 696 char *old_device_data = NULL, *new_device_data = NULL, *combined_device_data = NULL; 697 char *new_dev_name = NULL, *new_dev_uuid = NULL, *capacity_str = NULL; 698 bool noio = true; 699 int len; 700 701 if (dm_ima_alloc_and_copy_device_data(md, &new_device_data, 702 md->ima.active_table.num_targets, noio)) 703 return; 704 705 if (dm_ima_alloc_and_copy_name_uuid(md, &new_dev_name, &new_dev_uuid, noio)) 706 goto error; 707 708 combined_device_data = dm_ima_alloc(DM_IMA_DEVICE_BUF_LEN * 2, noio); 709 if (!combined_device_data) 710 goto error; 711 712 if (dm_ima_alloc_and_copy_capacity_str(md, &capacity_str, noio) < 0) 713 goto error; 714 715 old_device_data = md->ima.active_table.device_metadata; 716 717 md->ima.active_table.device_metadata = new_device_data; 718 md->ima.active_table.device_metadata_len = strlen(new_device_data); 719 720 len = scnprintf(combined_device_data, DM_IMA_DEVICE_BUF_LEN * 2, 721 "%s%snew_name=%s,new_uuid=%s;%s", DM_IMA_VERSION_STR, old_device_data, 722 new_dev_name, new_dev_uuid, capacity_str); 723 724 dm_ima_measure_data("dm_device_rename", combined_device_data, len, noio); 725 726 goto exit; 727 728 error: 729 kfree(new_device_data); 730 exit: 731 kfree(capacity_str); 732 kfree(combined_device_data); 733 kfree(old_device_data); 734 kfree(new_dev_name); 735 kfree(new_dev_uuid); 736 } 737