libcamera: ipa_manager: Verify IPA module signature

Decide whether to isolate the IPA module using the module signature
instead of its license.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
This commit is contained in:
Laurent Pinchart 2020-03-29 07:12:01 +03:00
parent 4b11facde4
commit eab143ee69
4 changed files with 25 additions and 30 deletions

View file

@ -38,6 +38,8 @@ private:
std::vector<std::string> &files); std::vector<std::string> &files);
unsigned int addDir(const char *libDir, unsigned int maxDepth = 0); unsigned int addDir(const char *libDir, unsigned int maxDepth = 0);
bool isSignatureValid(IPAModule *ipa) const;
static const uint8_t publicKeyData_[]; static const uint8_t publicKeyData_[];
static const PubKey pubKey_; static const PubKey pubKey_;
}; };

View file

@ -37,8 +37,6 @@ public:
bool match(PipelineHandler *pipe, bool match(PipelineHandler *pipe,
uint32_t minVersion, uint32_t maxVersion) const; uint32_t minVersion, uint32_t maxVersion) const;
bool isOpenSource() const;
private: private:
struct IPAModuleInfo info_; struct IPAModuleInfo info_;
std::vector<uint8_t> signature_; std::vector<uint8_t> signature_;

View file

@ -12,6 +12,7 @@
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
#include "file.h"
#include "ipa_module.h" #include "ipa_module.h"
#include "ipa_proxy.h" #include "ipa_proxy.h"
#include "log.h" #include "log.h"
@ -271,12 +272,12 @@ std::unique_ptr<IPAInterface> IPAManager::createIPA(PipelineHandler *pipe,
return nullptr; return nullptr;
/* /*
* Load and run the IPA module in a thread if it is open-source, or * Load and run the IPA module in a thread if it has a valid signature,
* isolate it in a separate process otherwise. * or isolate it in a separate process otherwise.
* *
* \todo Implement a better proxy selection * \todo Implement a better proxy selection
*/ */
const char *proxyName = m->isOpenSource() const char *proxyName = isSignatureValid(m)
? "IPAProxyThread" : "IPAProxyLinux"; ? "IPAProxyThread" : "IPAProxyLinux";
IPAProxyFactory *pf = nullptr; IPAProxyFactory *pf = nullptr;
@ -301,4 +302,23 @@ std::unique_ptr<IPAInterface> IPAManager::createIPA(PipelineHandler *pipe,
return proxy; return proxy;
} }
bool IPAManager::isSignatureValid(IPAModule *ipa) const
{
File file{ ipa->path() };
if (!file.open(File::ReadOnly))
return false;
Span<uint8_t> data = file.map();
if (data.empty())
return false;
bool valid = pubKey_.verify(data, ipa->signature());
LOG(IPAManager, Debug)
<< "IPA module " << ipa->path() << " signature is "
<< (valid ? "valid" : "not valid");
return valid;
}
} /* namespace libcamera */ } /* namespace libcamera */

View file

@ -472,29 +472,4 @@ bool IPAModule::match(PipelineHandler *pipe,
!strcmp(info_.pipelineName, pipe->name()); !strcmp(info_.pipelineName, pipe->name());
} }
/**
* \brief Verify if the IPA module is open source
*
* \sa IPAModuleInfo::license
*/
bool IPAModule::isOpenSource() const
{
static const char *osLicenses[] = {
"GPL-2.0-only",
"GPL-2.0-or-later",
"GPL-3.0-only",
"GPL-3.0-or-later",
"LGPL-2.1-only",
"LGPL-2.1-or-later",
"LGPL-3.0-only",
"LGPL-3.0-or-later",
};
for (unsigned int i = 0; i < ARRAY_SIZE(osLicenses); i++)
if (!strcmp(osLicenses[i], info_.license))
return true;
return false;
}
} /* namespace libcamera */ } /* namespace libcamera */