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 = dm_table_get_num_targets(table); 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 if (!ti) 241 goto error; 242 243 last_target_measured = 0; 244 245 /* 246 * First retrieve the target metadata. 247 */ 248 scnprintf(target_metadata_buf, DM_IMA_TARGET_METADATA_BUF_LEN, 249 "target_index=%d,target_begin=%llu,target_len=%llu,", 250 i, ti->begin, ti->len); 251 target_metadata_buf_len = strlen(target_metadata_buf); 252 253 /* 254 * Then retrieve the actual target data. 255 */ 256 if (ti->type->status) 257 ti->type->status(ti, type, status_flags, target_data_buf, 258 DM_IMA_TARGET_DATA_BUF_LEN); 259 else 260 target_data_buf[0] = '\0'; 261 262 target_data_buf_len = strlen(target_data_buf); 263 264 /* 265 * Check if the total data can fit into the IMA buffer. 266 */ 267 cur_total_buf_len = l + target_metadata_buf_len + target_data_buf_len; 268 269 /* 270 * IMA measurements for DM targets are best-effort. 271 * If the total data buffered so far, including the current target, 272 * is too large to fit into DM_IMA_MEASUREMENT_BUF_LEN, measure what 273 * we have in the current buffer, and continue measuring the remaining 274 * targets by prefixing the device metadata again. 275 */ 276 if (unlikely(cur_total_buf_len >= DM_IMA_MEASUREMENT_BUF_LEN)) { 277 dm_ima_measure_data(table_load_event_name, ima_buf, l, noio); 278 r = crypto_shash_update(shash, (const u8 *)ima_buf, l); 279 if (r < 0) 280 goto error; 281 282 memset(ima_buf, 0, DM_IMA_MEASUREMENT_BUF_LEN); 283 l = 0; 284 285 /* 286 * Each new "dm_table_load" entry in IMA log should have device data 287 * prefix, so that multiple records from the same "dm_table_load" for 288 * a given device can be linked together. 289 */ 290 memcpy(ima_buf + l, DM_IMA_VERSION_STR, table->md->ima.dm_version_str_len); 291 l += table->md->ima.dm_version_str_len; 292 293 memcpy(ima_buf + l, device_data_buf, device_data_buf_len); 294 l += device_data_buf_len; 295 296 /* 297 * If this iteration of the for loop turns out to be the last target 298 * in the table, dm_ima_measure_data("dm_table_load", ...) doesn't need 299 * to be called again, just the hash needs to be finalized. 300 * "last_target_measured" tracks this state. 301 */ 302 last_target_measured = 1; 303 } 304 305 /* 306 * Fill-in all the target metadata, so that multiple targets for the same 307 * device can be linked together. 308 */ 309 memcpy(ima_buf + l, target_metadata_buf, target_metadata_buf_len); 310 l += target_metadata_buf_len; 311 312 memcpy(ima_buf + l, target_data_buf, target_data_buf_len); 313 l += target_data_buf_len; 314 } 315 316 if (!last_target_measured) { 317 dm_ima_measure_data(table_load_event_name, ima_buf, l, noio); 318 319 r = crypto_shash_update(shash, (const u8 *)ima_buf, l); 320 if (r < 0) 321 goto error; 322 } 323 324 /* 325 * Finalize the table hash, and store it in table->md->ima.inactive_table.hash, 326 * so that the table data can be verified against the future device state change 327 * events, e.g. resume, rename, remove, table-clear etc. 328 */ 329 r = crypto_shash_final(shash, digest); 330 if (r < 0) 331 goto error; 332 333 digest_buf = dm_ima_alloc((digest_size*2) + hash_alg_prefix_len + 1, GFP_KERNEL, noio); 334 335 if (!digest_buf) 336 goto error; 337 338 snprintf(digest_buf, hash_alg_prefix_len + 1, "%s:", DM_IMA_TABLE_HASH_ALG); 339 340 for (i = 0; i < digest_size; i++) 341 snprintf((digest_buf + hash_alg_prefix_len + (i*2)), 3, "%02x", digest[i]); 342 343 if (table->md->ima.active_table.hash != table->md->ima.inactive_table.hash) 344 kfree(table->md->ima.inactive_table.hash); 345 346 table->md->ima.inactive_table.hash = digest_buf; 347 table->md->ima.inactive_table.hash_len = strlen(digest_buf); 348 table->md->ima.inactive_table.num_targets = num_targets; 349 350 if (table->md->ima.active_table.device_metadata != 351 table->md->ima.inactive_table.device_metadata) 352 kfree(table->md->ima.inactive_table.device_metadata); 353 354 table->md->ima.inactive_table.device_metadata = device_data_buf; 355 table->md->ima.inactive_table.device_metadata_len = device_data_buf_len; 356 357 goto exit; 358 error: 359 kfree(digest_buf); 360 kfree(device_data_buf); 361 exit: 362 kfree(digest); 363 if (tfm) 364 crypto_free_shash(tfm); 365 kfree(ima_buf); 366 kfree(target_metadata_buf); 367 kfree(target_data_buf); 368 } 369 370 /* 371 * Measure IMA data on device resume. 372 */ 373 void dm_ima_measure_on_device_resume(struct mapped_device *md, bool swap) 374 { 375 char *device_table_data, *dev_name = NULL, *dev_uuid = NULL, *capacity_str = NULL; 376 char active[] = "active_table_hash="; 377 unsigned int active_len = strlen(active), capacity_len = 0; 378 unsigned int l = 0; 379 bool noio = true; 380 bool nodata = true; 381 int r; 382 383 device_table_data = dm_ima_alloc(DM_IMA_DEVICE_BUF_LEN, GFP_KERNEL, noio); 384 if (!device_table_data) 385 return; 386 387 r = dm_ima_alloc_and_copy_capacity_str(md, &capacity_str, noio); 388 if (r) 389 goto error; 390 391 memcpy(device_table_data + l, DM_IMA_VERSION_STR, md->ima.dm_version_str_len); 392 l += md->ima.dm_version_str_len; 393 394 if (swap) { 395 if (md->ima.active_table.hash != md->ima.inactive_table.hash) 396 kfree(md->ima.active_table.hash); 397 398 md->ima.active_table.hash = NULL; 399 md->ima.active_table.hash_len = 0; 400 401 if (md->ima.active_table.device_metadata != 402 md->ima.inactive_table.device_metadata) 403 kfree(md->ima.active_table.device_metadata); 404 405 md->ima.active_table.device_metadata = NULL; 406 md->ima.active_table.device_metadata_len = 0; 407 md->ima.active_table.num_targets = 0; 408 409 if (md->ima.inactive_table.hash) { 410 md->ima.active_table.hash = md->ima.inactive_table.hash; 411 md->ima.active_table.hash_len = md->ima.inactive_table.hash_len; 412 md->ima.inactive_table.hash = NULL; 413 md->ima.inactive_table.hash_len = 0; 414 } 415 416 if (md->ima.inactive_table.device_metadata) { 417 md->ima.active_table.device_metadata = 418 md->ima.inactive_table.device_metadata; 419 md->ima.active_table.device_metadata_len = 420 md->ima.inactive_table.device_metadata_len; 421 md->ima.active_table.num_targets = md->ima.inactive_table.num_targets; 422 md->ima.inactive_table.device_metadata = NULL; 423 md->ima.inactive_table.device_metadata_len = 0; 424 md->ima.inactive_table.num_targets = 0; 425 } 426 } 427 428 if (md->ima.active_table.device_metadata) { 429 memcpy(device_table_data + l, md->ima.active_table.device_metadata, 430 md->ima.active_table.device_metadata_len); 431 l += md->ima.active_table.device_metadata_len; 432 433 nodata = false; 434 } 435 436 if (md->ima.active_table.hash) { 437 memcpy(device_table_data + l, active, active_len); 438 l += active_len; 439 440 memcpy(device_table_data + l, md->ima.active_table.hash, 441 md->ima.active_table.hash_len); 442 l += md->ima.active_table.hash_len; 443 444 memcpy(device_table_data + l, ";", 1); 445 l++; 446 447 nodata = false; 448 } 449 450 if (nodata) { 451 r = dm_ima_alloc_and_copy_name_uuid(md, &dev_name, &dev_uuid, noio); 452 if (r) 453 goto error; 454 455 scnprintf(device_table_data, DM_IMA_DEVICE_BUF_LEN, 456 "%sname=%s,uuid=%s;device_resume=no_data;", 457 DM_IMA_VERSION_STR, dev_name, dev_uuid); 458 l += strlen(device_table_data); 459 460 } 461 462 capacity_len = strlen(capacity_str); 463 memcpy(device_table_data + l, capacity_str, capacity_len); 464 l += capacity_len; 465 466 dm_ima_measure_data("dm_device_resume", device_table_data, l, noio); 467 468 kfree(dev_name); 469 kfree(dev_uuid); 470 error: 471 kfree(capacity_str); 472 kfree(device_table_data); 473 } 474 475 /* 476 * Measure IMA data on remove. 477 */ 478 void dm_ima_measure_on_device_remove(struct mapped_device *md, bool remove_all) 479 { 480 char *device_table_data, *dev_name = NULL, *dev_uuid = NULL, *capacity_str = NULL; 481 char active_table_str[] = "active_table_hash="; 482 char inactive_table_str[] = "inactive_table_hash="; 483 char device_active_str[] = "device_active_metadata="; 484 char device_inactive_str[] = "device_inactive_metadata="; 485 char remove_all_str[] = "remove_all="; 486 unsigned int active_table_len = strlen(active_table_str); 487 unsigned int inactive_table_len = strlen(inactive_table_str); 488 unsigned int device_active_len = strlen(device_active_str); 489 unsigned int device_inactive_len = strlen(device_inactive_str); 490 unsigned int remove_all_len = strlen(remove_all_str); 491 unsigned int capacity_len = 0; 492 unsigned int l = 0; 493 bool noio = true; 494 bool nodata = true; 495 int r; 496 497 device_table_data = dm_ima_alloc(DM_IMA_DEVICE_BUF_LEN*2, GFP_KERNEL, noio); 498 if (!device_table_data) 499 goto exit; 500 501 r = dm_ima_alloc_and_copy_capacity_str(md, &capacity_str, noio); 502 if (r) { 503 kfree(device_table_data); 504 goto exit; 505 } 506 507 memcpy(device_table_data + l, DM_IMA_VERSION_STR, md->ima.dm_version_str_len); 508 l += md->ima.dm_version_str_len; 509 510 if (md->ima.active_table.device_metadata) { 511 memcpy(device_table_data + l, device_active_str, device_active_len); 512 l += device_active_len; 513 514 memcpy(device_table_data + l, md->ima.active_table.device_metadata, 515 md->ima.active_table.device_metadata_len); 516 l += md->ima.active_table.device_metadata_len; 517 518 nodata = false; 519 } 520 521 if (md->ima.inactive_table.device_metadata) { 522 memcpy(device_table_data + l, device_inactive_str, device_inactive_len); 523 l += device_inactive_len; 524 525 memcpy(device_table_data + l, md->ima.inactive_table.device_metadata, 526 md->ima.inactive_table.device_metadata_len); 527 l += md->ima.inactive_table.device_metadata_len; 528 529 nodata = false; 530 } 531 532 if (md->ima.active_table.hash) { 533 memcpy(device_table_data + l, active_table_str, active_table_len); 534 l += active_table_len; 535 536 memcpy(device_table_data + l, md->ima.active_table.hash, 537 md->ima.active_table.hash_len); 538 l += md->ima.active_table.hash_len; 539 540 memcpy(device_table_data + l, ",", 1); 541 l++; 542 543 nodata = false; 544 } 545 546 if (md->ima.inactive_table.hash) { 547 memcpy(device_table_data + l, inactive_table_str, inactive_table_len); 548 l += inactive_table_len; 549 550 memcpy(device_table_data + l, md->ima.inactive_table.hash, 551 md->ima.inactive_table.hash_len); 552 l += md->ima.inactive_table.hash_len; 553 554 memcpy(device_table_data + l, ",", 1); 555 l++; 556 557 nodata = false; 558 } 559 /* 560 * In case both active and inactive tables, and corresponding 561 * device metadata is cleared/missing - record the name and uuid 562 * in IMA measurements. 563 */ 564 if (nodata) { 565 if (dm_ima_alloc_and_copy_name_uuid(md, &dev_name, &dev_uuid, noio)) 566 goto error; 567 568 scnprintf(device_table_data, DM_IMA_DEVICE_BUF_LEN, 569 "%sname=%s,uuid=%s;device_remove=no_data;", 570 DM_IMA_VERSION_STR, dev_name, dev_uuid); 571 l += strlen(device_table_data); 572 } 573 574 memcpy(device_table_data + l, remove_all_str, remove_all_len); 575 l += remove_all_len; 576 memcpy(device_table_data + l, remove_all ? "y;" : "n;", 2); 577 l += 2; 578 579 capacity_len = strlen(capacity_str); 580 memcpy(device_table_data + l, capacity_str, capacity_len); 581 l += capacity_len; 582 583 dm_ima_measure_data("dm_device_remove", device_table_data, l, noio); 584 585 error: 586 kfree(device_table_data); 587 kfree(capacity_str); 588 exit: 589 kfree(md->ima.active_table.device_metadata); 590 591 if (md->ima.active_table.device_metadata != 592 md->ima.inactive_table.device_metadata) 593 kfree(md->ima.inactive_table.device_metadata); 594 595 kfree(md->ima.active_table.hash); 596 597 if (md->ima.active_table.hash != md->ima.inactive_table.hash) 598 kfree(md->ima.inactive_table.hash); 599 600 dm_ima_reset_data(md); 601 602 kfree(dev_name); 603 kfree(dev_uuid); 604 } 605 606 /* 607 * Measure ima data on table clear. 608 */ 609 void dm_ima_measure_on_table_clear(struct mapped_device *md, bool new_map) 610 { 611 unsigned int l = 0, capacity_len = 0; 612 char *device_table_data = NULL, *dev_name = NULL, *dev_uuid = NULL, *capacity_str = NULL; 613 char inactive_str[] = "inactive_table_hash="; 614 unsigned int inactive_len = strlen(inactive_str); 615 bool noio = true; 616 bool nodata = true; 617 int r; 618 619 device_table_data = dm_ima_alloc(DM_IMA_DEVICE_BUF_LEN, GFP_KERNEL, noio); 620 if (!device_table_data) 621 return; 622 623 r = dm_ima_alloc_and_copy_capacity_str(md, &capacity_str, noio); 624 if (r) 625 goto error1; 626 627 memcpy(device_table_data + l, DM_IMA_VERSION_STR, md->ima.dm_version_str_len); 628 l += md->ima.dm_version_str_len; 629 630 if (md->ima.inactive_table.device_metadata_len && 631 md->ima.inactive_table.hash_len) { 632 memcpy(device_table_data + l, md->ima.inactive_table.device_metadata, 633 md->ima.inactive_table.device_metadata_len); 634 l += md->ima.inactive_table.device_metadata_len; 635 636 memcpy(device_table_data + l, inactive_str, inactive_len); 637 l += inactive_len; 638 639 memcpy(device_table_data + l, md->ima.inactive_table.hash, 640 md->ima.inactive_table.hash_len); 641 642 l += md->ima.inactive_table.hash_len; 643 644 memcpy(device_table_data + l, ";", 1); 645 l++; 646 647 nodata = false; 648 } 649 650 if (nodata) { 651 if (dm_ima_alloc_and_copy_name_uuid(md, &dev_name, &dev_uuid, noio)) 652 goto error2; 653 654 scnprintf(device_table_data, DM_IMA_DEVICE_BUF_LEN, 655 "%sname=%s,uuid=%s;table_clear=no_data;", 656 DM_IMA_VERSION_STR, dev_name, dev_uuid); 657 l += strlen(device_table_data); 658 } 659 660 capacity_len = strlen(capacity_str); 661 memcpy(device_table_data + l, capacity_str, capacity_len); 662 l += capacity_len; 663 664 dm_ima_measure_data("dm_table_clear", device_table_data, l, noio); 665 666 if (new_map) { 667 if (md->ima.inactive_table.hash && 668 md->ima.inactive_table.hash != md->ima.active_table.hash) 669 kfree(md->ima.inactive_table.hash); 670 671 md->ima.inactive_table.hash = NULL; 672 md->ima.inactive_table.hash_len = 0; 673 674 if (md->ima.inactive_table.device_metadata && 675 md->ima.inactive_table.device_metadata != md->ima.active_table.device_metadata) 676 kfree(md->ima.inactive_table.device_metadata); 677 678 md->ima.inactive_table.device_metadata = NULL; 679 md->ima.inactive_table.device_metadata_len = 0; 680 md->ima.inactive_table.num_targets = 0; 681 682 if (md->ima.active_table.hash) { 683 md->ima.inactive_table.hash = md->ima.active_table.hash; 684 md->ima.inactive_table.hash_len = md->ima.active_table.hash_len; 685 } 686 687 if (md->ima.active_table.device_metadata) { 688 md->ima.inactive_table.device_metadata = 689 md->ima.active_table.device_metadata; 690 md->ima.inactive_table.device_metadata_len = 691 md->ima.active_table.device_metadata_len; 692 md->ima.inactive_table.num_targets = 693 md->ima.active_table.num_targets; 694 } 695 } 696 697 kfree(dev_name); 698 kfree(dev_uuid); 699 error2: 700 kfree(capacity_str); 701 error1: 702 kfree(device_table_data); 703 } 704 705 /* 706 * Measure IMA data on device rename. 707 */ 708 void dm_ima_measure_on_device_rename(struct mapped_device *md) 709 { 710 char *old_device_data = NULL, *new_device_data = NULL, *combined_device_data = NULL; 711 char *new_dev_name = NULL, *new_dev_uuid = NULL, *capacity_str = NULL; 712 bool noio = true; 713 int r; 714 715 if (dm_ima_alloc_and_copy_device_data(md, &new_device_data, 716 md->ima.active_table.num_targets, noio)) 717 return; 718 719 if (dm_ima_alloc_and_copy_name_uuid(md, &new_dev_name, &new_dev_uuid, noio)) 720 goto error; 721 722 combined_device_data = dm_ima_alloc(DM_IMA_DEVICE_BUF_LEN * 2, GFP_KERNEL, noio); 723 if (!combined_device_data) 724 goto error; 725 726 r = dm_ima_alloc_and_copy_capacity_str(md, &capacity_str, noio); 727 if (r) 728 goto error; 729 730 old_device_data = md->ima.active_table.device_metadata; 731 732 md->ima.active_table.device_metadata = new_device_data; 733 md->ima.active_table.device_metadata_len = strlen(new_device_data); 734 735 scnprintf(combined_device_data, DM_IMA_DEVICE_BUF_LEN * 2, 736 "%s%snew_name=%s,new_uuid=%s;%s", DM_IMA_VERSION_STR, old_device_data, 737 new_dev_name, new_dev_uuid, capacity_str); 738 739 dm_ima_measure_data("dm_device_rename", combined_device_data, strlen(combined_device_data), 740 noio); 741 742 goto exit; 743 744 error: 745 kfree(new_device_data); 746 exit: 747 kfree(capacity_str); 748 kfree(combined_device_data); 749 kfree(old_device_data); 750 kfree(new_dev_name); 751 kfree(new_dev_uuid); 752 } 753