diff options
author | Dan Williams <dan.j.williams@intel.com> | 2019-08-26 20:55:05 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2019-08-29 16:51:57 -0400 |
commit | 7b60422cb796d40431337becf2129fd9944b2f05 (patch) | |
tree | 50cacd59a7d6691b0c2ff43a7705dcc46c2d98e5 | |
parent | bc4f2199ca3107809df96cf72f618b9559b00a21 (diff) |
libnvdimm/security: Consolidate 'security' operations
The security operations are exported from libnvdimm/security.c to
libnvdimm/dimm_devs.c, and libnvdimm/security.c is optionally compiled
based on the CONFIG_NVDIMM_KEYS config symbol.
Rather than export the operations across compile objects, just move the
__security_store() entry point to live with the helpers.
Acked-by: Jeff Moyer <jmoyer@redhat.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Link: https://lore.kernel.org/r/156686730515.184120.10522747907309996674.stgit@dwillia2-desk3.amr.corp.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r-- | drivers/nvdimm/dimm_devs.c | 84 | ||||
-rw-r--r-- | drivers/nvdimm/nd-core.h | 30 | ||||
-rw-r--r-- | drivers/nvdimm/security.c | 90 |
3 files changed, 90 insertions, 114 deletions
diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c index d837cb9be83d..196aa44c4936 100644 --- a/drivers/nvdimm/dimm_devs.c +++ b/drivers/nvdimm/dimm_devs.c | |||
@@ -393,88 +393,6 @@ static ssize_t frozen_show(struct device *dev, | |||
393 | } | 393 | } |
394 | static DEVICE_ATTR_RO(frozen); | 394 | static DEVICE_ATTR_RO(frozen); |
395 | 395 | ||
396 | #define OPS \ | ||
397 | C( OP_FREEZE, "freeze", 1), \ | ||
398 | C( OP_DISABLE, "disable", 2), \ | ||
399 | C( OP_UPDATE, "update", 3), \ | ||
400 | C( OP_ERASE, "erase", 2), \ | ||
401 | C( OP_OVERWRITE, "overwrite", 2), \ | ||
402 | C( OP_MASTER_UPDATE, "master_update", 3), \ | ||
403 | C( OP_MASTER_ERASE, "master_erase", 2) | ||
404 | #undef C | ||
405 | #define C(a, b, c) a | ||
406 | enum nvdimmsec_op_ids { OPS }; | ||
407 | #undef C | ||
408 | #define C(a, b, c) { b, c } | ||
409 | static struct { | ||
410 | const char *name; | ||
411 | int args; | ||
412 | } ops[] = { OPS }; | ||
413 | #undef C | ||
414 | |||
415 | #define SEC_CMD_SIZE 32 | ||
416 | #define KEY_ID_SIZE 10 | ||
417 | |||
418 | static ssize_t __security_store(struct device *dev, const char *buf, size_t len) | ||
419 | { | ||
420 | struct nvdimm *nvdimm = to_nvdimm(dev); | ||
421 | ssize_t rc; | ||
422 | char cmd[SEC_CMD_SIZE+1], keystr[KEY_ID_SIZE+1], | ||
423 | nkeystr[KEY_ID_SIZE+1]; | ||
424 | unsigned int key, newkey; | ||
425 | int i; | ||
426 | |||
427 | rc = sscanf(buf, "%"__stringify(SEC_CMD_SIZE)"s" | ||
428 | " %"__stringify(KEY_ID_SIZE)"s" | ||
429 | " %"__stringify(KEY_ID_SIZE)"s", | ||
430 | cmd, keystr, nkeystr); | ||
431 | if (rc < 1) | ||
432 | return -EINVAL; | ||
433 | for (i = 0; i < ARRAY_SIZE(ops); i++) | ||
434 | if (sysfs_streq(cmd, ops[i].name)) | ||
435 | break; | ||
436 | if (i >= ARRAY_SIZE(ops)) | ||
437 | return -EINVAL; | ||
438 | if (ops[i].args > 1) | ||
439 | rc = kstrtouint(keystr, 0, &key); | ||
440 | if (rc >= 0 && ops[i].args > 2) | ||
441 | rc = kstrtouint(nkeystr, 0, &newkey); | ||
442 | if (rc < 0) | ||
443 | return rc; | ||
444 | |||
445 | if (i == OP_FREEZE) { | ||
446 | dev_dbg(dev, "freeze\n"); | ||
447 | rc = nvdimm_security_freeze(nvdimm); | ||
448 | } else if (i == OP_DISABLE) { | ||
449 | dev_dbg(dev, "disable %u\n", key); | ||
450 | rc = nvdimm_security_disable(nvdimm, key); | ||
451 | } else if (i == OP_UPDATE || i == OP_MASTER_UPDATE) { | ||
452 | dev_dbg(dev, "%s %u %u\n", ops[i].name, key, newkey); | ||
453 | rc = nvdimm_security_update(nvdimm, key, newkey, i == OP_UPDATE | ||
454 | ? NVDIMM_USER : NVDIMM_MASTER); | ||
455 | } else if (i == OP_ERASE || i == OP_MASTER_ERASE) { | ||
456 | dev_dbg(dev, "%s %u\n", ops[i].name, key); | ||
457 | if (atomic_read(&nvdimm->busy)) { | ||
458 | dev_dbg(dev, "Unable to secure erase while DIMM active.\n"); | ||
459 | return -EBUSY; | ||
460 | } | ||
461 | rc = nvdimm_security_erase(nvdimm, key, i == OP_ERASE | ||
462 | ? NVDIMM_USER : NVDIMM_MASTER); | ||
463 | } else if (i == OP_OVERWRITE) { | ||
464 | dev_dbg(dev, "overwrite %u\n", key); | ||
465 | if (atomic_read(&nvdimm->busy)) { | ||
466 | dev_dbg(dev, "Unable to overwrite while DIMM active.\n"); | ||
467 | return -EBUSY; | ||
468 | } | ||
469 | rc = nvdimm_security_overwrite(nvdimm, key); | ||
470 | } else | ||
471 | return -EINVAL; | ||
472 | |||
473 | if (rc == 0) | ||
474 | rc = len; | ||
475 | return rc; | ||
476 | } | ||
477 | |||
478 | static ssize_t security_store(struct device *dev, | 396 | static ssize_t security_store(struct device *dev, |
479 | struct device_attribute *attr, const char *buf, size_t len) | 397 | struct device_attribute *attr, const char *buf, size_t len) |
480 | 398 | ||
@@ -489,7 +407,7 @@ static ssize_t security_store(struct device *dev, | |||
489 | nd_device_lock(dev); | 407 | nd_device_lock(dev); |
490 | nvdimm_bus_lock(dev); | 408 | nvdimm_bus_lock(dev); |
491 | wait_nvdimm_bus_probe_idle(dev); | 409 | wait_nvdimm_bus_probe_idle(dev); |
492 | rc = __security_store(dev, buf, len); | 410 | rc = nvdimm_security_store(dev, buf, len); |
493 | nvdimm_bus_unlock(dev); | 411 | nvdimm_bus_unlock(dev); |
494 | nd_device_unlock(dev); | 412 | nd_device_unlock(dev); |
495 | 413 | ||
diff --git a/drivers/nvdimm/nd-core.h b/drivers/nvdimm/nd-core.h index da2bbfd56d9f..454454ba1738 100644 --- a/drivers/nvdimm/nd-core.h +++ b/drivers/nvdimm/nd-core.h | |||
@@ -68,35 +68,11 @@ static inline unsigned long nvdimm_security_flags( | |||
68 | } | 68 | } |
69 | int nvdimm_security_freeze(struct nvdimm *nvdimm); | 69 | int nvdimm_security_freeze(struct nvdimm *nvdimm); |
70 | #if IS_ENABLED(CONFIG_NVDIMM_KEYS) | 70 | #if IS_ENABLED(CONFIG_NVDIMM_KEYS) |
71 | int nvdimm_security_disable(struct nvdimm *nvdimm, unsigned int keyid); | 71 | ssize_t nvdimm_security_store(struct device *dev, const char *buf, size_t len); |
72 | int nvdimm_security_update(struct nvdimm *nvdimm, unsigned int keyid, | ||
73 | unsigned int new_keyid, | ||
74 | enum nvdimm_passphrase_type pass_type); | ||
75 | int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned int keyid, | ||
76 | enum nvdimm_passphrase_type pass_type); | ||
77 | int nvdimm_security_overwrite(struct nvdimm *nvdimm, unsigned int keyid); | ||
78 | void nvdimm_security_overwrite_query(struct work_struct *work); | 72 | void nvdimm_security_overwrite_query(struct work_struct *work); |
79 | #else | 73 | #else |
80 | static inline int nvdimm_security_disable(struct nvdimm *nvdimm, | 74 | static inline ssize_t nvdimm_security_store(struct device *dev, |
81 | unsigned int keyid) | 75 | const char *buf, size_t len) |
82 | { | ||
83 | return -EOPNOTSUPP; | ||
84 | } | ||
85 | static inline int nvdimm_security_update(struct nvdimm *nvdimm, | ||
86 | unsigned int keyid, | ||
87 | unsigned int new_keyid, | ||
88 | enum nvdimm_passphrase_type pass_type) | ||
89 | { | ||
90 | return -EOPNOTSUPP; | ||
91 | } | ||
92 | static inline int nvdimm_security_erase(struct nvdimm *nvdimm, | ||
93 | unsigned int keyid, | ||
94 | enum nvdimm_passphrase_type pass_type) | ||
95 | { | ||
96 | return -EOPNOTSUPP; | ||
97 | } | ||
98 | static inline int nvdimm_security_overwrite(struct nvdimm *nvdimm, | ||
99 | unsigned int keyid) | ||
100 | { | 76 | { |
101 | return -EOPNOTSUPP; | 77 | return -EOPNOTSUPP; |
102 | } | 78 | } |
diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c index 2166e627383a..9e45b207ff01 100644 --- a/drivers/nvdimm/security.c +++ b/drivers/nvdimm/security.c | |||
@@ -235,7 +235,7 @@ static int check_security_state(struct nvdimm *nvdimm) | |||
235 | return 0; | 235 | return 0; |
236 | } | 236 | } |
237 | 237 | ||
238 | int nvdimm_security_disable(struct nvdimm *nvdimm, unsigned int keyid) | 238 | static int security_disable(struct nvdimm *nvdimm, unsigned int keyid) |
239 | { | 239 | { |
240 | struct device *dev = &nvdimm->dev; | 240 | struct device *dev = &nvdimm->dev; |
241 | struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); | 241 | struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); |
@@ -268,7 +268,7 @@ int nvdimm_security_disable(struct nvdimm *nvdimm, unsigned int keyid) | |||
268 | return rc; | 268 | return rc; |
269 | } | 269 | } |
270 | 270 | ||
271 | int nvdimm_security_update(struct nvdimm *nvdimm, unsigned int keyid, | 271 | static int security_update(struct nvdimm *nvdimm, unsigned int keyid, |
272 | unsigned int new_keyid, | 272 | unsigned int new_keyid, |
273 | enum nvdimm_passphrase_type pass_type) | 273 | enum nvdimm_passphrase_type pass_type) |
274 | { | 274 | { |
@@ -318,7 +318,7 @@ int nvdimm_security_update(struct nvdimm *nvdimm, unsigned int keyid, | |||
318 | return rc; | 318 | return rc; |
319 | } | 319 | } |
320 | 320 | ||
321 | int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned int keyid, | 321 | static int security_erase(struct nvdimm *nvdimm, unsigned int keyid, |
322 | enum nvdimm_passphrase_type pass_type) | 322 | enum nvdimm_passphrase_type pass_type) |
323 | { | 323 | { |
324 | struct device *dev = &nvdimm->dev; | 324 | struct device *dev = &nvdimm->dev; |
@@ -360,7 +360,7 @@ int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned int keyid, | |||
360 | return rc; | 360 | return rc; |
361 | } | 361 | } |
362 | 362 | ||
363 | int nvdimm_security_overwrite(struct nvdimm *nvdimm, unsigned int keyid) | 363 | static int security_overwrite(struct nvdimm *nvdimm, unsigned int keyid) |
364 | { | 364 | { |
365 | struct device *dev = &nvdimm->dev; | 365 | struct device *dev = &nvdimm->dev; |
366 | struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); | 366 | struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); |
@@ -465,3 +465,85 @@ void nvdimm_security_overwrite_query(struct work_struct *work) | |||
465 | __nvdimm_security_overwrite_query(nvdimm); | 465 | __nvdimm_security_overwrite_query(nvdimm); |
466 | nvdimm_bus_unlock(&nvdimm->dev); | 466 | nvdimm_bus_unlock(&nvdimm->dev); |
467 | } | 467 | } |
468 | |||
469 | #define OPS \ | ||
470 | C( OP_FREEZE, "freeze", 1), \ | ||
471 | C( OP_DISABLE, "disable", 2), \ | ||
472 | C( OP_UPDATE, "update", 3), \ | ||
473 | C( OP_ERASE, "erase", 2), \ | ||
474 | C( OP_OVERWRITE, "overwrite", 2), \ | ||
475 | C( OP_MASTER_UPDATE, "master_update", 3), \ | ||
476 | C( OP_MASTER_ERASE, "master_erase", 2) | ||
477 | #undef C | ||
478 | #define C(a, b, c) a | ||
479 | enum nvdimmsec_op_ids { OPS }; | ||
480 | #undef C | ||
481 | #define C(a, b, c) { b, c } | ||
482 | static struct { | ||
483 | const char *name; | ||
484 | int args; | ||
485 | } ops[] = { OPS }; | ||
486 | #undef C | ||
487 | |||
488 | #define SEC_CMD_SIZE 32 | ||
489 | #define KEY_ID_SIZE 10 | ||
490 | |||
491 | ssize_t nvdimm_security_store(struct device *dev, const char *buf, size_t len) | ||
492 | { | ||
493 | struct nvdimm *nvdimm = to_nvdimm(dev); | ||
494 | ssize_t rc; | ||
495 | char cmd[SEC_CMD_SIZE+1], keystr[KEY_ID_SIZE+1], | ||
496 | nkeystr[KEY_ID_SIZE+1]; | ||
497 | unsigned int key, newkey; | ||
498 | int i; | ||
499 | |||
500 | rc = sscanf(buf, "%"__stringify(SEC_CMD_SIZE)"s" | ||
501 | " %"__stringify(KEY_ID_SIZE)"s" | ||
502 | " %"__stringify(KEY_ID_SIZE)"s", | ||
503 | cmd, keystr, nkeystr); | ||
504 | if (rc < 1) | ||
505 | return -EINVAL; | ||
506 | for (i = 0; i < ARRAY_SIZE(ops); i++) | ||
507 | if (sysfs_streq(cmd, ops[i].name)) | ||
508 | break; | ||
509 | if (i >= ARRAY_SIZE(ops)) | ||
510 | return -EINVAL; | ||
511 | if (ops[i].args > 1) | ||
512 | rc = kstrtouint(keystr, 0, &key); | ||
513 | if (rc >= 0 && ops[i].args > 2) | ||
514 | rc = kstrtouint(nkeystr, 0, &newkey); | ||
515 | if (rc < 0) | ||
516 | return rc; | ||
517 | |||
518 | if (i == OP_FREEZE) { | ||
519 | dev_dbg(dev, "freeze\n"); | ||
520 | rc = nvdimm_security_freeze(nvdimm); | ||
521 | } else if (i == OP_DISABLE) { | ||
522 | dev_dbg(dev, "disable %u\n", key); | ||
523 | rc = security_disable(nvdimm, key); | ||
524 | } else if (i == OP_UPDATE || i == OP_MASTER_UPDATE) { | ||
525 | dev_dbg(dev, "%s %u %u\n", ops[i].name, key, newkey); | ||
526 | rc = security_update(nvdimm, key, newkey, i == OP_UPDATE | ||
527 | ? NVDIMM_USER : NVDIMM_MASTER); | ||
528 | } else if (i == OP_ERASE || i == OP_MASTER_ERASE) { | ||
529 | dev_dbg(dev, "%s %u\n", ops[i].name, key); | ||
530 | if (atomic_read(&nvdimm->busy)) { | ||
531 | dev_dbg(dev, "Unable to secure erase while DIMM active.\n"); | ||
532 | return -EBUSY; | ||
533 | } | ||
534 | rc = security_erase(nvdimm, key, i == OP_ERASE | ||
535 | ? NVDIMM_USER : NVDIMM_MASTER); | ||
536 | } else if (i == OP_OVERWRITE) { | ||
537 | dev_dbg(dev, "overwrite %u\n", key); | ||
538 | if (atomic_read(&nvdimm->busy)) { | ||
539 | dev_dbg(dev, "Unable to overwrite while DIMM active.\n"); | ||
540 | return -EBUSY; | ||
541 | } | ||
542 | rc = security_overwrite(nvdimm, key); | ||
543 | } else | ||
544 | return -EINVAL; | ||
545 | |||
546 | if (rc == 0) | ||
547 | rc = len; | ||
548 | return rc; | ||
549 | } | ||