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

Creates Focal-specific kernel metapackage #5691

Merged
merged 3 commits into from
Jan 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,8 @@ securedrop_app_rsync_opts:
- "--exclude=*aths"
- "--exclude=*.deb"
- "--exclude=*.j2"

package_name: ""
package_dirname: "{{ package_name }}"
package_path: "{{ role_path }}/../../../{{ package_dirname }}/"
build_path: "{{ securedrop_generic_build_path }}/{{ package_name }}"
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
---
- name: Reduce weird path re-usage
set_fact:
package_path: "{{ role_path }}/../../../{{ package_name }}/"
build_path: "{{ securedrop_generic_build_path }}/{{ package_name }}"
- name: Ensure package name is set
assert:
that: package_name != ""

- name: Ensure build directory in-place
file:
Expand All @@ -21,8 +20,7 @@

- name: Find any jinja templates
find:
# No longer seeing the `package_path` variable - seems like a bug
paths: "{{ role_path }}/../../../{{ package_name }}/"
paths: "{{ package_path }}/"
patterns: "*.j2"
recurse: yes
become: no
Expand All @@ -38,7 +36,8 @@
- name: Template out any jinja files found and copy over
template:
src: "{{ item.path }}"
dest: "{{ build_path }}/{{ item.path | regex_replace('^\\/.*'+package_name, '') | regex_replace ('\\.j2$','') }}"
dest: "{{ build_path }}/{{ item.path | regex_replace('^\\/.*'+package_dirname, '') | regex_replace ('\\.j2$','') }}"
mode: "{{ '0755' if 'postinst' in item.path|basename else '0644' }}"
with_items: "{{ jinja_files_found.files }}"

- name: run bash script to build generic packages
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
state: latest
async: 500
poll: 10
when: not install_local_packages|default(False)
tags:
- apt
- grsec
Expand All @@ -42,6 +43,7 @@
# Read-only task for
changed_when: false
register: grsec_str
when: ansible_distribution_release == "xenial"
tags:
- grsec
- kernel
Expand All @@ -51,6 +53,7 @@
stat:
path: /boot/grub/grubenv
register: grubenv_check_initial_result
when: ansible_distribution_release == "xenial"
tags:
- grsec
- grub
Expand All @@ -63,6 +66,7 @@
# so "changed" status can only be determined by comparing
# checksums on that file. We'll do so in the subsequent task.
changed_when: false
when: ansible_distribution_release == "xenial"
tags:
- grsec
- grub
Expand All @@ -80,6 +84,7 @@
register: grubenv_check_configured_result
changed_when: grubenv_check_initial_result.stat.checksum !=
grubenv_check_configured_result.stat.checksum
when: ansible_distribution_release == "xenial"
tags:
- grsec
- grub
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
- name: Copy locally built securedrop-grsec metapackage
copy:
src: "../../build/{{ ansible_distribution_release }}/securedrop-grsec-{{ securedrop_pkg_grsec.ver }}{{ '+focal' if securedrop_staging_install_target_distro|default('') == 'focal' else '' }}-amd64.deb"
dest: /root/securedrop-grsec.deb

- name: Install locally built securedrop-grsec metapackage
command: apt-get install -y -f /root/securedrop-grsec.deb
5 changes: 5 additions & 0 deletions install_files/ansible-base/roles/grsecurity/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
tags:
- grsec

- include: from_local_pkg_install_grsec.yml
when: install_local_packages|default(False)
tags:
- grsec

- include: clean_packages.yml

- include: apply_grsec_lock.yml
Expand Down
12 changes: 12 additions & 0 deletions install_files/securedrop-grsec-focal/DEBIAN/control.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Package: securedrop-grsec
Source: securedrop-grsec
Version: {{ securedrop_pkg_grsec.ver }}+{{ ansible_distribution_release }}
Architecture: amd64
Maintainer: SecureDrop Team <securedrop@freedom.press>
Depends: {{ securedrop_pkg_grsec.depends }},paxctld
Section: admin
Priority: optional
Homepage: https://securedrop.org
Description: Metapackage providing a grsecurity-patched Linux kernel for use
with SecureDrop. Depends on the most recently built patched kernel maintained
by FPF. Package also includes sysctl and PaX flags calls for GRUB.
66 changes: 66 additions & 0 deletions install_files/securedrop-grsec-focal/DEBIAN/postinst.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/bin/sh
# postinst script for securedrop-grsec
#
# see: dh_installdeb(1)
set -e
set -x
# summary of how this script can be called:
# * <postinst> `configure' <most-recently-configured-version>
# * <old-postinst> `abort-upgrade' <new version>
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
# <new-version>
# * <postinst> `abort-remove'
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
# <failed-install-package> <version> `removing'
# <conflicting-package> <version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package

# Pin current version of custom kernel
GRSEC_VERSION="{{ securedrop_pkg_grsec.ver }}-grsec-securedrop"

# Sets default grub boot parameter to the kernel version specified
# by $GRSEC_VERSION.
set_grub_default() {
GRUB_OPT="'Advanced options for Ubuntu>Ubuntu, with Linux $GRSEC_VERSION'"
perl -pi -e "s|^GRUB_DEFAULT=.*|GRUB_DEFAULT=$GRUB_OPT|" /etc/default/grub

# When using CONFIG_PAX_KERNEXEC, the grsecurity team recommends the kernel
# is booted with "noefi" on the kernel command line if "CONFIG_EFI" is
# enabled, as EFI runtime services are necessarily mapped as RWX.
sed -i '/^GRUB_CMDLINE_LINUX_DEFAULT=/s/=.*/=\"noefi\"/' /etc/default/grub
update-grub
}

# Ensure the paxctld daemon is running
start_paxctld() {
cp -v /opt/securedrop/paxctld.conf /etc/paxctld.conf
systemctl enable paxctld
systemctl restart paxctld
# Wait just a moment while flags are re-applied
sleep 1
}

case "$1" in
configure)
# Configure paxctld, required before update-grub runs
start_paxctld
# Ensure latest grsec kernel is used on every boot.
set_grub_default
;;

abort-upgrade|abort-remove|abort-deconfigure)
;;

*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac

# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.

#DEBHELPER#

exit 0
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# disables smt and provide full mds mitigations
# see https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/mds.html
GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX mds=full,nosmt"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
vm.heap_stack_gap=1048576
117 changes: 117 additions & 0 deletions install_files/securedrop-grsec-focal/opt/securedrop/paxctld.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# This file was provisioned via securedrop-workstation-svs-disp
# grub

/usr/bin/grub-script-check E
/usr/bin/grub-bios-setup E
/usr/sbin/grub-mkdevicemap E
/usr/sbin/grub-probe E

# qemu
/usr/bin/qemu-alpha m
/usr/bin/qemu-arm m
/usr/bin/qemu-armeb m
/usr/bin/qemu-cris m
/usr/bin/qemu-i386 m
/usr/bin/qemu-m68k m
/usr/bin/qemu-microblaze m
/usr/bin/qemu-microblazeel m
/usr/bin/qemu-mips m
/usr/bin/qemu-mips64 m
/usr/bin/qemu-mips64el m
/usr/bin/qemu-mipsel m
/usr/bin/qemu-mipsn32 m
/usr/bin/qemu-mipsn32el m
/usr/bin/qemu-or32 m
/usr/bin/qemu-ppc m
/usr/bin/qemu-ppc64 m
/usr/bin/qemu-ppc64abi32 m
/usr/bin/qemu-s390x m
/usr/bin/qemu-sh4 m
/usr/bin/qemu-sh4eb m
/usr/bin/qemu-sparc m
/usr/bin/qemu-sparc32plus m
/usr/bin/qemu-sparc64 m
/usr/bin/qemu-unicore32 m
/usr/bin/qemu-x86_64 m

/usr/bin/qemu-system-aarch64 m
/usr/bin/qemu-system-alpha m
/usr/bin/qemu-system-arm m
/usr/bin/qemu-system-cris m
/usr/bin/qemu-system-i386 m
/usr/bin/qemu-system-lm32 m
/usr/bin/qemu-system-m68k m
/usr/bin/qemu-system-microblaze m
/usr/bin/qemu-system-microblazeel m
/usr/bin/qemu-system-mips m
/usr/bin/qemu-system-mips64 m
/usr/bin/qemu-system-mips64el m
/usr/bin/qemu-system-mipsel m
/usr/bin/qemu-system-moxie m
/usr/bin/qemu-system-or32 m
/usr/bin/qemu-system-ppc m
/usr/bin/qemu-system-ppc64 m
/usr/bin/qemu-system-ppcemb m
/usr/bin/qemu-system-s390x m
/usr/bin/qemu-system-sh4 m
/usr/bin/qemu-system-sh4eb m
/usr/bin/qemu-system-sparc m
/usr/bin/qemu-system-sparc64 m
/usr/bin/qemu-system-unicore32 m
/usr/bin/qemu-system-x86_64 m
/usr/bin/qemu-system-xtensa m
/usr/bin/qemu-system-xtensaeb m

# skype
/usr/lib/skype/skype m
/usr/lib32/skype/skype m

# steam
/usr/lib32/ld-linux.so.2 m

# node
/usr/bin/node m

# chrome
/opt/google/chrome/chrome-sandbox m
/opt/google/chrome/nacl_helper m
/opt/google/chrome/chrome m

# chromium
/usr/lib/chromium-browser/chromium-browser m

# firefox
/usr/lib/firefox/firefox m
/usr/lib/firefox/plugin-container m

# webapp-container
/usr/bin/webapp-container m

# oxide
/usr/lib/x86_64-linux-gnu/oxide-qt/oxide-renderer m

# valgrind
/usr/bin/valgrind m

# python
/usr/bin/python2.7 E
/usr/bin/python3.5 E

# java
/usr/lib/jvm/java-6-sun-1.6.0.10/jre/bin/java m
/usr/lib/jvm/java-6-sun-1.6.0.10/jre/bin/javaws m
/usr/lib/jvm/java-6-openjdk/jre/bin/java m
/usr/lib/jvm/java-6-openjdk/jre/bin/java m
/usr/lib/jvm/java-8-openjdk/jre/bin/java m
/usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java m
# openrc
/lib/rc/bin/lsb2rcconf E

# libreoffice
# Ubuntu doesn't seem to carry this patch:
# https://bz.apache.org/ooo/show_bug.cgi?id=80816
# libreoffice will still run fine without the below line,
# but it will report an RWX mprotect attempt
# /usr/lib/libreoffice/program/soffice.bin m

/usr/bin/totem m
1 change: 1 addition & 0 deletions molecule/builder-focal/playbook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
- role: build-generic-pkg
tags: securedrop-grsec
package_name: securedrop-grsec
package_dirname: securedrop-grsec-focal
when: ansible_host.endswith("-sd-grsec") or ansible_host == "localhost"

- role: build-generic-pkg
Expand Down
17 changes: 14 additions & 3 deletions molecule/builder-xenial/tests/test_securedrop_deb_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,16 @@ def make_deb_paths() -> Dict[str, Path]:
Jinja-based evaluation of the YAML files (so we can't trivially
reuse vars in other var values, as is the case with Ansible).
"""
grsec_version = securedrop_test_vars["grsec_version"]
if SECUREDROP_TARGET_PLATFORM == "focal":
grsec_version = grsec_version+"+focal"

substitutions = dict(
securedrop_version=securedrop_test_vars["securedrop_version"],
ossec_version=securedrop_test_vars["ossec_version"],
keyring_version=securedrop_test_vars["keyring_version"],
config_version=securedrop_test_vars["config_version"],
grsec_version=securedrop_test_vars["grsec_version"],
grsec_version=grsec_version,
securedrop_target_platform=securedrop_test_vars["securedrop_target_platform"],
)

Expand Down Expand Up @@ -405,10 +409,17 @@ def test_grsec_metapackage(host: Host):

c = host.run("dpkg-deb --contents {}".format(deb_paths["securedrop_grsec"]))
contents = c.stdout
if SECUREDROP_TARGET_PLATFORM == "xenial":
# Post-install kernel hook for managing PaX flags must exist.
assert re.search(r"^.*\./etc/kernel/postinst.d/paxctl-grub$", contents, re.M)
# Config file for paxctld should not be present
assert not re.search(r"^.*\./opt/securedrop/paxctld.conf$", contents, re.M)
else:
assert not re.search(r"^.*\./etc/kernel/postinst.d/paxctl-grub$", contents, re.M)
assert re.search(r"^.*\./opt/securedrop/paxctld.conf$", contents, re.M)

# Custom sysctl options should be present
assert re.search(r"^.*\./etc/sysctl.d/30-securedrop.conf$", contents, re.M)
# Post-install kernel hook for managing PaX flags must exist.
assert re.search(r"^.*\./etc/kernel/postinst.d/paxctl-grub$", contents, re.M)


def test_control_helper_files_are_present(host: Host):
Expand Down
15 changes: 15 additions & 0 deletions molecule/testinfra/common/test_grsecurity.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,21 @@ def test_pax_flags(host, binary):
assert "MPROTECT is disabled" not in c.stdout


def test_paxctld(host):
"""
Ensures that paxctld is configured and running. Only relevant
for Focal hosts.
"""
if host.system_info.codename == "xenial":
return True
assert host.package("paxctld").is_installed
assert host.file("/etc/paxctld.conf").is_file
assert host.file("/opt/securedrop/paxctld.conf").is_file
s = host.service("paxctld")
assert s.is_enabled
assert s.is_running


@pytest.mark.parametrize('kernel_opts', [
'WLAN',
'NFC',
Expand Down