Make crossystem kern_nv field read-only.

BUG=chromium-os:14029
TEST=make && make runtests, and manually check:

crossystem fwupdate_tries=3
crossystem fwupdate_tries kern_nv
(should print 3 0x00000003)
crossystem kern_nv=0
(should fail)
crossystem fwupdate_tries kern_nv
(should print 3 0x00000003)
crossystem fwupdate_tries=0
crossystem fwupdate_tries kern_nv
(should print 0 0x00000000)

Change-Id: I906ad41a36378b93e0c3330d8f94b7d69aafa536
Reviewed-on: http://gerrit.chromium.org/gerrit/4751
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Tested-by: Randall Spangler <rspangler@chromium.org>
diff --git a/host/lib/crossystem.c b/host/lib/crossystem.c
index 34c1de1..ef3c6d1 100644
--- a/host/lib/crossystem.c
+++ b/host/lib/crossystem.c
@@ -43,9 +43,13 @@
 } VdatIntField;
 
 
-/* Masks for kern_nv usage by kernel */
+/* Masks for kern_nv usage by kernel. */
 #define KERN_NV_FWUPDATE_TRIES_MASK 0x0000000F
-
+/* If you want to use the remaining currently-unused bits in kern_nv
+ * for something kernel-y, define a new field (the way we did for
+ * fwupdate_tries).  Don't just modify kern_nv directly, because that
+ * makes it too easy to accidentally corrupt other sub-fields. */
+#define KERN_NV_CURRENTLY_UNUSED    0xFFFFFFF0
 
 /* Return true if the FWID starts with the specified string. */
 int FwidStartsWith(const char *start) {
@@ -444,8 +448,6 @@
   if (!strcasecmp(name,"nvram_cleared")) {
     /* Can only clear this flag; it's set inside the NV storage library. */
     return VbSetNvStorage(VBNV_KERNEL_SETTINGS_RESET, 0);
-  } else if (!strcasecmp(name,"kern_nv")) {
-    return VbSetNvStorage(VBNV_KERNEL_FIELD, value);
   } else if (!strcasecmp(name,"vbtest_errfunc")) {
     return VbSetNvStorage(VBNV_TEST_ERROR_FUNC, value);
   } else if (!strcasecmp(name,"vbtest_errno")) {
diff --git a/utility/crossystem_main.c b/utility/crossystem_main.c
index 0c1d2fd..b914d62 100644
--- a/utility/crossystem_main.c
+++ b/utility/crossystem_main.c
@@ -48,7 +48,7 @@
   {"fwupdate_tries", CAN_WRITE,
    "Times to try OS firmware update (writable, inside kern_nv)"},
   {"hwid", IS_STRING, "Hardware ID"},
-  {"kern_nv", CAN_WRITE, "Non-volatile field for kernel use", "0x%08x"},
+  {"kern_nv", 0, "Non-volatile field for kernel use", "0x%08x"},
   {"kernkey_vfy", IS_STRING, "Type of verification done on kernel key block"},
   {"loc_idx", CAN_WRITE, "Localization index for firmware screens (writable)"},
   {"mainfw_act", IS_STRING, "Active main firmware"},