Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for 6.6.x workstation kernels #45

Merged
merged 13 commits into from
Apr 22, 2024
Merged

Add support for 6.6.x workstation kernels #45

merged 13 commits into from
Apr 22, 2024

Conversation

legoktm
Copy link
Member

@legoktm legoktm commented Mar 25, 2024

Description

Linux 6.6 changed mkdebian, so our previous copy and override would've needed significant work to follow upstream. I think it's easiest to just create our own Debian directory with all the metadata we want, and any future kernel upgrades will require synchronizing debian/rules with what upstream does. This is shown in the current file with two different stanzas for 5.15 and 6.6. The script has gotten sufficiently complex now so I've taken the opportunity to port it to Python and jinja2 templating.

For 6.6, I took the workstation 5.15 config, ran make olddefconfig and then copied over the Qubes kernel config's netfilter part. I also updated the build container to bookworm for these 6.6 builds.

Linux has a concept of "tinyconfig", which is the smallest possible kernel that can be built, which is a good way to test our build infrastructure without taking too much time. Add 5.15 and 6.6 tinyconfigs and use those in CI, cutting it down from about 10-11min to 5min.

Test plan

Run through all the make targets:

  • make tiny-5.15
  • make tiny-6.6
  • make securedrop-core-5.15
  • make securedrop-workstation-5.15
  • make securedrop-workstation-6.6

And then:

  • CI passes
  • Visual review

Copy link
Member Author

@legoktm legoktm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly notes/questions for myself.

Dockerfile Outdated Show resolved Hide resolved
Makefile Show resolved Hide resolved
build-kernel.sh Outdated Show resolved Hide resolved
build-kernel.sh Outdated Show resolved Hide resolved
build-kernel.sh Outdated Show resolved Hide resolved
build-kernel.sh Outdated Show resolved Hide resolved
build-kernel.sh Outdated Show resolved Hide resolved
Package: securedrop-workstation-grsec
Section: admin
Architecture: ${DEBARCH}
Pre-Depends: qubes-kernel-vm-support (>=4.0.31)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume we can drop this now? The 4.1 bookworm VM I have is on 4.1.19+deb12u1 already.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per freedomofpress/securedrop-builder@de34206 this was also only needed for the dkms build, so we can drop it too.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This analysis didn't account for the switch to minimal templates, which are missing this package. So we do need a dependency on qubes-kernel-vm-support, though we can make it unversioned.

debian/control.workstation Outdated Show resolved Hide resolved
grsecurity-urls.py Show resolved Hide resolved
@legoktm
Copy link
Member Author

legoktm commented Mar 27, 2024

For whatever reason, the 6.6.22 kernel doesn't have networking in Qubes with HVM. Here's the diff of kernel modules between a stock Debian bookworm kernel (with working networking) and ours: https://gist.github.com/legoktm/292e4a5dbd0c733d837cb6f0d72c0773

@legoktm
Copy link
Member Author

legoktm commented Mar 27, 2024

The qubes-antispoof.service unit failed, because of network filter errors. Here's the beginning of the error:

Mar 27 18:17:33 d12-test systemd[1]: Starting qubes-antispoof.service - Qubes anti-spoofing firewall rules...
Mar 27 18:17:33 d12-test nft[691]: /etc/qubes/qubes-antispoof.nft:2:1-2: Error: Could not process rule: Operation not supported
Mar 27 18:17:33 d12-test nft[691]: table ip qubes {
Mar 27 18:17:33 d12-test nft[691]: ^^
Mar 27 18:17:33 d12-test nft[691]: /etc/qubes/qubes-antispoof.nft:2:10-14: Error: No such file or directory; did you mean chain ‘prerouting’ in table ip ‘qubes’?
Mar 27 18:17:33 d12-test nft[691]: table ip qubes {
Mar 27 18:17:33 d12-test nft[691]:          ^^^^^
Mar 27 18:17:33 d12-test nft[691]: /etc/qubes/qubes-antispoof.nft:2:10-14: Error: No such file or directory; did you mean chain ‘antispoof’ in table ip ‘qubes’?
Mar 27 18:17:33 d12-test nft[691]: table ip qubes {
Mar 27 18:17:33 d12-test nft[691]:          ^^^^^
Mar 27 18:17:33 d12-test nft[691]: /etc/qubes/qubes-antispoof.nft:2:10-14: Error: No such file or directory; did you mean set ‘downstream’ in table ip ‘qubes’?
Mar 27 18:17:33 d12-test nft[691]: table ip qubes {
Mar 27 18:17:33 d12-test nft[691]:          ^^^^^
Mar 27 18:17:33 d12-test nft[691]: /etc/qubes/qubes-antispoof.nft:2:10-14: Error: No such file or directory; did you mean set ‘allowed’ in table ip ‘qubes’?
Mar 27 18:17:33 d12-test nft[691]: table ip qubes {
Mar 27 18:17:33 d12-test nft[691]:          ^^^^^
Mar 27 18:17:33 d12-test nft[691]: /etc/qubes/qubes-antispoof.nft:2:10-14: Error: Could not process rule: No such file or directory
Mar 27 18:17:33 d12-test nft[691]: table ip qubes {
Mar 27 18:17:33 d12-test nft[691]:          ^^^^^
Mar 27 18:17:33 d12-test nft[691]: /etc/qubes/qubes-antispoof.nft:2:10-14: Error: Could not process rule: No such file or directory
Mar 27 18:17:33 d12-test nft[691]: table ip qubes {
Mar 27 18:17:33 d12-test nft[691]:          ^^^^^
Mar 27 18:17:33 d12-test nft[691]: /etc/qubes/qubes-antispoof.nft:2:10-14: Error: Could not process rule: No such file or directory
Mar 27 18:17:33 d12-test nft[691]: table ip qubes {
Mar 27 18:17:33 d12-test nft[691]:          ^^^^^
Mar 27 18:17:33 d12-test nft[691]: /etc/qubes/qubes-antispoof.nft:2:10-14: Error: Could not process rule: No such file or directory
Mar 27 18:17:33 d12-test nft[691]: table ip qubes {
Mar 27 18:17:33 d12-test nft[691]:          ^^^^^
Mar 27 18:17:33 d12-test nft[691]: /etc/qubes/qubes-antispoof.nft:23:1-2: Error: Could not process rule: Operation not supported
Mar 27 18:17:33 d12-test nft[691]: table ip6 qubes {
Mar 27 18:17:33 d12-test nft[691]: ^^

So the missing networkfilter modules from above are even more suspect:

-nf_conntrack
-nf_defrag_ipv4
-nf_defrag_ipv6
-nf_nat
 nfnetlink
-nf_reject_ipv4
-nf_reject_ipv6
 nf_tables
-nft_chain_nat
-nft_ct
-nft_masq
-nft_reject
-nft_reject_ipv4
-nft_reject_ipv6

@legoktm
Copy link
Member Author

legoktm commented Mar 28, 2024

The newly built kernel (freedomofpress/securedrop-apt-test#225) now has networking on Qubes \o/

@legoktm legoktm force-pushed the kernel-6 branch 2 times, most recently from 615c69f to 5d4b064 Compare March 28, 2024 20:55
@legoktm
Copy link
Member Author

legoktm commented Mar 28, 2024

OK, we now have seemingly functional kernels! The remaining steps here are to add some back-compat for the 5.15 series, since we're planning to keep building those for a while on the server.

@thedeadliestcatch
Copy link

A quick note: I'm not sure why you are pressing on HVM modes, you can actually use Xen's pvh grub.

@thedeadliestcatch
Copy link

The newly built kernel (freedomofpress/securedrop-apt-test#225) now has networking on Qubes \o/

Remember Qubes has transitioned away from iptables. nft is used now instead. I would strongly suggest considering building monolithic kernels with a minimal config. If you transition away from HVM to pvgrub, and even if you don't, it will be a good idea. Removing LKM support has several benefits in terms of reducing attack surface in the kernel for ROP and code injection scenarios (after all, LKM support comes with the implicit need for a dynamic linker in kernel space).

@zenmonkeykstop
Copy link
Contributor

Yup, SDW AppVMs were previously HVM, but looks like we're moving to PVH for the next workstation release on Qubes 4.2, it's working pretty well on a test branch.

@legoktm
Copy link
Member Author

legoktm commented Apr 1, 2024

I would strongly suggest considering building monolithic kernels with a minimal config. If you transition away from HVM to pvgrub, and even if you don't, it will be a good idea. Removing LKM support has several benefits in terms of reducing attack surface in the kernel for ROP and code injection scenarios (after all, LKM support comes with the implicit need for a dynamic linker in kernel space).

This is a good point and something I started wondering about mid-last week, whether there was any benefit to building individual modules. I'll look into doing a monolithic build.

@thedeadliestcatch
Copy link

Yup, SDW AppVMs were previously HVM, but looks like we're moving to PVH for the next workstation release on Qubes 4.2, it's working pretty well on a test branch.

Unrelated to the kernel-builder but remember pvgrub requires a working GRUB bootloader in the virtual disk and some issues might come up (if this is not done properly) when creating qubes from disposable templates with their kernel set to pvgrub. MIght save you time. Use a separate dispvm template from sys-usb and co or you might face a non functional system once dom0 does the USB controller handoff.

@legoktm legoktm force-pushed the kernel-6 branch 2 times, most recently from e466358 to 0d6f913 Compare April 1, 2024 20:54
@legoktm legoktm changed the title WIP: Add support for 6.6.x workstation kernels Add support for 6.6.x workstation kernels Apr 1, 2024
@legoktm
Copy link
Member Author

legoktm commented Apr 1, 2024

OK, marking this as ready for review now. I've split the monolithic kernel suggestion to its own issue.

@zenmonkeykstop
Copy link
Contributor

So far:

  • securedrop-workstation-6.6 built successfully
  • securedrop-core-5.15 does not have a complete config, starts prompting at Enable dynamic slab page orders (SLUB_DYNORDER) [N/y/?] (NEW)

others to follow.

@zenmonkeykstop
Copy link
Contributor

6.6.23-1-grsec-workstation results

  • set up standaloneVM based on debian-12-xfce

  • copied and installed kernel directly (qvm-copy kernelname.deb & apt install ./path/to/deb

  • flipped standaloneVM to PVH with pvgrub2-pvh as kernel, and rebooted

  • booted successfully

  • uname -r reports 6.6.23-1-grsec-workstation

  • paxtest and meltdown.sh test results attached (only fail in the latter is srbds)

testlog.txt

@legoktm
Copy link
Member Author

legoktm commented Apr 3, 2024

securedrop-core-5.15 does not have a complete config, starts prompting at Enable dynamic slab page orders (SLUB_DYNORDER) [N/y/?] (NEW)

The 6.6 build command runs make olddefconfig all, so the config file will be up to date, so I removed the explicit make olddefconfig from the script but didn't add it back in for 5.15. To quickly verify this, I generated a 5.15.16 tinyconfig that is missing settings (will commit), did a build and ran into the same config prompt. I then added make olddefconfig to the 5.15 d/rules part, and now the tiny-5.15 build works fine.

@legoktm
Copy link
Member Author

legoktm commented Apr 3, 2024

Some reproducibility issue seems to have snuck in...debugging.

New configuration was generated by taking the old 5.15 config,
taking a 6.6.22 grsec-patched kernel tree and running `make xen.config`
and then `make olddefconfig` in a bookworm VM.
We are missing netfilter modules that the Qubes firewall/network needs,
so copy their config directly:
<https://github.com/QubesOS/qubes-linux-kernel/blob/b93840a3c8254c696bc3fedcb792bb3ed99bfa19/config-base>.
Reduce the diff between the two. We can't eliminate it fully, but there
are no superificial differences anymore.
Build on bookworm so we can take advantage of newer gcc and the
hardening features they bring.
Instead of dynamically generating the debian/ packaging information,
just keep our own. This will hopefully make future upgrades easier since
we'll just need to synchronize the d/rules file.

Instead of continuing to use increasingly complex shell scripts, take
the opportunity to port build-kernel.sh to Python and use jinja2 for
templating the dynamic parts of the debian/ folder.

Take the opportunity to start xz-compressing the orig tarballs. This
brings us in line with stable kernel releases and allows us to reuse
upstream tarballs when possible (implemented in a later commit).
* Allow varying the base distro in the Dockerfile
* Add conditionals to d/rules to vary how we build the kernel packages
* Add tinyconfig from 5.15.16, intentionally using an old version that
  has missing settings
To avoid repacking the kernel source on non-grsec builds, we can reuse
the upstream tarball. The only thing we modify in the kernel source is
`.config`, which we can place in the debian/ directory.
* Build tinyconfig kernels instead of "vanilla" ones for speed
* Have one job build both times instead of duplicating into a second job
* Use diffoscope on the .changes file but ignore the buildinfo file
* Install xz-utils so the packages can be diffed instead of hexdumped
@legoktm
Copy link
Member Author

legoktm commented Apr 9, 2024

I better documented the changes around xz and rebased and signed this commit stack.

libelf-dev is a leftover from the u2mn kernel module builds that we
needed on buster/4.0 but haven't since.

Switch qubes-kernel-vm-support to an unversioned `Depends` as it's
only needed in the postinst and the necessary version is already in
both bullseye and bookworm.
rocodes
rocodes previously approved these changes Apr 17, 2024
Copy link
Contributor

@rocodes rocodes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good sleuthing, and thank you!

@rocodes
Copy link
Contributor

rocodes commented Apr 19, 2024

Tacked on 2 wee commits:

@legoktm
Copy link
Member Author

legoktm commented Apr 19, 2024

Both of your commits LGTM, thanks. (I still don't understand the Pre-Depends vs Depends, I will take some time next week to better understand the dependency.)

@rocodes
Copy link
Contributor

rocodes commented Apr 22, 2024

Per internal chat, kernels looking good, gonna merge -thanks @legoktm and team for all your work on this

@rocodes rocodes merged commit 32dae88 into main Apr 22, 2024
12 checks passed
@legoktm legoktm deleted the kernel-6 branch April 22, 2024 15:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
4 participants