Fix get operation for chained secure storage providers

The smm-gateway's use of a backend storage provider showed
up an issue with the 'get' operation where the data_size
parameter set by a client is based on the maximum payload
size for the RPC interface between the client and in this
case, the smm-gateway. The request then gets delegated
to a storage SP. Because the RPC buffer sizes between
the client->smm-gateway and smm-gateway->storage SP are
not necessarily the same, the secure storage provider
was rejecting a get request when the data size was bigger
than its immediate RPC response buffer. The PC deployment of
ts-service-test is modified to recreate the problem.
The implemented fix in secure_storage_provider clips
the incoming data_size value if it exceeds the size of
the local response buffer.

Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: I649d585df4ff3d8f6559b476bbcf6acbf256645b
diff --git a/components/service/locator/standalone/services/smm-variable/smm_variable_service_context.cpp b/components/service/locator/standalone/services/smm-variable/smm_variable_service_context.cpp
index 3669792..0b28917 100644
--- a/components/service/locator/standalone/services/smm-variable/smm_variable_service_context.cpp
+++ b/components/service/locator/standalone/services/smm-variable/smm_variable_service_context.cpp
@@ -8,7 +8,7 @@
 #include <protocols/rpc/common/packed-c/encoding.h>
 
 smm_variable_service_context::smm_variable_service_context(const char *sn) :
-	standalone_service_context(sn),
+	standalone_service_context(sn, RPC_BUFFER_SIZE),
 	m_smm_variable_provider(),
 	m_persistent_store_client(),
 	m_volatile_store(),
diff --git a/components/service/locator/standalone/services/smm-variable/smm_variable_service_context.h b/components/service/locator/standalone/services/smm-variable/smm_variable_service_context.h
index ebdb7b6..011c97a 100644
--- a/components/service/locator/standalone/services/smm-variable/smm_variable_service_context.h
+++ b/components/service/locator/standalone/services/smm-variable/smm_variable_service_context.h
@@ -27,6 +27,9 @@
 
 	static const size_t MAX_VARIABLES = 40;
 
+	/* Use an RPC buffer size that is typical for MM Communicate */
+	static const size_t RPC_BUFFER_SIZE = 64 * 1024;
+
 	struct smm_variable_provider m_smm_variable_provider;
 	struct secure_storage_client m_persistent_store_client;
 	struct mock_store m_volatile_store;
diff --git a/components/service/locator/standalone/standalone_service_context.cpp b/components/service/locator/standalone/standalone_service_context.cpp
index 13b8b1d..c4fda1e 100644
--- a/components/service/locator/standalone/standalone_service_context.cpp
+++ b/components/service/locator/standalone/standalone_service_context.cpp
@@ -14,15 +14,31 @@
 
 
 standalone_service_context::standalone_service_context(const char *sn) :
-    m_sn(sn),
-    m_ref_count(0),
-    m_service_context(),
-    m_rpc_interface(NULL)
+	m_sn(sn),
+	m_ref_count(0),
+	m_rpc_buffer_size_override(0),
+	m_service_context(),
+	m_rpc_interface(NULL)
 {
-    m_service_context.context = this;
-    m_service_context.open = standalone_service_context_open;
-    m_service_context.close = standalone_service_context_close;
-    m_service_context.relinquish = standalone_service_context_relinquish;
+	m_service_context.context = this;
+	m_service_context.open = standalone_service_context_open;
+	m_service_context.close = standalone_service_context_close;
+	m_service_context.relinquish = standalone_service_context_relinquish;
+}
+
+standalone_service_context::standalone_service_context(
+	const char *sn,
+	size_t rpc_buffer_size_override) :
+	m_sn(sn),
+	m_ref_count(0),
+	m_rpc_buffer_size_override(rpc_buffer_size_override),
+	m_service_context(),
+	m_rpc_interface(NULL)
+{
+	m_service_context.context = this;
+	m_service_context.open = standalone_service_context_open;
+	m_service_context.close = standalone_service_context_close;
+	m_service_context.relinquish = standalone_service_context_relinquish;
 }
 
 standalone_service_context::~standalone_service_context()
@@ -32,86 +48,91 @@
 
 void standalone_service_context::init()
 {
-    assert(m_ref_count >= 0);
+	assert(m_ref_count >= 0);
 
-    if (!m_ref_count) do_init();
-    ++m_ref_count;
+	if (!m_ref_count) do_init();
+	++m_ref_count;
 }
 
 void standalone_service_context::deinit()
 {
-    assert(m_ref_count > 0);
+	assert(m_ref_count > 0);
 
-    --m_ref_count;
-    if (!m_ref_count) do_deinit();
+	--m_ref_count;
+	if (!m_ref_count) do_deinit();
 }
 
 rpc_session_handle standalone_service_context::open(struct rpc_caller **caller)
 {
-    struct rpc_session *session = new rpc_session(m_rpc_interface);
-    *caller = session->m_rpc_caller;
-    return static_cast<rpc_session_handle>(session);
+	struct rpc_session *session = new rpc_session(m_rpc_interface, m_rpc_buffer_size_override);
+	*caller = session->m_rpc_caller;
+	return static_cast<rpc_session_handle>(session);
 }
 
 void standalone_service_context::close(rpc_session_handle session_handle)
 {
-    struct rpc_session *session = reinterpret_cast<struct rpc_session*>(session_handle);
-    delete session;
+	struct rpc_session *session = reinterpret_cast<struct rpc_session*>(session_handle);
+	delete session;
 }
 
 const std::string &standalone_service_context::get_service_name() const
 {
-    return m_sn;
+	return m_sn;
 }
 
 struct service_context *standalone_service_context::get_service_context()
 {
-    return &m_service_context;
+	return &m_service_context;
 }
 
 void standalone_service_context::set_rpc_interface(rpc_interface *iface)
 {
-    m_rpc_interface = iface;
+	m_rpc_interface = iface;
 }
 
-standalone_service_context::rpc_session::rpc_session(struct rpc_interface *rpc_interface) :
-    m_direct_caller(),
-    m_rpc_caller()
+standalone_service_context::rpc_session::rpc_session(
+	struct rpc_interface *rpc_interface,
+	size_t rpc_buffer_size_override) :
+	m_direct_caller(),
+	m_rpc_caller()
 {
-    m_rpc_caller = direct_caller_init_default(&m_direct_caller, rpc_interface);
+	m_rpc_caller = (rpc_buffer_size_override) ?
+		direct_caller_init(&m_direct_caller, rpc_interface,
+			rpc_buffer_size_override, rpc_buffer_size_override) :
+		direct_caller_init_default(&m_direct_caller, rpc_interface);
 }
 
 standalone_service_context::rpc_session::~rpc_session()
 {
-    direct_caller_deinit(&m_direct_caller);
+	direct_caller_deinit(&m_direct_caller);
 }
 
 static rpc_session_handle standalone_service_context_open(void *context, struct rpc_caller **caller)
 {
-    rpc_session_handle handle = NULL;
-    standalone_service_context *this_context = reinterpret_cast<standalone_service_context*>(context);
+	rpc_session_handle handle = NULL;
+	standalone_service_context *this_context = reinterpret_cast<standalone_service_context*>(context);
 
-    if (this_context) {
-        handle = this_context->open(caller);
-    }
+	if (this_context) {
+		handle = this_context->open(caller);
+	}
 
-    return handle;
+	return handle;
 }
 
 static void standalone_service_context_close(void *context, rpc_session_handle session_handle)
 {
-    standalone_service_context *this_context = reinterpret_cast<standalone_service_context*>(context);
+	standalone_service_context *this_context = reinterpret_cast<standalone_service_context*>(context);
 
-    if (this_context) {
-        this_context->close(session_handle);
-    }
+	if (this_context) {
+		this_context->close(session_handle);
+	}
 }
 
 static void standalone_service_context_relinquish(void *context)
 {
-    standalone_service_context *this_context = reinterpret_cast<standalone_service_context*>(context);
+	standalone_service_context *this_context = reinterpret_cast<standalone_service_context*>(context);
 
-    if (this_context) {
-        this_context->deinit();
-    }
+	if (this_context) {
+		this_context->deinit();
+	}
 }
diff --git a/components/service/locator/standalone/standalone_service_context.h b/components/service/locator/standalone/standalone_service_context.h
index 2b5de68..64e903d 100644
--- a/components/service/locator/standalone/standalone_service_context.h
+++ b/components/service/locator/standalone/standalone_service_context.h
@@ -7,6 +7,7 @@
 #ifndef STANDALONE_SERVICE_CONTEXT_H
 #define STANDALONE_SERVICE_CONTEXT_H
 
+#include <cstddef>
 #include <service_locator.h>
 #include <rpc/common/endpoint/rpc_interface.h>
 #include <rpc/direct/direct_caller.h>
@@ -16,6 +17,7 @@
 {
 public:
     standalone_service_context(const char *sn);
+    standalone_service_context(const char *sn, size_t rpc_buffer_size_override);
     virtual ~standalone_service_context();
 
     void init();
@@ -37,7 +39,8 @@
 
     struct rpc_session
     {
-        rpc_session(struct rpc_interface *rpc_interface);
+        rpc_session(struct rpc_interface *rpc_interface,
+            size_t rpc_buffer_size_override);
         ~rpc_session();
 
         struct direct_caller m_direct_caller;
@@ -46,6 +49,7 @@
 
     std::string m_sn;
     int m_ref_count;
+    size_t m_rpc_buffer_size_override;
     struct service_context m_service_context;
     struct rpc_interface *m_rpc_interface;
 };
diff --git a/components/service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.c b/components/service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.c
index c18e435..8703157 100644
--- a/components/service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.c
+++ b/components/service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.c
@@ -54,14 +54,15 @@
 
 	request_desc = (struct secure_storage_request_get *)(req->req_buf.data);
 
-	/* Check if the requested data would fit into the response buffer. */
-	if (req->resp_buf.size < request_desc->data_size)
-		return TS_RPC_ERROR_INVALID_RESP_BODY;
+	/* Clip the requested data size if it's too big for the response buffer */
+	size_t data_size = (req->resp_buf.size < data_size) ?
+		req->resp_buf.size :
+		request_desc->data_size;
 
 	psa_status = this_context->backend->interface->get(this_context->backend->context,
 				req->caller_id, request_desc->uid,
 				request_desc->data_offset,
-				request_desc->data_size,
+				data_size,
 				req->resp_buf.data, &req->resp_buf.data_len);
 	call_req_set_opstatus(req, psa_status);
 
@@ -226,7 +227,7 @@
 		goto out;
 
 	service_provider_init(&context->base_provider, context, handler_table,
-			      sizeof(handler_table) / sizeof(handler_table[0]));
+				  sizeof(handler_table) / sizeof(handler_table[0]));
 
 	rpc_interface = service_provider_get_rpc_interface(&context->base_provider);
 
diff --git a/components/service/smm_variable/client/cpp/smm_variable_client.cpp b/components/service/smm_variable/client/cpp/smm_variable_client.cpp
index 2972e1a..a68b7ac 100644
--- a/components/service/smm_variable/client/cpp/smm_variable_client.cpp
+++ b/components/service/smm_variable/client/cpp/smm_variable_client.cpp
@@ -472,7 +472,7 @@
 	return efi_status;
 }
 
-efi_status_t smm_variable_client::get_payload_zize(
+efi_status_t smm_variable_client::get_payload_size(
 	size_t &payload_size)
 {
 	efi_status_t efi_status = EFI_NOT_READY;
diff --git a/components/service/smm_variable/client/cpp/smm_variable_client.h b/components/service/smm_variable/client/cpp/smm_variable_client.h
index f194420..9c36c4e 100644
--- a/components/service/smm_variable/client/cpp/smm_variable_client.h
+++ b/components/service/smm_variable/client/cpp/smm_variable_client.h
@@ -101,7 +101,7 @@
 		size_t override_name_size);
 
 	/* Get maximum variable payload size */
-	efi_status_t get_payload_zize(
+	efi_status_t get_payload_size(
 		size_t &payload_size);
 
 
diff --git a/components/service/smm_variable/test/service/smm_variable_service_tests.cpp b/components/service/smm_variable/test/service/smm_variable_service_tests.cpp
index c8c64ff..d76d9cc 100644
--- a/components/service/smm_variable/test/service/smm_variable_service_tests.cpp
+++ b/components/service/smm_variable/test/service/smm_variable_service_tests.cpp
@@ -64,6 +64,160 @@
 		m_common_guid.Data4[7] = 0x07;
 	}
 
+	/* This test makes the irreversible transition from boot to runtime
+	 * state, leaving a variable that can't be removed. To prevent this from
+	 * breaking the variable enumeration test, this test is called from
+	 * the enumeration test to guarantee the order.
+	 */
+	void runtimeStateAccessControl()
+	{
+		efi_status_t efi_status = EFI_SUCCESS;
+		std::wstring boot_var_name = L"a boot variable";
+		std::string boot_set_data = "Only accessible during boot";
+		std::wstring runtime_var_name = L"a runtime variable";
+		std::string runtime_set_data = "Only accessible during runtime";
+		std::string get_data;
+
+		/* This test can only successfully be run once as it exits
+		 * boot service, blocking access to the added boot variable.
+		 * If the boot variable already exists at the start of the
+		 * test, indicating a subsequent test run, just return.
+		 */
+		efi_status = m_client->get_variable(
+			m_common_guid,
+			boot_var_name,
+			get_data);
+		if (efi_status == EFI_ACCESS_DENIED) return;
+
+		/* Add variables with runtime state access control */
+		efi_status = m_client->set_variable(
+			m_common_guid,
+			boot_var_name,
+			boot_set_data,
+			EFI_VARIABLE_BOOTSERVICE_ACCESS);
+		UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
+
+		efi_status = m_client->set_variable(
+			m_common_guid,
+			runtime_var_name,
+			runtime_set_data,
+			EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS);
+		UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
+
+		/* Expect access to boot variable to be permitted */
+		efi_status = m_client->get_variable(
+			m_common_guid,
+			boot_var_name,
+			get_data);
+		UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
+		UNSIGNED_LONGS_EQUAL(boot_set_data.size(), get_data.size());
+		LONGS_EQUAL(0, get_data.compare(boot_set_data));
+
+		/* Expect access to the runtime variable to be forbidden during boot */
+		efi_status = m_client->get_variable(
+			m_common_guid,
+			runtime_var_name,
+			get_data);
+		UNSIGNED_LONGLONGS_EQUAL(EFI_ACCESS_DENIED, efi_status);
+
+		/* Exit boot service - access should no longer be permitted */
+		efi_status = m_client->exit_boot_service();
+		UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
+
+		/* Access to the boot variablel should now be forbidden */
+		efi_status = m_client->get_variable(
+			m_common_guid,
+			boot_var_name,
+			get_data);
+		UNSIGNED_LONGLONGS_EQUAL(EFI_ACCESS_DENIED, efi_status);
+
+		/* Expect access to the runtime variable to now be permitted */
+		efi_status = m_client->get_variable(
+			m_common_guid,
+			runtime_var_name,
+			get_data);
+		UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
+		UNSIGNED_LONGS_EQUAL(runtime_set_data.size(), get_data.size());
+		LONGS_EQUAL(0, get_data.compare(runtime_set_data));
+
+		/* Expect removing boot variable to be forbidden */
+		efi_status = m_client->remove_variable(m_common_guid, boot_var_name);
+		UNSIGNED_LONGLONGS_EQUAL(EFI_ACCESS_DENIED, efi_status);
+
+		/* Expect removing runtime variable to be permitted */
+		efi_status = m_client->remove_variable(m_common_guid, runtime_var_name);
+		UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
+	}
+
+	/* This test also leaves an unremovable variable */
+	void setReadOnlyConstraint()
+	{
+		efi_status_t efi_status = EFI_SUCCESS;
+		std::wstring var_name_1 = L"ro_variable";
+		std::string set_data = "A read only variable";
+
+		/* Add a variable to the store */
+		efi_status = m_client->set_variable(
+			m_common_guid,
+			var_name_1,
+			set_data,
+			0);
+
+		UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
+
+		/* Apply a check to constrain to Read Only */
+		VAR_CHECK_VARIABLE_PROPERTY check_property;
+		check_property.Revision = VAR_CHECK_VARIABLE_PROPERTY_REVISION;
+		check_property.Attributes = 0;
+		check_property.Property = VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY;
+		check_property.MinSize = 0;
+		check_property.MaxSize = 100;
+
+		efi_status = m_client->set_var_check_property(
+			m_common_guid,
+			var_name_1,
+			check_property);
+		UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
+
+		/* Read back the check property constraint and expect it to match the set value */
+		VAR_CHECK_VARIABLE_PROPERTY got_check_property;
+
+		efi_status = m_client->get_var_check_property(
+			m_common_guid,
+			var_name_1,
+			got_check_property);
+		UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
+
+		UNSIGNED_LONGS_EQUAL(check_property.Revision, got_check_property.Revision);
+		UNSIGNED_LONGS_EQUAL(check_property.Attributes, got_check_property.Attributes);
+		UNSIGNED_LONGS_EQUAL(check_property.Property, got_check_property.Property);
+		UNSIGNED_LONGS_EQUAL(check_property.MinSize, got_check_property.MinSize);
+		UNSIGNED_LONGS_EQUAL(check_property.MaxSize, got_check_property.MaxSize);
+
+		/* Attempt to modify variable */
+		efi_status = m_client->set_variable(
+			m_common_guid,
+			var_name_1,
+			std::string("Different variable data"),
+			0);
+
+		UNSIGNED_LONGLONGS_EQUAL(EFI_WRITE_PROTECTED, efi_status);
+
+		/* Expect to still be able to read variable */
+		std::string get_data;
+
+		efi_status = m_client->get_variable(
+			m_common_guid,
+			var_name_1,
+			get_data);
+
+		UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
+
+		/* Variable value should be unmodified */
+		UNSIGNED_LONGS_EQUAL(set_data.size(), get_data.size());
+		LONGS_EQUAL(0, get_data.compare(set_data));
+	}
+
 	smm_variable_client *m_client;
 	rpc_session_handle m_rpc_session_handle;
 	struct service_context *m_service_context;
@@ -130,86 +284,6 @@
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
 }
 
-TEST(SmmVariableServiceTests, runtimeStateAccessControl)
-{
-	efi_status_t efi_status = EFI_SUCCESS;
-	std::wstring boot_var_name = L"a boot variable";
-	std::string boot_set_data = "Only accessible during boot";
-	std::wstring runtime_var_name = L"a runtime variable";
-	std::string runtime_set_data = "Only accessible during runtime";
-	std::string get_data;
-
-	/* This test can only successfully be run once as it exits
-	 * boot service, blocking access to the added boot variable.
-	 * If the boot variable already exists at the start of the
-	 * test, indicating a subsequent test run, just return.
-	 */
-	efi_status = m_client->get_variable(
-		m_common_guid,
-		boot_var_name,
-		get_data);
-	if (efi_status == EFI_ACCESS_DENIED) return;
-
-	/* Add variables with runtime state access control */
-	efi_status = m_client->set_variable(
-		m_common_guid,
-		boot_var_name,
-		boot_set_data,
-		EFI_VARIABLE_BOOTSERVICE_ACCESS);
-	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
-
-	efi_status = m_client->set_variable(
-		m_common_guid,
-		runtime_var_name,
-		runtime_set_data,
-		EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS);
-	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
-
-	/* Expect access to boot variable to be permitted */
-	efi_status = m_client->get_variable(
-		m_common_guid,
-		boot_var_name,
-		get_data);
-	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
-	UNSIGNED_LONGS_EQUAL(boot_set_data.size(), get_data.size());
-	LONGS_EQUAL(0, get_data.compare(boot_set_data));
-
-	/* Expect access to the runtime variable to be forbidden during boot */
-	efi_status = m_client->get_variable(
-		m_common_guid,
-		runtime_var_name,
-		get_data);
-	UNSIGNED_LONGLONGS_EQUAL(EFI_ACCESS_DENIED, efi_status);
-
-	/* Exit boot service - access should no longer be permitted */
-	efi_status = m_client->exit_boot_service();
-	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
-
-	/* Access to the boot variablel should now be forbidden */
-	efi_status = m_client->get_variable(
-		m_common_guid,
-		boot_var_name,
-		get_data);
-	UNSIGNED_LONGLONGS_EQUAL(EFI_ACCESS_DENIED, efi_status);
-
-	/* Expect access to the runtime variable to now be permitted */
-	efi_status = m_client->get_variable(
-		m_common_guid,
-		runtime_var_name,
-		get_data);
-	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
-	UNSIGNED_LONGS_EQUAL(runtime_set_data.size(), get_data.size());
-	LONGS_EQUAL(0, get_data.compare(runtime_set_data));
-
-	/* Expect removing boot variable to be forbidden */
-	efi_status = m_client->remove_variable(m_common_guid, boot_var_name);
-	UNSIGNED_LONGLONGS_EQUAL(EFI_ACCESS_DENIED, efi_status);
-
-	/* Expect removing runtime variable to be permitted */
-	efi_status = m_client->remove_variable(m_common_guid, runtime_var_name);
-	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
-}
-
 TEST(SmmVariableServiceTests, enumerateStoreContents)
 {
 	efi_status_t efi_status = EFI_SUCCESS;
@@ -274,74 +348,12 @@
 
 	efi_status = m_client->remove_variable(m_common_guid, var_name_3);
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
-}
 
-TEST(SmmVariableServiceTests, setReadOnlyConstraint)
-{
-	efi_status_t efi_status = EFI_SUCCESS;
-	std::wstring var_name_1 = L"ro_variable";
-	std::string set_data = "A read only variable";
-
-	/* Add a variable to the store */
-	efi_status = m_client->set_variable(
-		m_common_guid,
-		var_name_1,
-		set_data,
-		0);
-
-	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
-
-	/* Apply a check to constrain to Read Only */
-	VAR_CHECK_VARIABLE_PROPERTY check_property;
-	check_property.Revision = VAR_CHECK_VARIABLE_PROPERTY_REVISION;
-	check_property.Attributes = 0;
-	check_property.Property = VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY;
-	check_property.MinSize = 0;
-	check_property.MaxSize = 100;
-
-	efi_status = m_client->set_var_check_property(
-		m_common_guid,
-		var_name_1,
-		check_property);
-	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
-
-	/* Read back the check property constraint and expect it to match the set value */
-	VAR_CHECK_VARIABLE_PROPERTY got_check_property;
-
-	efi_status = m_client->get_var_check_property(
-		m_common_guid,
-		var_name_1,
-		got_check_property);
-	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
-
-	UNSIGNED_LONGS_EQUAL(check_property.Revision, got_check_property.Revision);
-	UNSIGNED_LONGS_EQUAL(check_property.Attributes, got_check_property.Attributes);
-	UNSIGNED_LONGS_EQUAL(check_property.Property, got_check_property.Property);
-	UNSIGNED_LONGS_EQUAL(check_property.MinSize, got_check_property.MinSize);
-	UNSIGNED_LONGS_EQUAL(check_property.MaxSize, got_check_property.MaxSize);
-
-	/* Attempt to modify variable */
-	efi_status = m_client->set_variable(
-		m_common_guid,
-		var_name_1,
-		std::string("Different variable data"),
-		0);
-
-	UNSIGNED_LONGLONGS_EQUAL(EFI_WRITE_PROTECTED, efi_status);
-
-	/* Expect to still be able to read variable */
-	std::string get_data;
-
-	efi_status = m_client->get_variable(
-		m_common_guid,
-		var_name_1,
-		get_data);
-
-	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
-
-	/* Variable value should be unmodified */
-	UNSIGNED_LONGS_EQUAL(set_data.size(), get_data.size());
-	LONGS_EQUAL(0, get_data.compare(set_data));
+	/* Now that the enumeration test is completed, it's safe to
+	 * run tests that leavev variables behind.
+	 */
+	runtimeStateAccessControl();
+	setReadOnlyConstraint();
 }
 
 TEST(SmmVariableServiceTests, setSizeConstraint)
@@ -410,7 +422,7 @@
 	size_t max_payload_size = 0;
 
 	/* Expect to read a reasonable size for the variable payload */
-	efi_status = m_client->get_payload_zize(max_payload_size);
+	efi_status = m_client->get_payload_size(max_payload_size);
 
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
 	CHECK_TRUE(max_payload_size >= 1024);