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