Most of the time when you’re distributing firmware you have permission from the OEM or ODM to redistribute the non-free parts of the system firmware, e.g. Dell can re-distribute the proprietary Intel Management Engine as part as the firmware capsule that gets flashed onto the hardware. In some cases that’s not possible, for example for smaller vendors or people selling OpenHardware. In this case I’m trying to help Purism distribute firmware updates for their hardware, and they’re only able to redistribute the Free Software coreboot part of the firmware. For reasons (IFD, FMAP and CBFS…) you need to actually build the target firmware on the system you’re deploying onto, where build means executing random low-level tools to push random blobs of specific sizes into specific unnecessarily complex partition formats rather than actually compiling
.c into executable code. The current solution is a manually updated interactive bash script which isn’t awesome from a user-experience or security point of view. The other things vendors have asked for in the past is a way to “dd” a few bytes of randomness into the target image at a specific offset and also to copy the old network MAC address into the new firmware. I figured fwupd should probably handle this somewhat better than a random bash script running as root on your live system.
I’ve created a branch that allows you to ship an archive (I’m suggesting using the simple .tar format, as the .cab file will be compressed already) within the
.cab file as the main “release”. Within the
.tar archive will be a
startup.sh file and all the utilities or scripts needed to run the build operation, statically linked if required. At firmware deploy time fwupd will explode the tar file into a newly-created temp directory, create a bubblewrap container which has no network and limited file-system access and then run the
startup.sh script. Once complete, fwupd will copy out just the
firmware.bin file and then destroy the bubblewrap container and the temporary directory. I’ve not yet worked out how to inject some things into the jail, for instance we sometimes need the old system firmware blob if we’re applying a
bsdiff rather than just replacing all the data. I’m tempted to just mount
/var/lib/fwupd/builder/ into the jail as read-only and then get the fwupd plugin to create the required data there at startup before the jail gets created.
Not awesome, but more reliable and secure than just running random bash files as root. Comments welcome.