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