e1000e: write protect ICHx NVM to prevent malicious write/erase

Set the hardware to ignore all write/erase cycles to the GbE region in
the ICHx NVM. This feature can be disabled by the WriteProtectNVM module
parameter (enabled by default) only after a hardware reset, but
the machine must be power cycled before trying to enable writes.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
CC: arjan@linux.intel.com
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by Bruce Allan and committed by Linus Torvalds 4a770358 20b918dc

+100 -3
+2
drivers/net/e1000e/e1000.h
··· 305 305 #define FLAG_HAS_CTRLEXT_ON_LOAD (1 << 5) 306 306 #define FLAG_HAS_SWSM_ON_LOAD (1 << 6) 307 307 #define FLAG_HAS_JUMBO_FRAMES (1 << 7) 308 + #define FLAG_READ_ONLY_NVM (1 << 8) 308 309 #define FLAG_IS_ICH (1 << 9) 309 310 #define FLAG_HAS_SMART_POWER_DOWN (1 << 11) 310 311 #define FLAG_IS_QUAD_PORT_A (1 << 12) ··· 386 385 extern bool e1000e_get_laa_state_82571(struct e1000_hw *hw); 387 386 extern void e1000e_set_laa_state_82571(struct e1000_hw *hw, bool state); 388 387 388 + extern void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw); 389 389 extern void e1000e_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw, 390 390 bool state); 391 391 extern void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw);
+3
drivers/net/e1000e/ethtool.c
··· 529 529 if (eeprom->magic != (adapter->pdev->vendor | (adapter->pdev->device << 16))) 530 530 return -EFAULT; 531 531 532 + if (adapter->flags & FLAG_READ_ONLY_NVM) 533 + return -EINVAL; 534 + 532 535 max_len = hw->nvm.word_size * 2; 533 536 534 537 first_word = eeprom->offset >> 1;
+58
drivers/net/e1000e/ich8lan.c
··· 58 58 #define ICH_FLASH_HSFCTL 0x0006 59 59 #define ICH_FLASH_FADDR 0x0008 60 60 #define ICH_FLASH_FDATA0 0x0010 61 + #define ICH_FLASH_PR0 0x0074 61 62 62 63 #define ICH_FLASH_READ_COMMAND_TIMEOUT 500 63 64 #define ICH_FLASH_WRITE_COMMAND_TIMEOUT 500 ··· 149 148 u32 gmwag :8; /* 31:24 GbE Master Write Access Grant */ 150 149 } hsf_flregacc; 151 150 u16 regval; 151 + }; 152 + 153 + /* ICH Flash Protected Region */ 154 + union ich8_flash_protected_range { 155 + struct ich8_pr { 156 + u32 base:13; /* 0:12 Protected Range Base */ 157 + u32 reserved1:2; /* 13:14 Reserved */ 158 + u32 rpe:1; /* 15 Read Protection Enable */ 159 + u32 limit:13; /* 16:28 Protected Range Limit */ 160 + u32 reserved2:2; /* 29:30 Reserved */ 161 + u32 wpe:1; /* 31 Write Protection Enable */ 162 + } range; 163 + u32 regval; 152 164 }; 153 165 154 166 static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw); ··· 1298 1284 * programming failed. 1299 1285 */ 1300 1286 if (ret_val) { 1287 + /* Possibly read-only, see e1000e_write_protect_nvm_ich8lan() */ 1301 1288 hw_dbg(hw, "Flash commit failed.\n"); 1302 1289 e1000_release_swflag_ich8lan(hw); 1303 1290 return ret_val; ··· 1386 1371 } 1387 1372 1388 1373 return e1000e_validate_nvm_checksum_generic(hw); 1374 + } 1375 + 1376 + /** 1377 + * e1000e_write_protect_nvm_ich8lan - Make the NVM read-only 1378 + * @hw: pointer to the HW structure 1379 + * 1380 + * To prevent malicious write/erase of the NVM, set it to be read-only 1381 + * so that the hardware ignores all write/erase cycles of the NVM via 1382 + * the flash control registers. The shadow-ram copy of the NVM will 1383 + * still be updated, however any updates to this copy will not stick 1384 + * across driver reloads. 1385 + **/ 1386 + void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw) 1387 + { 1388 + union ich8_flash_protected_range pr0; 1389 + union ich8_hws_flash_status hsfsts; 1390 + u32 gfpreg; 1391 + s32 ret_val; 1392 + 1393 + ret_val = e1000_acquire_swflag_ich8lan(hw); 1394 + if (ret_val) 1395 + return; 1396 + 1397 + gfpreg = er32flash(ICH_FLASH_GFPREG); 1398 + 1399 + /* Write-protect GbE Sector of NVM */ 1400 + pr0.regval = er32flash(ICH_FLASH_PR0); 1401 + pr0.range.base = gfpreg & FLASH_GFPREG_BASE_MASK; 1402 + pr0.range.limit = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK); 1403 + pr0.range.wpe = true; 1404 + ew32flash(ICH_FLASH_PR0, pr0.regval); 1405 + 1406 + /* 1407 + * Lock down a subset of GbE Flash Control Registers, e.g. 1408 + * PR0 to prevent the write-protection from being lifted. 1409 + * Once FLOCKDN is set, the registers protected by it cannot 1410 + * be written until FLOCKDN is cleared by a hardware reset. 1411 + */ 1412 + hsfsts.regval = er16flash(ICH_FLASH_HSFSTS); 1413 + hsfsts.hsf_status.flockdn = true; 1414 + ew32flash(ICH_FLASH_HSFSTS, hsfsts.regval); 1415 + 1416 + e1000_release_swflag_ich8lan(hw); 1389 1417 } 1390 1418 1391 1419 /**
+7 -3
drivers/net/e1000e/netdev.c
··· 47 47 48 48 #include "e1000.h" 49 49 50 - #define DRV_VERSION "0.3.3.3-k2" 50 + #define DRV_VERSION "0.3.3.3-k4" 51 51 char e1000e_driver_name[] = "e1000e"; 52 52 const char e1000e_driver_version[] = DRV_VERSION; 53 53 ··· 4467 4467 4468 4468 adapter->bd_number = cards_found++; 4469 4469 4470 + e1000e_check_options(adapter); 4471 + 4470 4472 /* setup adapter struct */ 4471 4473 err = e1000_sw_init(adapter); 4472 4474 if (err) ··· 4483 4481 err = ei->get_variants(adapter); 4484 4482 if (err) 4485 4483 goto err_hw_init; 4484 + 4485 + if ((adapter->flags & FLAG_IS_ICH) && 4486 + (adapter->flags & FLAG_READ_ONLY_NVM)) 4487 + e1000e_write_protect_nvm_ich8lan(&adapter->hw); 4486 4488 4487 4489 hw->mac.ops.get_bus_info(&adapter->hw); 4488 4490 ··· 4578 4572 4579 4573 INIT_WORK(&adapter->reset_task, e1000_reset_task); 4580 4574 INIT_WORK(&adapter->watchdog_task, e1000_watchdog_task); 4581 - 4582 - e1000e_check_options(adapter); 4583 4575 4584 4576 /* Initialize link parameters. User can change them with ethtool */ 4585 4577 adapter->hw.mac.autoneg = 1;
+30
drivers/net/e1000e/param.c
··· 133 133 */ 134 134 E1000_PARAM(KumeranLockLoss, "Enable Kumeran lock loss workaround"); 135 135 136 + /* 137 + * Write Protect NVM 138 + * 139 + * Valid Range: 0, 1 140 + * 141 + * Default Value: 1 (enabled) 142 + */ 143 + E1000_PARAM(WriteProtectNVM, "Write-protect NVM [WARNING: disabling this can lead to corrupted NVM]"); 144 + 136 145 struct e1000_option { 137 146 enum { enable_option, range_option, list_option } type; 138 147 const char *name; ··· 395 386 if (hw->mac.type == e1000_ich8lan) 396 387 e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, 397 388 opt.def); 389 + } 390 + } 391 + { /* Write-protect NVM */ 392 + const struct e1000_option opt = { 393 + .type = enable_option, 394 + .name = "Write-protect NVM", 395 + .err = "defaulting to Enabled", 396 + .def = OPTION_ENABLED 397 + }; 398 + 399 + if (adapter->flags & FLAG_IS_ICH) { 400 + if (num_WriteProtectNVM > bd) { 401 + unsigned int write_protect_nvm = WriteProtectNVM[bd]; 402 + e1000_validate_option(&write_protect_nvm, &opt, 403 + adapter); 404 + if (write_protect_nvm) 405 + adapter->flags |= FLAG_READ_ONLY_NVM; 406 + } else { 407 + if (opt.def) 408 + adapter->flags |= FLAG_READ_ONLY_NVM; 409 + } 398 410 } 399 411 } 400 412 }