Authenticate nanoapps loaded on FreeRTOS
Adds logic needed to ensure nanoapps are signed properly before loading
them onto a device. At the moment, this logic has no effect since
nanoapps aren't signed yet.
Bug: 158713869
Test: Load CHRE and verify an authentication response is received
Change-Id: I60d36ddf80a180bb78a47c6b47357959f29e8dee
diff --git a/platform/freertos/include/chre/target_platform/condition_variable_base.h b/platform/freertos/include/chre/target_platform/condition_variable_base.h
index 382954e..d290c62 100644
--- a/platform/freertos/include/chre/target_platform/condition_variable_base.h
+++ b/platform/freertos/include/chre/target_platform/condition_variable_base.h
@@ -47,6 +47,13 @@
* is an extra iteration of the while-empty-queue loop.
*/
class ConditionVariableBase {
+ public:
+ /**
+ * While in an interrupt context, unblock one thread that is waiting on this
+ * condition variable.
+ */
+ void notify_one_from_isr();
+
protected:
// Since, per CHRE specification, only one thread is ever
// going to be blocked on this condition variable, all we
diff --git a/platform/freertos/include/chre/target_platform/condition_variable_impl.h b/platform/freertos/include/chre/target_platform/condition_variable_impl.h
index 296738e..54adf21 100644
--- a/platform/freertos/include/chre/target_platform/condition_variable_impl.h
+++ b/platform/freertos/include/chre/target_platform/condition_variable_impl.h
@@ -72,6 +72,12 @@
return !mTimedOut;
}
+inline void ConditionVariableBase::notify_one_from_isr() {
+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+ xSemaphoreGiveFromISR(mCvSemaphoreHandle, &xHigherPriorityTaskWoken);
+ portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
+}
+
} // namespace chre
#endif // CHRE_PLATFORM_FREERTOS_CONDITION_VARIABLE_IMPL_H_
diff --git a/platform/freertos/platform_nanoapp.cc b/platform/freertos/platform_nanoapp.cc
index 80fbf17..180c879 100644
--- a/platform/freertos/platform_nanoapp.cc
+++ b/platform/freertos/platform_nanoapp.cc
@@ -21,6 +21,7 @@
#include "chre/platform/assert.h"
#include "chre/platform/log.h"
+#include "chre/platform/shared/authentication.h"
#include "chre/platform/shared/memory.h"
#include "chre/platform/shared/nanoapp_dso_util.h"
#include "chre/platform/shared/nanoapp_loader.h"
@@ -248,8 +249,19 @@
if (mIsStatic) {
success = true;
} else if (mAppBinary != nullptr) {
+ //! The true start of the binary will be after the authentication header.
+ //! Use the returned value from authenticateBinary to ensure dlopenbuf has
+ //! the starting address to a valid ELF.
+ void *binaryStart = mAppBinary;
+
+ // TODO(158770259): Enforce this and make the log message and error once all
+ // nanoapp binaries are signed.
+ if (!authenticateBinary(mAppBinary, &binaryStart)) {
+ LOGV("Unable to authenticate 0x%" PRIx32 " not stopping loading for now",
+ mExpectedAppId);
+ }
if (mDsoHandle == nullptr) {
- mDsoHandle = dlopenbuf(mAppBinary, mExpectedTcmCapable);
+ mDsoHandle = dlopenbuf(binaryStart, mExpectedTcmCapable);
success = verifyNanoappInfo();
} else {
LOGE("Trying to reopen an existing buffer");
diff --git a/platform/shared/include/chre/platform/shared/authentication.h b/platform/shared/include/chre/platform/shared/authentication.h
new file mode 100644
index 0000000..6409b47
--- /dev/null
+++ b/platform/shared/include/chre/platform/shared/authentication.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CHRE_PLATFORM_SHARED_AUTHENTICATION_H_
+#define CHRE_PLATFORM_SHARED_AUTHENTICATION_H_
+
+namespace chre {
+
+/**
+ * Authenticates the signature of the provided binary. If not provided
+ * elsewhere by the platform, this method must ensure that nanoapps are signed
+ * appropriately and no corruption has occurred to the binary prior to being
+ * loaded. If this method succeeds, CHRE will assume the binary has the same
+ * execution privileges as the core framework itself.
+ *
+ * @param binary Pointer to the binary that should be authenticated.
+ * @param realBinaryStart A non-null pointer that, if this method succeeds, must
+ * be filled with the starting address of the raw binary after any headers
+ * used by the authentication code. This will be passed to the dynamic
+ * loader which will assume the starting address is a valid ELF binary.
+ * @return True if the binary passed authentication.
+ */
+bool authenticateBinary(void *binary, void **realBinaryStart);
+
+} // namespace chre
+
+#endif // CHRE_PLATFORM_SHARED_AUTHENTICATION_H_