Add SELinux feature 90/27790/2
authorScott Murray <scott.murray@konsulko.com>
Mon, 25 Jul 2022 18:23:13 +0000 (14:23 -0400)
committerJan-Simon Moeller <jsmoeller@linuxfoundation.org>
Wed, 27 Jul 2022 12:31:58 +0000 (12:31 +0000)
Add agl-selinux feature to enable SELinux support.

Notes:
- SELinux is in permissive mode by default for now, and using the
  targeted policy by default.
- The linux-yocto specific bbappend in meta-selinux is masked out in
  favor of adding a more universal kernel configuration fragment with
  AGL's own scheme.
- SELinux specific recipes and bbappends are added via a meta-selinux
  dynamic-layers addition in meta-agl-core to keep using meta-selinux
  optional.  This will avoid issues with the Yocto autobuilder testing
  of meta-agl-core.
- To avoid the effectively hard-coded autorelabel on first boot, a
  bbappend is added to the selinux-autorelabel recipe to remove the
  flag creation.  In the off chance that a build happens on a filesystem
  without xattr support, the logic in the selinux-image bbclass will
  still touch the /.autorelabel flag and trigger relabeling.
- A systemd unit and script are added with a new systemd-selinux-relabel
  recipe to handle relabeling of some systemd generated files that do
  not get handled during root filesystem construction.  Some of these
  can be addressed by some upstream tweaks, but /etc/machine-id will
  always need special handling unless there is a shift to using
  read-only or stateless root by default.  With this workaround we still
  avoid doing a full relabel and reboot on first boot, which helps
  simplify CI.

Bug-AGL: SPEC-4332

Signed-off-by: Scott Murray <scott.murray@konsulko.com>
Change-Id: Ibf469e11eb3a67709074cc6794b3d12cd5071a90
Reviewed-on: https://gerrit.automotivelinux.org/gerrit/c/AGL/meta-agl/+/27790
Tested-by: Jenkins Job builder account
ci-image-build: Jenkins Job builder account
ci-image-boot-test: Jenkins Job builder account
Reviewed-by: Jan-Simon Moeller <jsmoeller@linuxfoundation.org>
14 files changed:
meta-agl-core/conf/include/agl-selinux.inc [new file with mode: 0644]
meta-agl-core/conf/layer.conf
meta-agl-core/dynamic-layers/meta-selinux/recipes-core/systemd/files/systemd-selinux-relabel.service [new file with mode: 0644]
meta-agl-core/dynamic-layers/meta-selinux/recipes-core/systemd/files/systemd-selinux-relabel.sh [new file with mode: 0644]
meta-agl-core/dynamic-layers/meta-selinux/recipes-core/systemd/systemd-selinux-relabel_1.0.bb [new file with mode: 0644]
meta-agl-core/dynamic-layers/meta-selinux/recipes-platform/packagegroups/packagegroup-agl-core-selinux.bb [new file with mode: 0644]
meta-agl-core/dynamic-layers/meta-selinux/recipes-security/selinux-scripts/selinux-autorelabel_0.1.bbappend [new file with mode: 0644]
meta-agl-core/dynamic-layers/meta-selinux/recipes-security/selinux-scripts/selinux-autorelabel_aglcore.inc [new file with mode: 0644]
meta-agl-core/recipes-kernel/linux/linux-agl-config.inc
meta-agl-core/recipes-kernel/linux/linux/selinux.cfg [new file with mode: 0644]
meta-agl-core/recipes-platform/images/agl-image-boot.inc
templates/feature/agl-selinux/50_bblayers.conf.inc [new file with mode: 0644]
templates/feature/agl-selinux/50_local.conf.inc [new file with mode: 0644]
templates/feature/agl-selinux/README_feature_agl-selinux.md [new file with mode: 0644]

diff --git a/meta-agl-core/conf/include/agl-selinux.inc b/meta-agl-core/conf/include/agl-selinux.inc
new file mode 100644 (file)
index 0000000..aeb26e3
--- /dev/null
@@ -0,0 +1,20 @@
+DISTRO_FEATURES:append = " acl xattr selinux"
+
+# Reiterate the upstream default of targeted policy since that
+# is the mostly widely used model, and it will likely be easier
+# to pull policy from other distributions for it.
+# Having an explicit setting here seems useful for documentation
+# purposes, and it is still possible that using one of the other
+# refpolicy package options as the AGL default desirable, and it
+# would be set here.
+PREFERRED_PROVIDER_virtual/refpolicy ?= "refpolicy-targeted"
+
+# Default to permissive mode
+DEFAULT_ENFORCING ?= "permissive"
+
+# Override the base image class to get the SELinux labeling hook
+AGL_BASE_IMAGE ?= "selinux-image"
+
+# Mask out meta-selinux's linux-yocto kernel config bbappend to
+# avoid collision with AGL's own more universal scheme.
+BBMASK += "meta-selinux/recipes-kernel/linux/"
\ No newline at end of file
index 2749aec..ddea256 100644 (file)
@@ -13,6 +13,9 @@ BBFILES_DYNAMIC += " \
     openembedded-layer:${LAYERDIR}/dynamic-layers/meta-oe/*/*/*.bb \
     openembedded-layer:${LAYERDIR}/dynamic-layers/meta-oe/*/*/*.bbappend \
     \
     openembedded-layer:${LAYERDIR}/dynamic-layers/meta-oe/*/*/*.bb \
     openembedded-layer:${LAYERDIR}/dynamic-layers/meta-oe/*/*/*.bbappend \
     \
+    selinux:${LAYERDIR}/dynamic-layers/meta-selinux/*/*/*.bb \
+    selinux:${LAYERDIR}/dynamic-layers/meta-selinux/*/*/*.bbappend \
+    \
     qt5-layer:${LAYERDIR}/dynamic-layers/meta-qt5/*/*/*.bb \
     qt5-layer:${LAYERDIR}/dynamic-layers/meta-qt5/*/*/*.bbappend \
 "
     qt5-layer:${LAYERDIR}/dynamic-layers/meta-qt5/*/*/*.bb \
     qt5-layer:${LAYERDIR}/dynamic-layers/meta-qt5/*/*/*.bbappend \
 "
diff --git a/meta-agl-core/dynamic-layers/meta-selinux/recipes-core/systemd/files/systemd-selinux-relabel.service b/meta-agl-core/dynamic-layers/meta-selinux/recipes-core/systemd/files/systemd-selinux-relabel.service
new file mode 100644 (file)
index 0000000..b8d3940
--- /dev/null
@@ -0,0 +1,12 @@
+[Unit]
+Description=Generated file SELinux relabeling
+DefaultDependencies=no
+After=local-fs.target systemd-machine-id-commit.service
+Before=sysinit.target
+
+[Service]
+Type=oneshot
+ExecStart=/usr/sbin/systemd-selinux-relabel.sh
+
+[Install]
+WantedBy=sysinit.target
diff --git a/meta-agl-core/dynamic-layers/meta-selinux/recipes-core/systemd/files/systemd-selinux-relabel.sh b/meta-agl-core/dynamic-layers/meta-selinux/recipes-core/systemd/files/systemd-selinux-relabel.sh
new file mode 100644 (file)
index 0000000..b2557a8
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# Update labels on files generated on first boot.
+/usr/sbin/restorecon -FRi /etc/systemd /etc/machine-id
+if [ $? -eq 0 ]; then
+       # Disable parent service
+       # NOTE: The service does not use the first boot functionality
+       #       in systemd as /etc/machine-id is not writeable until
+       #       after it is complete.
+       systemctl disable systemd-selinux-relabel.service
+fi
+exit 0
diff --git a/meta-agl-core/dynamic-layers/meta-selinux/recipes-core/systemd/systemd-selinux-relabel_1.0.bb b/meta-agl-core/dynamic-layers/meta-selinux/recipes-core/systemd/systemd-selinux-relabel_1.0.bb
new file mode 100644 (file)
index 0000000..7e4f978
--- /dev/null
@@ -0,0 +1,25 @@
+SUMMARY     = "System unit to relabel systemd generated files"
+LICENSE     = "MIT"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
+
+SRC_URI = "file://systemd-selinux-relabel.service \
+           file://systemd-selinux-relabel.sh \
+"
+
+inherit systemd allarch features_check
+
+SYSTEMD_SERVICE:${PN} = "${BPN}.service"
+
+REQUIRED_DISTRO_FEATURES = "systemd"
+
+do_configure[noexec] = "1"
+do_compile[noexec] = "1"
+
+do_install() {
+    install -d ${D}${systemd_system_unitdir}
+    install -m 0644 ${WORKDIR}/systemd-selinux-relabel.service ${D}${systemd_system_unitdir}/
+    install -d ${D}${sbindir}
+    install -m 0755 ${WORKDIR}/systemd-selinux-relabel.sh ${D}${sbindir}/
+}
+
+FILES:${PN} += "${systemd_system_unitdir}"
diff --git a/meta-agl-core/dynamic-layers/meta-selinux/recipes-platform/packagegroups/packagegroup-agl-core-selinux.bb b/meta-agl-core/dynamic-layers/meta-selinux/recipes-platform/packagegroups/packagegroup-agl-core-selinux.bb
new file mode 100644 (file)
index 0000000..493a46f
--- /dev/null
@@ -0,0 +1,57 @@
+SUMMARY = "SELinux packages"
+DESCRIPTION = "SELinux packages required for AGL"
+LICENSE = "MIT"
+
+inherit packagegroup features_check
+
+REQUIRED_DISTRO_FEATURES = "selinux"
+
+PACKAGES = " \
+    packagegroup-agl-core-selinux \
+    packagegroup-agl-core-selinux-devel \
+"
+
+#
+# meta-selinux's packagegroup-core-selinux includes a lot of
+# policy development tools with its inclusion of the layer's
+# packagegroup-selinux-policycoreutils, which is not really
+# desirable for a production image.  Create our own base
+# packagegroup and an accompanying devel packagegroup that
+# agl-devel can trigger pulling in.
+#
+# NOTES:
+# - It seems likely we will always want auditd, so include
+#   it in the base packagegroup.
+# - selinux-autorelabel seems required to handle both the
+#   edge case of builds done on non-xattr capable filesystems,
+#   and to allow driving relabeling after potential package
+#   installation during runtime.
+# - packagegroup-selinux-policycoreutils includes a lot of
+#   things that seem not useful in a lot of systems (e.g.
+#   the gtk dependent selinux-gui), so for now the devel
+#   packagegroup aims to include a more minimal set of tools
+#   aimed at enabling checkpolicy and audit2allow use.
+# - Some thought needs to go into whether the relabeling
+#   fixup packages should be handled separately, as they
+#   ideally should not go into images using read-only or
+#   stateless rootfs, but those are image features so we
+#   cannot check for them here.
+#
+
+RDEPENDS:${PN} = " \
+    packagegroup-selinux-minimal \
+    auditd \
+    selinux-autorelabel \
+    systemd-selinux-relabel \
+"
+
+RDEPENDS:${PN}-devel = " \
+    ${BPN} \
+    libsepol-bin \
+    checkpolicy \
+    policycoreutils-loadpolicy \
+    policycoreutils-setsebool \
+    policycoreutils-hll \
+    semodule-utils-semodule-package \
+    selinux-python-audit2allow \
+"
diff --git a/meta-agl-core/dynamic-layers/meta-selinux/recipes-security/selinux-scripts/selinux-autorelabel_0.1.bbappend b/meta-agl-core/dynamic-layers/meta-selinux/recipes-security/selinux-scripts/selinux-autorelabel_0.1.bbappend
new file mode 100644 (file)
index 0000000..793b049
--- /dev/null
@@ -0,0 +1 @@
+require ${@bb.utils.contains('AGL_FEATURES', 'aglcore', 'selinux-autorelabel_aglcore.inc', '', d)}
diff --git a/meta-agl-core/dynamic-layers/meta-selinux/recipes-security/selinux-scripts/selinux-autorelabel_aglcore.inc b/meta-agl-core/dynamic-layers/meta-selinux/recipes-security/selinux-scripts/selinux-autorelabel_aglcore.inc
new file mode 100644 (file)
index 0000000..67d3843
--- /dev/null
@@ -0,0 +1,4 @@
+do_install:append() {
+    # Do not force auto relabeling just from the package getting installed
+    rm -f ${D}/.autorelabel
+}
index 81cf018..b3ac737 100644 (file)
@@ -39,6 +39,7 @@ AGL_KCONFIG_FRAGMENTS += " \
     can-bus.cfg \
     fanotify.cfg \
     overlayfs.cfg \
     can-bus.cfg \
     fanotify.cfg \
     overlayfs.cfg \
+    ${@bb.utils.contains('DISTRO_FEATURES', 'selinux', 'selinux.cfg', '', d)} \
 "
 
 AGL_KCONFIG_FRAGMENTS += " ${@bb.utils.contains('AGL_XEN_GUEST_WANTED','1','xen_domu.cfg','',d)}"
 "
 
 AGL_KCONFIG_FRAGMENTS += " ${@bb.utils.contains('AGL_XEN_GUEST_WANTED','1','xen_domu.cfg','',d)}"
diff --git a/meta-agl-core/recipes-kernel/linux/linux/selinux.cfg b/meta-agl-core/recipes-kernel/linux/linux/selinux.cfg
new file mode 100644 (file)
index 0000000..86330f1
--- /dev/null
@@ -0,0 +1,18 @@
+CONFIG_AUDIT=y
+CONFIG_AUDIT_GENERIC=y
+CONFIG_NETWORK_SECMARK=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_JFS_SECURITY=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFFS2_FS_SECURITY=y
+CONFIG_SECURITY=y
+CONFIG_SECURITYFS=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
index 60d671b..b7cb194 100644 (file)
@@ -1,6 +1,15 @@
 IMAGE_LINGUAS = " "
 
 IMAGE_LINGUAS = " "
 
-inherit core-image
+AGL_BASE_IMAGE ?= "core-image"
+
+inherit ${AGL_BASE_IMAGE}
+
+FEATURE_PACKAGES_selinux = " \
+    packagegroup-agl-core-selinux \
+    ${@bb.utils.contains('DISTRO_FEATURES', 'agl-devel', 'packagegroup-agl-core-selinux-devel', '', d)} \
+"
+
+IMAGE_FEATURES:append = " ${@bb.utils.filter('DISTRO_FEATURES', 'selinux', d)}"
 
 IMAGE_INSTALL = "packagegroup-agl-core-boot ${CORE_IMAGE_EXTRA_INSTALL}"
 
 
 IMAGE_INSTALL = "packagegroup-agl-core-boot ${CORE_IMAGE_EXTRA_INSTALL}"
 
diff --git a/templates/feature/agl-selinux/50_bblayers.conf.inc b/templates/feature/agl-selinux/50_bblayers.conf.inc
new file mode 100644 (file)
index 0000000..b17e292
--- /dev/null
@@ -0,0 +1,5 @@
+AGL_META_PYTHON = "${METADIR}/external/meta-openembedded/meta-python"
+
+BBLAYERS =+ " \
+       ${METADIR}/external/meta-selinux \
+       "
diff --git a/templates/feature/agl-selinux/50_local.conf.inc b/templates/feature/agl-selinux/50_local.conf.inc
new file mode 100644 (file)
index 0000000..4aaac2d
--- /dev/null
@@ -0,0 +1,2 @@
+#see meta-agl/meta-agl/conf/include/agl-selinux.inc
+require conf/include/agl-selinux.inc
diff --git a/templates/feature/agl-selinux/README_feature_agl-selinux.md b/templates/feature/agl-selinux/README_feature_agl-selinux.md
new file mode 100644 (file)
index 0000000..c48ce06
--- /dev/null
@@ -0,0 +1,9 @@
+---
+description: Feature agl-selinux
+authors: Scott Murray <scott.murray@konsulko.com>
+---
+
+### Feature agl-selinux
+
+Enables building with SELinux enabled, with the default mode
+being permissive.