summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Jeffery <andrew@aj.id.au>2018-11-13 17:15:18 +1030
committerAndrew Jeffery <andrew@aj.id.au>2019-01-08 03:11:04 +0000
commit7a85d22a5ffce603fa0e6b3dae41aabc954df10f (patch)
treea61bc41df63ba70f8e22c85bda10293bb1ad5f65
parent8a0efd5e9e0f544fc383cd9cd92979b27ccc0a94 (diff)
downloadphosphor-mboxbridge-7a85d22a5ffce603fa0e6b3dae41aabc954df10f.tar.gz
phosphor-mboxbridge-7a85d22a5ffce603fa0e6b3dae41aabc954df10f.zip
vpnor: Enforce a read-only FFS ToC regardless of flags
The virtual PNOR implementation never properly honoured writes to the FFS ToC, as the ToC's binary representation is generated from the CSV file shipped in the PNOR squashfs image. What *did* happen was that opening a write window to the ToC region succeeded and writes could be flushed, but the flushed writes were never read, and ToC representation internal to mboxd was never updated to match the written state. Thus the written values "persisted" until the ToC's window fell out of the cache (with 64MiB reserved regions, probably on a host reboot). Short circuit the insanity of handling FFS more than we have to by forcefully marking the ToC as read-only, regardless of the flag configuration shipped in the CSV representation. This prevents the host from successfully opening a write window and thus the host can have no expectation of write persistence. Change-Id: Ib2788c56b245da506cb7d607c0758b17785766cf Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
-rw-r--r--vpnor/pnor_partition_table.cpp12
-rw-r--r--vpnor/test/Makefile.am.include3
2 files changed, 13 insertions, 2 deletions
diff --git a/vpnor/pnor_partition_table.cpp b/vpnor/pnor_partition_table.cpp
index aa0b2fb..7e99ae2 100644
--- a/vpnor/pnor_partition_table.cpp
+++ b/vpnor/pnor_partition_table.cpp
@@ -296,6 +296,15 @@ static inline void writeUserdata(pnor_partition& part, uint32_t version,
}
}
+ // Awful hack: Detect the TOC partition and force it read-only.
+ //
+ // Note that as it stands in the caller code we populate the critical
+ // elements before the user data. These tests make doing so a requirement.
+ if (part.data.id == 0 && !part.data.base && part.data.size)
+ {
+ perms |= PARTITION_READONLY;
+ }
+
part.data.user.data[0] = state;
part.data.user.data[1] = perms;
part.data.user.data[1] |= version;
@@ -374,6 +383,9 @@ void parseTocLine(const std::string& line, size_t blockSize,
// Use the shift to convert "80" to 0x80000000
unsigned long version = std::stoul(match[VERSION_MATCH].str(), nullptr, 16);
+ // Note that we must have written the partition ID and sizes prior to
+ // populating the userdata. See the note about awful hacks in
+ // writeUserdata()
writeUserdata(part, version << versionShift, match.suffix().str());
part.checksum = details::checksum(part.data);
}
diff --git a/vpnor/test/Makefile.am.include b/vpnor/test/Makefile.am.include
index 3b366b6..f3f4fc2 100644
--- a/vpnor/test/Makefile.am.include
+++ b/vpnor/test/Makefile.am.include
@@ -267,6 +267,5 @@ check_PROGRAMS += \
%reldir%/force_readonly_toc
XFAIL_TESTS += \
- %reldir%/write_toc \
- %reldir%/force_readonly_toc
+ %reldir%/write_toc
endif
OpenPOWER on IntegriCloud