Merge tag 'libnvdimm-fixes-5.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm

Pull libnvdimm fixes from Dan Williams:
"I debated holding this back for the v5.2 merge window due to the size
of the "zero-key" changes, but affected users would benefit from
having the fixes sooner. It did not make sense to change the zero-key
semantic in isolation for the "secure-erase" command, but instead
include it for all security commands.

The short background on the need for these changes is that some NVDIMM
platforms enable security with a default zero-key rather than let the
OS specify the initial key. This makes the security enabling that
landed in v5.0 unusable for some users.

Summary:

- Compatibility fix for nvdimm-security implementations with a
default zero-key.

- Miscellaneous small fixes for out-of-bound accesses, cleanup after
initialization failures, and missing debug messages"

* tag 'libnvdimm-fixes-5.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm:
tools/testing/nvdimm: Retain security state after overwrite
libnvdimm/pmem: fix a possible OOB access when read and write pmem
libnvdimm/security, acpi/nfit: unify zero-key for all security commands
libnvdimm/security: provide fix for secure-erase to use zero-key
libnvdimm/btt: Fix a kmemdup failure check
libnvdimm/namespace: Fix a potential NULL pointer dereference
acpi/nfit: Always dump _DSM output payload

+117 -71
+6 -6
drivers/acpi/nfit/core.c
··· 567 goto out; 568 } 569 570 if (call_pkg) { 571 call_pkg->nd_fw_size = out_obj->buffer.length; 572 memcpy(call_pkg->nd_payload + call_pkg->nd_size_in, ··· 590 *cmd_rc = 0; 591 return 0; 592 } 593 - 594 - dev_dbg(dev, "%s cmd: %s output length: %d\n", dimm_name, 595 - cmd_name, out_obj->buffer.length); 596 - print_hex_dump_debug(cmd_name, DUMP_PREFIX_OFFSET, 4, 4, 597 - out_obj->buffer.pointer, 598 - min_t(u32, 128, out_obj->buffer.length), true); 599 600 for (i = 0, offset = 0; i < desc->out_num; i++) { 601 u32 out_size = nd_cmd_out_size(nvdimm, cmd, desc, i, buf,
··· 567 goto out; 568 } 569 570 + dev_dbg(dev, "%s cmd: %s output length: %d\n", dimm_name, 571 + cmd_name, out_obj->buffer.length); 572 + print_hex_dump_debug(cmd_name, DUMP_PREFIX_OFFSET, 4, 4, 573 + out_obj->buffer.pointer, 574 + min_t(u32, 128, out_obj->buffer.length), true); 575 + 576 if (call_pkg) { 577 call_pkg->nd_fw_size = out_obj->buffer.length; 578 memcpy(call_pkg->nd_payload + call_pkg->nd_size_in, ··· 584 *cmd_rc = 0; 585 return 0; 586 } 587 588 for (i = 0, offset = 0; i < desc->out_num; i++) { 589 u32 out_size = nd_cmd_out_size(nvdimm, cmd, desc, i, buf,
+4 -6
drivers/acpi/nfit/intel.c
··· 122 if (!test_bit(cmd, &nfit_mem->dsm_mask)) 123 return -ENOTTY; 124 125 - if (old_data) 126 - memcpy(nd_cmd.cmd.old_pass, old_data->data, 127 - sizeof(nd_cmd.cmd.old_pass)); 128 memcpy(nd_cmd.cmd.new_pass, new_data->data, 129 sizeof(nd_cmd.cmd.new_pass)); 130 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL); ··· 335 336 /* flush all cache before we erase DIMM */ 337 nvdimm_invalidate_cache(); 338 - if (nkey) 339 - memcpy(nd_cmd.cmd.passphrase, nkey->data, 340 - sizeof(nd_cmd.cmd.passphrase)); 341 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL); 342 if (rc < 0) 343 return rc;
··· 122 if (!test_bit(cmd, &nfit_mem->dsm_mask)) 123 return -ENOTTY; 124 125 + memcpy(nd_cmd.cmd.old_pass, old_data->data, 126 + sizeof(nd_cmd.cmd.old_pass)); 127 memcpy(nd_cmd.cmd.new_pass, new_data->data, 128 sizeof(nd_cmd.cmd.new_pass)); 129 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL); ··· 336 337 /* flush all cache before we erase DIMM */ 338 nvdimm_invalidate_cache(); 339 + memcpy(nd_cmd.cmd.passphrase, nkey->data, 340 + sizeof(nd_cmd.cmd.passphrase)); 341 rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL); 342 if (rc < 0) 343 return rc;
+13 -5
drivers/nvdimm/btt_devs.c
··· 198 return NULL; 199 200 nd_btt->id = ida_simple_get(&nd_region->btt_ida, 0, 0, GFP_KERNEL); 201 - if (nd_btt->id < 0) { 202 - kfree(nd_btt); 203 - return NULL; 204 - } 205 206 nd_btt->lbasize = lbasize; 207 - if (uuid) 208 uuid = kmemdup(uuid, 16, GFP_KERNEL); 209 nd_btt->uuid = uuid; 210 dev = &nd_btt->dev; 211 dev_set_name(dev, "btt%d.%d", nd_region->id, nd_btt->id); ··· 221 return NULL; 222 } 223 return dev; 224 } 225 226 struct device *nd_btt_create(struct nd_region *nd_region)
··· 198 return NULL; 199 200 nd_btt->id = ida_simple_get(&nd_region->btt_ida, 0, 0, GFP_KERNEL); 201 + if (nd_btt->id < 0) 202 + goto out_nd_btt; 203 204 nd_btt->lbasize = lbasize; 205 + if (uuid) { 206 uuid = kmemdup(uuid, 16, GFP_KERNEL); 207 + if (!uuid) 208 + goto out_put_id; 209 + } 210 nd_btt->uuid = uuid; 211 dev = &nd_btt->dev; 212 dev_set_name(dev, "btt%d.%d", nd_region->id, nd_btt->id); ··· 220 return NULL; 221 } 222 return dev; 223 + 224 + out_put_id: 225 + ida_simple_remove(&nd_region->btt_ida, nd_btt->id); 226 + 227 + out_nd_btt: 228 + kfree(nd_btt); 229 + return NULL; 230 } 231 232 struct device *nd_btt_create(struct nd_region *nd_region)
+4 -1
drivers/nvdimm/namespace_devs.c
··· 2249 if (!nsblk->uuid) 2250 goto blk_err; 2251 memcpy(name, nd_label->name, NSLABEL_NAME_LEN); 2252 - if (name[0]) 2253 nsblk->alt_name = kmemdup(name, NSLABEL_NAME_LEN, 2254 GFP_KERNEL); 2255 res = nsblk_add_resource(nd_region, ndd, nsblk, 2256 __le64_to_cpu(nd_label->dpa)); 2257 if (!res)
··· 2249 if (!nsblk->uuid) 2250 goto blk_err; 2251 memcpy(name, nd_label->name, NSLABEL_NAME_LEN); 2252 + if (name[0]) { 2253 nsblk->alt_name = kmemdup(name, NSLABEL_NAME_LEN, 2254 GFP_KERNEL); 2255 + if (!nsblk->alt_name) 2256 + goto blk_err; 2257 + } 2258 res = nsblk_add_resource(nd_region, ndd, nsblk, 2259 __le64_to_cpu(nd_label->dpa)); 2260 if (!res)
+4 -4
drivers/nvdimm/pmem.c
··· 113 114 while (len) { 115 mem = kmap_atomic(page); 116 - chunk = min_t(unsigned int, len, PAGE_SIZE); 117 memcpy_flushcache(pmem_addr, mem + off, chunk); 118 kunmap_atomic(mem); 119 len -= chunk; 120 off = 0; 121 page++; 122 - pmem_addr += PAGE_SIZE; 123 } 124 } 125 ··· 132 133 while (len) { 134 mem = kmap_atomic(page); 135 - chunk = min_t(unsigned int, len, PAGE_SIZE); 136 rem = memcpy_mcsafe(mem + off, pmem_addr, chunk); 137 kunmap_atomic(mem); 138 if (rem) ··· 140 len -= chunk; 141 off = 0; 142 page++; 143 - pmem_addr += PAGE_SIZE; 144 } 145 return BLK_STS_OK; 146 }
··· 113 114 while (len) { 115 mem = kmap_atomic(page); 116 + chunk = min_t(unsigned int, len, PAGE_SIZE - off); 117 memcpy_flushcache(pmem_addr, mem + off, chunk); 118 kunmap_atomic(mem); 119 len -= chunk; 120 off = 0; 121 page++; 122 + pmem_addr += chunk; 123 } 124 } 125 ··· 132 133 while (len) { 134 mem = kmap_atomic(page); 135 + chunk = min_t(unsigned int, len, PAGE_SIZE - off); 136 rem = memcpy_mcsafe(mem + off, pmem_addr, chunk); 137 kunmap_atomic(mem); 138 if (rem) ··· 140 len -= chunk; 141 off = 0; 142 page++; 143 + pmem_addr += chunk; 144 } 145 return BLK_STS_OK; 146 }
+73 -45
drivers/nvdimm/security.c
··· 22 module_param(key_revalidate, bool, 0444); 23 MODULE_PARM_DESC(key_revalidate, "Require key validation at init."); 24 25 static void *key_data(struct key *key) 26 { 27 struct encrypted_key_payload *epayload = dereference_key_locked(key); ··· 77 return key; 78 } 79 80 static struct key *nvdimm_lookup_user_key(struct nvdimm *nvdimm, 81 key_serial_t id, int subclass) 82 { ··· 117 return key; 118 } 119 120 - static struct key *nvdimm_key_revalidate(struct nvdimm *nvdimm) 121 { 122 struct key *key; 123 int rc; 124 125 if (!nvdimm->sec.ops->change_key) 126 - return NULL; 127 128 - key = nvdimm_request_key(nvdimm); 129 - if (!key) 130 - return NULL; 131 132 /* 133 * Send the same key to the hardware as new and old key to 134 * verify that the key is good. 135 */ 136 - rc = nvdimm->sec.ops->change_key(nvdimm, key_data(key), 137 - key_data(key), NVDIMM_USER); 138 if (rc < 0) { 139 nvdimm_put_key(key); 140 - key = NULL; 141 } 142 - return key; 143 } 144 145 static int __nvdimm_security_unlock(struct nvdimm *nvdimm) 146 { 147 struct device *dev = &nvdimm->dev; 148 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); 149 - struct key *key = NULL; 150 int rc; 151 152 /* The bus lock should be held at the top level of the call stack */ ··· 193 if (!key_revalidate) 194 return 0; 195 196 - key = nvdimm_key_revalidate(nvdimm); 197 - if (!key) 198 - return nvdimm_security_freeze(nvdimm); 199 } else 200 - key = nvdimm_request_key(nvdimm); 201 202 - if (!key) 203 - return -ENOKEY; 204 - 205 - rc = nvdimm->sec.ops->unlock(nvdimm, key_data(key)); 206 dev_dbg(dev, "key: %d unlock: %s\n", key_serial(key), 207 rc == 0 ? "success" : "fail"); 208 ··· 223 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); 224 struct key *key; 225 int rc; 226 227 /* The bus lock should be held at the top level of the call stack */ 228 lockdep_assert_held(&nvdimm_bus->reconfig_mutex); ··· 243 return -EBUSY; 244 } 245 246 - key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY); 247 - if (!key) 248 return -ENOKEY; 249 250 - rc = nvdimm->sec.ops->disable(nvdimm, key_data(key)); 251 dev_dbg(dev, "key: %d disable: %s\n", key_serial(key), 252 rc == 0 ? "success" : "fail"); 253 ··· 265 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); 266 struct key *key, *newkey; 267 int rc; 268 269 /* The bus lock should be held at the top level of the call stack */ 270 lockdep_assert_held(&nvdimm_bus->reconfig_mutex); ··· 280 return -EIO; 281 } 282 283 - if (keyid == 0) 284 - key = NULL; 285 - else { 286 - key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY); 287 - if (!key) 288 - return -ENOKEY; 289 - } 290 291 - newkey = nvdimm_lookup_user_key(nvdimm, new_keyid, NVDIMM_NEW_KEY); 292 - if (!newkey) { 293 nvdimm_put_key(key); 294 return -ENOKEY; 295 } 296 297 - rc = nvdimm->sec.ops->change_key(nvdimm, key ? key_data(key) : NULL, 298 - key_data(newkey), pass_type); 299 dev_dbg(dev, "key: %d %d update%s: %s\n", 300 key_serial(key), key_serial(newkey), 301 pass_type == NVDIMM_MASTER ? "(master)" : "(user)", ··· 314 { 315 struct device *dev = &nvdimm->dev; 316 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); 317 - struct key *key; 318 int rc; 319 320 /* The bus lock should be held at the top level of the call stack */ 321 lockdep_assert_held(&nvdimm_bus->reconfig_mutex); ··· 348 return -EOPNOTSUPP; 349 } 350 351 - key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY); 352 - if (!key) 353 return -ENOKEY; 354 355 - rc = nvdimm->sec.ops->erase(nvdimm, key_data(key), pass_type); 356 dev_dbg(dev, "key: %d erase%s: %s\n", key_serial(key), 357 pass_type == NVDIMM_MASTER ? "(master)" : "(user)", 358 rc == 0 ? "success" : "fail"); ··· 367 { 368 struct device *dev = &nvdimm->dev; 369 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); 370 - struct key *key; 371 int rc; 372 373 /* The bus lock should be held at the top level of the call stack */ 374 lockdep_assert_held(&nvdimm_bus->reconfig_mutex); ··· 399 return -EBUSY; 400 } 401 402 - if (keyid == 0) 403 - key = NULL; 404 - else { 405 - key = nvdimm_lookup_user_key(nvdimm, keyid, NVDIMM_BASE_KEY); 406 - if (!key) 407 - return -ENOKEY; 408 - } 409 410 - rc = nvdimm->sec.ops->overwrite(nvdimm, key ? key_data(key) : NULL); 411 dev_dbg(dev, "key: %d overwrite submission: %s\n", key_serial(key), 412 rc == 0 ? "success" : "fail"); 413
··· 22 module_param(key_revalidate, bool, 0444); 23 MODULE_PARM_DESC(key_revalidate, "Require key validation at init."); 24 25 + static const char zero_key[NVDIMM_PASSPHRASE_LEN]; 26 + 27 static void *key_data(struct key *key) 28 { 29 struct encrypted_key_payload *epayload = dereference_key_locked(key); ··· 75 return key; 76 } 77 78 + static const void *nvdimm_get_key_payload(struct nvdimm *nvdimm, 79 + struct key **key) 80 + { 81 + *key = nvdimm_request_key(nvdimm); 82 + if (!*key) 83 + return zero_key; 84 + 85 + return key_data(*key); 86 + } 87 + 88 static struct key *nvdimm_lookup_user_key(struct nvdimm *nvdimm, 89 key_serial_t id, int subclass) 90 { ··· 105 return key; 106 } 107 108 + static const void *nvdimm_get_user_key_payload(struct nvdimm *nvdimm, 109 + key_serial_t id, int subclass, struct key **key) 110 + { 111 + *key = NULL; 112 + if (id == 0) { 113 + if (subclass == NVDIMM_BASE_KEY) 114 + return zero_key; 115 + else 116 + return NULL; 117 + } 118 + 119 + *key = nvdimm_lookup_user_key(nvdimm, id, subclass); 120 + if (!*key) 121 + return NULL; 122 + 123 + return key_data(*key); 124 + } 125 + 126 + 127 + static int nvdimm_key_revalidate(struct nvdimm *nvdimm) 128 { 129 struct key *key; 130 int rc; 131 + const void *data; 132 133 if (!nvdimm->sec.ops->change_key) 134 + return -EOPNOTSUPP; 135 136 + data = nvdimm_get_key_payload(nvdimm, &key); 137 138 /* 139 * Send the same key to the hardware as new and old key to 140 * verify that the key is good. 141 */ 142 + rc = nvdimm->sec.ops->change_key(nvdimm, data, data, NVDIMM_USER); 143 if (rc < 0) { 144 nvdimm_put_key(key); 145 + return rc; 146 } 147 + 148 + nvdimm_put_key(key); 149 + nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER); 150 + return 0; 151 } 152 153 static int __nvdimm_security_unlock(struct nvdimm *nvdimm) 154 { 155 struct device *dev = &nvdimm->dev; 156 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); 157 + struct key *key; 158 + const void *data; 159 int rc; 160 161 /* The bus lock should be held at the top level of the call stack */ ··· 160 if (!key_revalidate) 161 return 0; 162 163 + return nvdimm_key_revalidate(nvdimm); 164 } else 165 + data = nvdimm_get_key_payload(nvdimm, &key); 166 167 + rc = nvdimm->sec.ops->unlock(nvdimm, data); 168 dev_dbg(dev, "key: %d unlock: %s\n", key_serial(key), 169 rc == 0 ? "success" : "fail"); 170 ··· 195 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); 196 struct key *key; 197 int rc; 198 + const void *data; 199 200 /* The bus lock should be held at the top level of the call stack */ 201 lockdep_assert_held(&nvdimm_bus->reconfig_mutex); ··· 214 return -EBUSY; 215 } 216 217 + data = nvdimm_get_user_key_payload(nvdimm, keyid, 218 + NVDIMM_BASE_KEY, &key); 219 + if (!data) 220 return -ENOKEY; 221 222 + rc = nvdimm->sec.ops->disable(nvdimm, data); 223 dev_dbg(dev, "key: %d disable: %s\n", key_serial(key), 224 rc == 0 ? "success" : "fail"); 225 ··· 235 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); 236 struct key *key, *newkey; 237 int rc; 238 + const void *data, *newdata; 239 240 /* The bus lock should be held at the top level of the call stack */ 241 lockdep_assert_held(&nvdimm_bus->reconfig_mutex); ··· 249 return -EIO; 250 } 251 252 + data = nvdimm_get_user_key_payload(nvdimm, keyid, 253 + NVDIMM_BASE_KEY, &key); 254 + if (!data) 255 + return -ENOKEY; 256 257 + newdata = nvdimm_get_user_key_payload(nvdimm, new_keyid, 258 + NVDIMM_NEW_KEY, &newkey); 259 + if (!newdata) { 260 nvdimm_put_key(key); 261 return -ENOKEY; 262 } 263 264 + rc = nvdimm->sec.ops->change_key(nvdimm, data, newdata, pass_type); 265 dev_dbg(dev, "key: %d %d update%s: %s\n", 266 key_serial(key), key_serial(newkey), 267 pass_type == NVDIMM_MASTER ? "(master)" : "(user)", ··· 286 { 287 struct device *dev = &nvdimm->dev; 288 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); 289 + struct key *key = NULL; 290 int rc; 291 + const void *data; 292 293 /* The bus lock should be held at the top level of the call stack */ 294 lockdep_assert_held(&nvdimm_bus->reconfig_mutex); ··· 319 return -EOPNOTSUPP; 320 } 321 322 + data = nvdimm_get_user_key_payload(nvdimm, keyid, 323 + NVDIMM_BASE_KEY, &key); 324 + if (!data) 325 return -ENOKEY; 326 327 + rc = nvdimm->sec.ops->erase(nvdimm, data, pass_type); 328 dev_dbg(dev, "key: %d erase%s: %s\n", key_serial(key), 329 pass_type == NVDIMM_MASTER ? "(master)" : "(user)", 330 rc == 0 ? "success" : "fail"); ··· 337 { 338 struct device *dev = &nvdimm->dev; 339 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); 340 + struct key *key = NULL; 341 int rc; 342 + const void *data; 343 344 /* The bus lock should be held at the top level of the call stack */ 345 lockdep_assert_held(&nvdimm_bus->reconfig_mutex); ··· 368 return -EBUSY; 369 } 370 371 + data = nvdimm_get_user_key_payload(nvdimm, keyid, 372 + NVDIMM_BASE_KEY, &key); 373 + if (!data) 374 + return -ENOKEY; 375 376 + rc = nvdimm->sec.ops->overwrite(nvdimm, data); 377 dev_dbg(dev, "key: %d overwrite submission: %s\n", key_serial(key), 378 rc == 0 ? "success" : "fail"); 379
+13 -4
tools/testing/nvdimm/test/nfit.c
··· 146 struct nfit_test_sec { 147 u8 state; 148 u8 ext_state; 149 u8 passphrase[32]; 150 u8 master_passphrase[32]; 151 u64 overwrite_end_time; ··· 225 static struct workqueue_struct *nfit_wq; 226 227 static struct gen_pool *nfit_pool; 228 229 static struct nfit_test *to_nfit_test(struct device *dev) 230 { ··· 1062 struct device *dev = &t->pdev.dev; 1063 struct nfit_test_sec *sec = &dimm_sec_info[dimm]; 1064 1065 - if (!(sec->state & ND_INTEL_SEC_STATE_ENABLED) || 1066 - (sec->state & ND_INTEL_SEC_STATE_FROZEN)) { 1067 nd_cmd->status = ND_INTEL_STATUS_INVALID_STATE; 1068 dev_dbg(dev, "secure erase: wrong security state\n"); 1069 } else if (memcmp(nd_cmd->passphrase, sec->passphrase, ··· 1070 nd_cmd->status = ND_INTEL_STATUS_INVALID_PASS; 1071 dev_dbg(dev, "secure erase: wrong passphrase\n"); 1072 } else { 1073 memset(sec->passphrase, 0, ND_INTEL_PASSPHRASE_SIZE); 1074 memset(sec->master_passphrase, 0, ND_INTEL_PASSPHRASE_SIZE); 1075 sec->state = 0; ··· 1101 return 0; 1102 } 1103 1104 - memset(sec->passphrase, 0, ND_INTEL_PASSPHRASE_SIZE); 1105 sec->state = ND_INTEL_SEC_STATE_OVERWRITE; 1106 dev_dbg(dev, "overwrite progressing.\n"); 1107 sec->overwrite_end_time = get_jiffies_64() + 5 * HZ; ··· 1123 1124 if (time_is_before_jiffies64(sec->overwrite_end_time)) { 1125 sec->overwrite_end_time = 0; 1126 - sec->state = 0; 1127 sec->ext_state = ND_INTEL_SEC_ESTATE_ENABLED; 1128 dev_dbg(dev, "overwrite is complete\n"); 1129 } else
··· 146 struct nfit_test_sec { 147 u8 state; 148 u8 ext_state; 149 + u8 old_state; 150 u8 passphrase[32]; 151 u8 master_passphrase[32]; 152 u64 overwrite_end_time; ··· 224 static struct workqueue_struct *nfit_wq; 225 226 static struct gen_pool *nfit_pool; 227 + 228 + static const char zero_key[NVDIMM_PASSPHRASE_LEN]; 229 230 static struct nfit_test *to_nfit_test(struct device *dev) 231 { ··· 1059 struct device *dev = &t->pdev.dev; 1060 struct nfit_test_sec *sec = &dimm_sec_info[dimm]; 1061 1062 + if (sec->state & ND_INTEL_SEC_STATE_FROZEN) { 1063 nd_cmd->status = ND_INTEL_STATUS_INVALID_STATE; 1064 dev_dbg(dev, "secure erase: wrong security state\n"); 1065 } else if (memcmp(nd_cmd->passphrase, sec->passphrase, ··· 1068 nd_cmd->status = ND_INTEL_STATUS_INVALID_PASS; 1069 dev_dbg(dev, "secure erase: wrong passphrase\n"); 1070 } else { 1071 + if (!(sec->state & ND_INTEL_SEC_STATE_ENABLED) 1072 + && (memcmp(nd_cmd->passphrase, zero_key, 1073 + ND_INTEL_PASSPHRASE_SIZE) != 0)) { 1074 + dev_dbg(dev, "invalid zero key\n"); 1075 + return 0; 1076 + } 1077 memset(sec->passphrase, 0, ND_INTEL_PASSPHRASE_SIZE); 1078 memset(sec->master_passphrase, 0, ND_INTEL_PASSPHRASE_SIZE); 1079 sec->state = 0; ··· 1093 return 0; 1094 } 1095 1096 + sec->old_state = sec->state; 1097 sec->state = ND_INTEL_SEC_STATE_OVERWRITE; 1098 dev_dbg(dev, "overwrite progressing.\n"); 1099 sec->overwrite_end_time = get_jiffies_64() + 5 * HZ; ··· 1115 1116 if (time_is_before_jiffies64(sec->overwrite_end_time)) { 1117 sec->overwrite_end_time = 0; 1118 + sec->state = sec->old_state; 1119 + sec->old_state = 0; 1120 sec->ext_state = ND_INTEL_SEC_ESTATE_ENABLED; 1121 dev_dbg(dev, "overwrite is complete\n"); 1122 } else