mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Jesse Brandeburg <jesse.brandeburg@intel.com>
To: linux-kernel@vger.kernel.org
Cc: linux-netdev@vger.kernel.org, kkeil@suse.de, agospoda@redhat.com,
	arjan@linux.intel.com, david.graham@intel.com,
	bruce.w.allan@intel.com, jkosina@suse.cz, john.ronciak@intel.com,
	tglx@linutronix.de, chris.jones@canonical.com,
	tim.gardner@intel.com, airlied@gmail.com,
	Bruce Allan <bruce.w.allan@intel.com>,
	Jesse Brandeburg <jesse.brandeburg@intel.com>
Subject: [RFC PATCH 11/12] e1000e: write protect ICHx NVM to prevent malicious write/erase
Date: Mon, 29 Sep 2008 20:20:13 -0700	[thread overview]
Message-ID: <20080930032013.22950.70966.stgit@jbrandeb-bw.jf.intel.com> (raw)
In-Reply-To: <20080930030825.22950.18891.stgit@jbrandeb-bw.jf.intel.com>

From: Bruce Allan <bruce.w.allan@intel.com>

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) though that is not recommended.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
---

 drivers/net/e1000e/e1000.h   |    2 ++
 drivers/net/e1000e/ethtool.c |    3 +++
 drivers/net/e1000e/ich8lan.c |   46 ++++++++++++++++++++++++++++++++++++++++++
 drivers/net/e1000e/netdev.c  |    8 +++++--
 drivers/net/e1000e/param.c   |   30 +++++++++++++++++++++++++++
 5 files changed, 87 insertions(+), 2 deletions(-)

diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index 2a3a311..6b0eb73 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -307,6 +307,7 @@ struct e1000_info {
 #define FLAG_HAS_CTRLEXT_ON_LOAD          (1 << 5)
 #define FLAG_HAS_SWSM_ON_LOAD             (1 << 6)
 #define FLAG_HAS_JUMBO_FRAMES             (1 << 7)
+#define FLAG_READ_ONLY_NVM                (1 << 8)
 #define FLAG_IS_ICH                       (1 << 9)
 #define FLAG_HAS_SMART_POWER_DOWN         (1 << 11)
 #define FLAG_IS_QUAD_PORT_A               (1 << 12)
@@ -387,6 +388,7 @@ extern bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw);
 extern bool e1000e_get_laa_state_82571(struct e1000_hw *hw);
 extern void e1000e_set_laa_state_82571(struct e1000_hw *hw, bool state);
 
+extern void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw, bool enable);
 extern void e1000e_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw,
 						 bool state);
 extern void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw);
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index f3b49f6..33a3ff1 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -533,6 +533,9 @@ static int e1000_set_eeprom(struct net_device *netdev,
 	if (eeprom->magic != (adapter->pdev->vendor | (adapter->pdev->device << 16)))
 		return -EFAULT;
 
+	if (adapter->flags & FLAG_READ_ONLY_NVM)
+		return -EINVAL;
+
 	max_len = hw->nvm.word_size * 2;
 
 	first_word = eeprom->offset >> 1;
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 2b1aa2a..5e3dac9 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -58,6 +58,7 @@
 #define ICH_FLASH_HSFCTL		0x0006
 #define ICH_FLASH_FADDR			0x0008
 #define ICH_FLASH_FDATA0		0x0010
+#define ICH_FLASH_PR0			0x0074
 
 #define ICH_FLASH_READ_COMMAND_TIMEOUT	500
 #define ICH_FLASH_WRITE_COMMAND_TIMEOUT	500
@@ -150,6 +151,19 @@ union ich8_hws_flash_regacc {
 	u16 regval;
 };
 
+/* ICH Flash Protected Region */
+union ich8_flash_protected_range {
+	struct ich8_pr {
+		u32 base:13;     /* 0:12 Protected Range Base */
+		u32 reserved1:2; /* 13:14 Reserved */
+		u32 rpe:1;       /* 15 Read Protection Enable */
+		u32 limit:13;    /* 16:28 Protected Range Limit */
+		u32 reserved2:2; /* 29:30 Reserved */
+		u32 wpe:1;       /* 31 Write Protection Enable */
+	} range;
+	u32 regval;
+};
+
 static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw);
 static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw);
 static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw);
@@ -1317,6 +1331,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
 	 * programming failed.
 	 */
 	if (ret_val) {
+		/* Possibly read-only, see e1000e_write_protect_nvm_ich8lan() */
 		hw_dbg(hw, "Flash commit failed.\n");
 		e1000_release_swflag_ich8lan(hw);
 		return ret_val;
@@ -1407,6 +1422,37 @@ static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw)
 }
 
 /**
+ *  e1000e_write_protect_nvm_ich8lan - Make the NVM read-only
+ *  @hw: pointer to the HW structure
+ *  @enable: pointer to the HW structure
+ *  @enable: TRUE to enable write protection, FALSE to disable write protection
+ *
+ *  To prevent malicious write/erase of the NVM, set it to be read-only
+ *  so that the hardware ignores all write/erase cycles of the NVM via
+ *  the flash control registers.  The shadow-ram copy of the NVM will
+ *  still be updated, however any updates to this copy will not stick
+ *  across driver reloads.
+ **/
+void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw, bool enable)
+{
+	union ich8_flash_protected_range pr0;
+	u32 gfpreg;
+
+	if (hw->nvm.ops.acquire_nvm(hw))
+		return;
+
+	gfpreg = er32flash(ICH_FLASH_GFPREG);
+
+	pr0.regval = er32flash(ICH_FLASH_PR0);
+	pr0.range.base = gfpreg & FLASH_GFPREG_BASE_MASK;
+	pr0.range.limit = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK);
+	pr0.range.wpe = enable;
+	ew32flash(ICH_FLASH_PR0, pr0.regval);
+
+	hw->nvm.ops.release_nvm(hw);
+}
+
+/**
  *  e1000_write_flash_data_ich8lan - Writes bytes to the NVM
  *  @hw: pointer to the HW structure
  *  @offset: The offset (in bytes) of the byte/word to read.
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index f04de5a..2626c42 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -4508,6 +4508,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 
 	adapter->bd_number = cards_found++;
 
+	e1000e_check_options(adapter);
+
 	/* setup adapter struct */
 	err = e1000_sw_init(adapter);
 	if (err)
@@ -4523,6 +4525,10 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 	if (err)
 		goto err_hw_init;
 
+	if (adapter->flags & FLAG_IS_ICH)
+		e1000e_write_protect_nvm_ich8lan(&adapter->hw,
+		                       !!(adapter->flags & FLAG_READ_ONLY_NVM));
+
 	hw->mac.ops.get_bus_info(&adapter->hw);
 
 	adapter->hw.phy.autoneg_wait_to_complete = 0;
@@ -4629,8 +4635,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 	INIT_WORK(&adapter->downshift_task, e1000e_downshift_workaround);
 	INIT_WORK(&adapter->update_phy_task, e1000e_update_phy_task);
 
-	e1000e_check_options(adapter);
-
 	/* Initialize link parameters. User can change them with ethtool */
 	adapter->hw.mac.autoneg = 1;
 	adapter->fc_autoneg = 1;
diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c
index ed912e0..d91dbf7 100644
--- a/drivers/net/e1000e/param.c
+++ b/drivers/net/e1000e/param.c
@@ -133,6 +133,15 @@ E1000_PARAM(SmartPowerDownEnable, "Enable PHY smart power down");
  */
 E1000_PARAM(KumeranLockLoss, "Enable Kumeran lock loss workaround");
 
+/*
+ * Write Protect NVM
+ *
+ * Valid Range: 0, 1
+ *
+ * Default Value: 1 (enabled)
+ */
+E1000_PARAM(WriteProtectNVM, "Write-protect NVM [WARNING: disabling this can lead to corrupted NVM]");
+
 struct e1000_option {
 	enum { enable_option, range_option, list_option } type;
 	const char *name;
@@ -388,4 +397,25 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
 								       opt.def);
 		}
 	}
+	{ /* Write-protect NVM */
+		const struct e1000_option opt = {
+			.type = enable_option,
+			.name = "Write-protect NVM",
+			.err  = "defaulting to Enabled",
+			.def  = OPTION_ENABLED
+		};
+
+		if (adapter->flags & FLAG_IS_ICH) {
+			if (num_WriteProtectNVM > bd) {
+				unsigned int write_protect_nvm = WriteProtectNVM[bd];
+				e1000_validate_option(&write_protect_nvm, &opt,
+						      adapter);
+				if (write_protect_nvm)
+					adapter->flags |= FLAG_READ_ONLY_NVM;
+			} else {
+				if (opt.def)
+					adapter->flags |= FLAG_READ_ONLY_NVM;
+			}
+		}
+	}
 }


  parent reply	other threads:[~2008-09-30  3:23 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-09-30  3:19 [RFC PATCH 00/12] e1000e debug and protection patches Jesse Brandeburg
2008-09-30  3:19 ` [RFC PATCH 01/12] x86: export set_memory_ro and set_memory_rw Jesse Brandeburg
2008-09-30  7:07   ` Ingo Molnar
2008-09-30  3:19 ` [RFC PATCH 02/12] On Tue, 23 Sep 2008, David Miller wrote: Jesse Brandeburg
2008-10-02 22:23   ` Jesse Barnes
2008-10-03 20:46     ` David Miller
2008-10-03 21:29       ` Jesse Barnes
2008-10-03 21:45         ` Jiri Kosina
2008-10-03 23:28           ` Jesse Brandeburg
2008-10-03 23:30             ` Jesse Brandeburg
2008-10-04 10:21             ` Jiri Kosina
2008-10-04 11:02               ` Thomas Gleixner
2008-10-05  1:24                 ` Jesse Brandeburg
2008-10-05  8:51                   ` Thomas Gleixner
2008-10-05 15:05                     ` Arjan van de Ven
2008-10-05 15:55                       ` Thomas Gleixner
2008-10-05 16:02                         ` Arjan van de Ven
2008-10-05 16:16                           ` Thomas Gleixner
2008-10-05 17:01                             ` Arjan van de Ven
2008-10-07 23:19     ` David Miller
2008-09-30  3:19 ` [RFC PATCH 03/12] e1000e: reset swflag after resetting hardware Jesse Brandeburg
2008-09-30  3:19 ` [RFC PATCH 04/12] e1000e: do not ever sleep in interrupt context Jesse Brandeburg
2008-09-30  3:19 ` [RFC PATCH 05/12] e1000e: fix lockdep issues Jesse Brandeburg
2008-09-30  3:19 ` [RFC PATCH 06/12] e1000e: drop stats lock Jesse Brandeburg
2008-09-30  3:19 ` [RFC PATCH 07/12] e1000e: debug contention on NVM SWFLAG Jesse Brandeburg
2008-10-02 14:28   ` Jiri Kosina
2008-10-02 15:03     ` Olaf Kirch
2008-10-02 16:27       ` Brandeburg, Jesse
2008-10-02 17:33         ` Olaf Kirch
2008-10-02 18:58           ` Thomas Gleixner
2008-10-02 19:07             ` Olaf Kirch
2008-10-02 19:08               ` Olaf Kirch
2008-10-02 18:02         ` Thomas Gleixner
2008-10-02 23:42       ` [PATCH] e1000e: prevent concurrent access to NVRAM Thomas Gleixner
2008-10-03  0:19         ` Jesse Brandeburg
2008-10-03  0:28           ` Thomas Gleixner
2008-09-30  3:19 ` [RFC PATCH 08/12] e1000e: allow bad checksum Jesse Brandeburg
2008-09-30  8:38   ` Jiri Kosina
2008-09-30  3:20 ` [RFC PATCH 09/12] e1000e: dump eeprom to dmesg for ich8/9 Jesse Brandeburg
2008-09-30  3:20 ` [RFC PATCH 10/12] e1000e: Use set_memory_ro()/set_memory_rw() to protect flash memory Jesse Brandeburg
2008-09-30  3:20 ` Jesse Brandeburg [this message]
2008-09-30 12:40   ` [RFC PATCH 11/12] e1000e: write protect ICHx NVM to prevent malicious write/erase Jiri Kosina
2008-09-30 15:47     ` Allan, Bruce W
2008-10-01 13:29       ` Jiri Kosina
2008-10-01 19:13         ` Allan, Bruce W
2008-09-30  3:20 ` [RFC PATCH 12/12] update version Jesse Brandeburg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080930032013.22950.70966.stgit@jbrandeb-bw.jf.intel.com \
    --to=jesse.brandeburg@intel.com \
    --cc=agospoda@redhat.com \
    --cc=airlied@gmail.com \
    --cc=arjan@linux.intel.com \
    --cc=bruce.w.allan@intel.com \
    --cc=chris.jones@canonical.com \
    --cc=david.graham@intel.com \
    --cc=jkosina@suse.cz \
    --cc=john.ronciak@intel.com \
    --cc=kkeil@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-netdev@vger.kernel.org \
    --cc=tglx@linutronix.de \
    --cc=tim.gardner@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®