meta-measured updates

I’ve been grinding down updates to meta-measured slowly but surely over these past few days. This was started a while back but slowed to a stop when I got distracted by work on meta-selinux. Last week my work to upgrade the SELinux toolstack was merged upstream so I’m re-focusing on getting meta-measured back in shape. This is a quick run down on the changes.

General Maintenance and Release Tracking

I haven’t been chasing upstream much so most of this work has just been maintenance. The kernel in OE has moved forward with 4.1 the new stable in master. The read-only root file system class was broken when I tried a fresh master build the other day. When jumping in to start a refresh, finding core features broken can be a bit discouraging. Instead of taking on this fix immediately I figured it would be best to create a branch to track the latest release (fido) and get that working first. I’ve always avoided tracking OE releases because I don’t want to give the impression that meta-measured is in any way “stable”, as if having my master branch broken on a regular basis wasn’t a good enough indicator.

Seriously though, I kinda dropped the “chasing master” ball. Having a branch that follows the latest release is a good way to make getting everything up to date and it’s a good insurance policy against future breakage in master. So win / win on that. Fido still has a functional readonly-rootfs class so, for the 2 other people out there who have kicked the tires on meta-measured, fall back to a release branch. My goal is to keep at least one release branch in working order.

There are two changes between fido and the current master that have an impact on meta-measured. The first is the upgrade to GCC5. For the trousers and tpm-tools packages this requires a patch that I’ve gratefully borrowed from the hardworking people over at the Debian project. The other is meta-intel nuking the meta-nuc layer. This is a pretty minor change and I’m now using the measured-intel-corei7-64 that extends the intel-corei7-64 machine from meta-intel on the master branch. Fido still has the NUC machine so I’ll stick to that for Fido.

systemd

The first external submission to meta-measured came in a few months back. This was to add systemd support to the trousers package. I had done something similar to this as part of some work to get meta-measured working with the Edison but it was in the BSP layer. It really shouldn’t have been in the BSP layer to begin and my implementation was a hack regardless. The patch I received that adds this feature directly to meta-measured was well done so I’ve added it directly and removed my hack from the BSP.

The only bit I didn’t like from the patch was a utility script that loaded every TPM module under /lib/modules/$(uname -r). This seems a bit heavy handed given that modern Linux kernels autoload these modules when the device is detected. Pretty minor change though and this is now in meta-measured proper.

IMA and TPM2

I started playing around with configuring IMA a while back as a way to exercise the TPM2 that’s baked into the Minnowboard Max as part of PTT. I don’t have any specific plans to do much with IMA just yet but with the xattrs patches I pushed into meta-selinux I’m hoping to be able to support IMA appraisal. It would be a great use case and demonstration to show the utility of my xattr work with an OE image booting with IMA appraisal enforced from firstboot.

UEFI Breakage

I’ve been saving the bad news for last unfortunately. Somewhere in the changes that have been going on with OE, my bringing meta-measured up to date and flashing the firmware on my IVB NUC, measured-image-bootimg broke. I’m pretty sure this is a problem with the latest firmware for the NUC but that’s a guess. Grub2 comes up OK but tboot doesn’t seem to take over.

In prevous debugging I learned that tboot won’t log to VGA since UEFI doesn’t setup a text console for use by whatever executes after ExitBootServices() is called. It’s frame buffer only in UEFI world I guess. But tboot would still log to a serial device through direct I/O. Not this time though. Once Grub2 kicks off tboot my NUC is unresponsive and I get no additional output. Booting straight to the kernel from grub works fine but going the tboot route through multiboot2 isn’t working.

I’m pretty much out of debugging ideas here. My test system is getting a bit old and it’s the only UEFI system I have for use here so I’m writing this off as a loss for the time being. If anyone out there is testing this on a UEFI system I’d love to hear about whatever results you have to report.

Next steps

I’ve added the contributed systemd support to trousers but I haven’t enabled or tested systemd support for my reference images. This is next on my list of things to do. I’ve got trousers working on a systemd driven image previously in some work to wire a TPM up to an Edison system (more on this in the future hopefully) but I was working on on the reference Edison images. Stay tuned and hopefully I’ll have proper systemd support in the near future.

xattrs in OE rootfs part 2

This is an update on some work from a previous post. My xattr patches sat on the yocto mailing list waiting for meta-selinux maintainers to review them for about a month. I got a bit testy and even commented to another contributor off list about the possible need to fork given the lack of response from maintainers. Turns out that this contributor was using his gmail account but actually works for the same company as the maintainer. So about 24 hours later the maintainers magically reappeared and merged my patches!

I really have no interest in forking and maintaining meta-selinux so this was a win. Hopefully I didn’t look like too much of a jerk in the process … ¯_(ツ)_/¯ After a quick stint in a feature branch my xattr code was merged into meta-selinux master. This is only a step in the process though. These patches really belong in the openembedded-core repository. They can likely be moved with minimal effort on the technical side. Getting traction for these sorts of fringe features upstream however takes a bunch of time though, as demonstrated by the 2 months it took to get this into meta-selinux.

As a strategy I should probably prove out an additional use case beyond SELinux file labels. I did some work on meta-measured a while back to add basic IMA support. I really want to expand this to support IMA appraisal. I’m not a huge fan of local enforcement policies but this use case is a great example of build-time xattr usage that would demonstrate the utility of my xattr patches. This is all food for thought though at this point.

Building and Booting Grub2 for a UEFI System

I’ve been playing around with Grub2 a bit while trying to learn something about UEFI. Long story short: I’m really interested in the current measurement gap between the UEFI environment and the Linux OS. Before I go too far into those details I just wanted to get a quick note up on building Grub2 for a UEFI target, specifcally the x86_64 (aka amd64) target.

WARNING: This post won’t help you get Linux or any other OS booted from Grub. I’m only covering the steps necessary to build Grub for the efi target and setting up a UEFI boot disk to run it. That’s all.

Build

Doing the actual build is the easy part. First things first: get the source from the GNU project website. Then RTFM in the INSTALL file. For my setup, specifying --target and --with-platform. The build goes something like this:

./autogen.sh
./configure --target=x86_64 --with-platform=efi
make

UEFI bootable USB

UEFI is a huge departure from the legacy BIOS world. To keep this post short we won’t spend any time discussing BIOS but if you’ve ever wrestled with fixing a broken grub-pc install you’ll know what I mean. Installing or fixing a UEFI Grub system by comparison is pretty simple:

  1. Format a disk (USB in my case) with a GPT using your favorite partitioning tool.
  2. Create a partition with the appropriate type for UEFI. Unfortunately the name for this type is different depending on which partitioning tool you’re using. I use fdisk and the type is ‘EFI System’. It doesn’t need to be large, just enough to hold the grub executable. I made mine 100M which is extremely large. Make note of the UUID of the partition.
  3. Format the partition as FAT16 or FAT32.

Create the UEFI Executable

This builds everything but we don’t yet have a UEFI executable. To create one you’ll need to run the grub-mkimage utility. This is the root of the build directory and it’s responsible for stitching the grub kernel, core modules and a builtin config to bootstrap grub. Generally you’d only build the minimally necessary grub modules into the UEFI executable but since this is for my debug setup I’m going to build every module in. This makes the executable very large but it’s easier.

Before we can do this we need to grok the idea of the builtin config. Grub needs a hint when it comes to setting up the system. For my purposes all I care about is getting the FAT partition mounted so my config just tells Grub how to find the root partition and what to set as the prefix.

(
  cat < grub-buildin.cfg

The --fs-uuid is pretty self explanitory. The UUID in the above code fragment isn’t the actual UUID of my UEFI system partition. If you’re following along at home you can get the UUID for the FS you created above using the blkid utility. The prefix tells Grub where to look for the grub.cfg configuration. We won’t even supply one here so the system will boot straight to the grub shell.

Since we’ve specified the prefix in the builtin config the -p option below is useless but grub-mkimage throws an error if it’s not provided. The value we pass is obviously wrong but the image produced will still function.

Finally execute the command:

./grub-mkimage -d ./grub-core -o bootx64.efi -O x86_64-efi -c ./grub-buildin.cfg -p /foobar $(find . -name '*.mod' | tr 'n' ' ' | sed -e 's/.mod//g')

Setup the Boot Disk

By default UEFI firmware will look for the bootloader on a disk at /EFI/BOOT/bootx64.efi. So all we need to do is mount our EFI system partition, create the /EFI/BOOT directory and copy the bootx64.efi executable there. In the above command we built in ever module that Grub has so we don’t need to worry about copying over any modules.

And that should do it. Point your system to this USB device, boot up the grub efi executable and you should go straight to a Grub shell. If you want to get an OS up and running on top of this you’ve still got a long way to go. But if you’re like me and just screwing around with grub (more on this later) then you’ve got a pretty good test environment. Now all you need to do is write a quick config to get Grub logging to some serial hardware and crank up the debug output!