Hello Przemek!
Thanks for joining this discussion.
This is a valid design pattern and you did very impressive things with
it, but it’s not compatible with the basic design of Linux hardware
integration: I don’t know of a single mainline kernel driver designed
this way.
What are you talking about here? Is it libpruio? libpruio isn’t a kernel driver, it’s a userspace library. Jason Kridner wanted to make it mainline, but nothing happened yet. Currently it’s an optional OpenSource package.
… e.g. by disallowing full control of the entire physical address space.
How? We’re talking about the PRUSS (= Programable Realtime Unit SubSystems). They haven’t been designed with security in mind. There’s no way to disallow control of any address space. Again, the PRUSS can access !ALL! CPU memory, indeed also kernel space.
The only way to protect a system against PRU malware is to disable the PRUSS. Not only once, the kernel has to disable them again and again on a regular basis, before any virus can get loaded and executed on any PRU. I don’t see any other way to gain classic Linux security on a board with PRUSS. This is how a secure standard image should work: no PRUSS support at all.
Users who want to benefit from the PRUSS should get informed about the riscs and should install optional drivers to get PRUSS support. I cannot understand how a PRUSS driver can find its way to a standard installation. And I cannot understand how this driver can be enabled by default. And much more, I canot understand why this default driver wasn’t designed with security in mind, in order to work around the hardware unsecurity. This is a massive safety risc, implemented in all TI kernels since major version 4, threatening all SoC families.
On BB it’s pretty bad: the default cape_universal overlay enables the PRUSS and loads the remoteproc driver. And this driver autoloads any malware at boot time. Your system will be hacked before you see any prompt. An agressor only needs to copy a single file and the operation system in standard configuration does the rest, loading and starting the malware at boot time. Not just a simple userspace virus. No, well defined interfaces open doors for PRU malware to infect kernel space.
I’m no expert in virus development, but I’m sure it can work as simple as
- PRU searches the CPU memory for RPMsg driver instructions.
- PRU overrides these instructions by ARM malware.
- PRU triggers a message.
- Now the ARM malware is running in kernel space.
Each interface, like vring or even a simple interrupt handler, is an open door which a PRU virus can use to implement and trigger malware on the ARM side. With this in mind, we all should reconsider the question:
Do we really need PRU support from kernel space? If so, is it all of us?
William said:
The proper solution is to make the remoteproc project as if it’s a working module NOW. Loadable module, that can play nice with the rest of the module world. Then mark it as experimental. Worry about the actual remoteproc implementation after that.
BR
@John
If RPMSG implements mmap(), then we might have a solution that should works for TJF.
You’re again thinking in the wrong direction. It doesn’t matter what you or anybody else add to this framework. It’ll never work for me, since I care about security. The only way to gain a little bit of safety is to remove unsave features.
Regarding PRUSS, for me the best security strategy is that PRU code should never be able to estimate how the software on the ARM side is working. And the number of options to trigger software on the ARM by PRU should be as small as possible, in best case no options at all. (Even then a PRU virus can use brute force attacks to implement kernel or userspace malware, but such a virus activity is more likely to get found. A kernel space virus can work for a long period of time before you even notice it.)
BR