From 3ba2a3411dea519ae82829a8eba8a5c84472dc6e Mon Sep 17 00:00:00 2001 From: Oskari Rauta Date: Tue, 18 May 2021 04:27:21 +0300 Subject: [PATCH] apparmor: add package Signed-off-by: Oskari Rauta --- utils/apparmor/Makefile | 216 +++++++++ utils/apparmor/files/apparmor.init | 22 + utils/apparmor/files/apparmor.sh | 380 ++++++++++++++++ .../patches/010-autoconf-libapparmor.patch | 10 + utils/apparmor/patches/020-fix-ss-path.patch | 11 + .../patches/030-remove-pynotify2-dep.patch | 416 ++++++++++++++++++ .../patches/040-remove-bash-dep.patch | 134 ++++++ .../patches/050-disable-man-pages.patch | 69 +++ .../patches/060-openwrt-dnsmasq-profile.patch | 190 ++++++++ 9 files changed, 1448 insertions(+) create mode 100644 utils/apparmor/Makefile create mode 100755 utils/apparmor/files/apparmor.init create mode 100755 utils/apparmor/files/apparmor.sh create mode 100644 utils/apparmor/patches/010-autoconf-libapparmor.patch create mode 100644 utils/apparmor/patches/020-fix-ss-path.patch create mode 100644 utils/apparmor/patches/030-remove-pynotify2-dep.patch create mode 100644 utils/apparmor/patches/040-remove-bash-dep.patch create mode 100644 utils/apparmor/patches/050-disable-man-pages.patch create mode 100644 utils/apparmor/patches/060-openwrt-dnsmasq-profile.patch diff --git a/utils/apparmor/Makefile b/utils/apparmor/Makefile new file mode 100644 index 0000000000..c72ea681a6 --- /dev/null +++ b/utils/apparmor/Makefile @@ -0,0 +1,216 @@ +# SPDX-License-Identifier: GPL-2.0-only + +include $(TOPDIR)/rules.mk + +PKG_NAME:=apparmor +PKG_VERSION:=3.0.1 +PKG_RELEASE:=$(AUTORELEASE) + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://gitlab.com/apparmor/apparmor.git +PKG_SOURCE_VERSION:=0325ba06da6eeb5acf3e568063a08136fd0913e0 +PKG_MIRROR_HASH:=303ceca041ad8023fa44cdda366448d60b6299790266834b4078d30b70ad27f9 + +PKG_LICENSE:=GPL-2.0-only +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Oskari Rauta +BUILDONLY:=1 + +PKG_BUILD_DEPENDS:=swig/host +HOST_PYTHON3_PACKAGE_BUILD_DEPENDS:=setuptools-scm + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/nls.mk +include ../../../packages/lang/python/python3-package.mk + +define Package/apparmor/Default + SECTION:=utils + CATEGORY:=Utilities + SUBMENU:=AppArmor + URL:=https://apparmor.net +endef + +define Package/libapparmor + TITLE:=AppArmor library + SECTION:=libs + CATEGORY:=Libraries + URL:=https://apparmor.net +endef + +define Package/python3-apparmor + TITLE:=AppArmor Python bindings + SECTION:=lang + CATEGORY:=Languages + SUBMENU:=Python + URL:=https://apparmor.net + DEPENDS:=+libapparmor +python3 +endef + +define Package/apparmor-utils + $(call Package/apparmor/Default) + TITLE:=AppArmor utils + DEPENDS:=$(INTL_DEPENDS) +libapparmor +python3-apparmor +python3 +python3-readline +python3-psutil +ss +findutils-xargs +endef + +define Package/apparmor-profiles + $(call Package/apparmor/Default) + TITLE:=AppArmor default profiles +endef + +define Package/libapparmor/description + Library to support AppArmor userspace utilities +endef + +define Package/apparmor-utils/description + AppArmor application security system init script and + userspace utils to assist with AppArmor profile management +endef + +define Package/apparmor-profiles/description + A collection of profiles for the AppArmor application security system +endef + +CONFIGURE_PATH=libraries/libapparmor + +TARGET_LDFLAGS += \ + -L$(PYTHON3_LIB_DIR) + +CONFIGURE_VARS += \ + SHELL=$(bash) \ + PYTHON_VERSION=$(PYTHON3_VERSION) \ + PYTHON_VERSIONS=$(PYTHON3) \ + PYTHON=$(PYTHON3) \ + PYTHON_CONFIG=$(STAGING_DIR_ROOT)/host/bin/python$(PYTHON3_VERSION)-config \ + PYTHON_LDFLAGS="-L$(STAGING_DIR)/usr/lib -L$(PYTHON3_LIB_DIR)" \ + PYTHON_CPPFLAGS="-I$(STAGING_DIR)/usr/include/python$(PYTHON3_VERSION)" \ + PYTHON_LDFLAGS="-I$(PYTHON3_INC_DIR) -L$(STAGING_DIR)/usr/lib -L$(PYTHON3_LIB_DIR)" \ + PYTHON_EXTRA_LDFLAGS="-L$(STAGING_DIR)/usr/lib -L$(PYTHON3_LIB_DIR)/config-$(PYTHON3_VERSION) -lpthread -ldl -lm -lz -lpython$(PYTHON3_VERSION)" \ + ac_cv_path_PYTHON_CONFIG="$(STAGING_DIR)/host/bin/python$(PYTHON3_VERSION)-config" + +CONFIGURE_ARGS += \ + --with-python \ + --without-perl \ + --without-ruby \ + --disable-man-pages + +ifeq ($(CONFIG_BUILD_NLS),y) + MAKE_VARS += WITH_LIBINTL=1 + MAKE_FLAGS += WITH_LIBINTL=1 +endif + +APPARMOR_CFLAGS = -I$(PKG_BUILD_DIR)/libraries/libapparmor/include +APPARMOR_LDFLAGS = -L$(PKG_BUILD_DIR)/libraries/libapparmor/src/.libs + +define Build/Configure + $(MAKE) -C $(PKG_BUILD_DIR)/libraries/libapparmor configure + $(RM) $(PKG_BUILD_DIR)/libraries/libapparmor/Makefile + $(SED) 's#ac_cv_path_PYTHON_CONFIG=#ac_cv_path_X_PYTHON_CONFIG=#g' $(PKG_BUILD_DIR)/libraries/libapparmor/configure + $(call Build/Configure/Default) +endef + +define Build/Compile + # Building libapparmor + +$(MAKE_VARS) \ + CFLAGS="$(TARGET_CFLAGS)" CPPFLAGS="$(TARGET_CPPFLAGS)" LDFLAGS="$(TARGET_LDFLAGS)" $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/libraries/libapparmor \ + $(MAKE_FLAGS) + # Building parser + +$(MAKE_VARS) PYTHON=$(HOST_PYTHON) \ + CFLAGS="$(TARGET_CFLAGS) $(APPARMOR_CFLAGS)" CPPFLAGS="$(TARGET_CPPFLAGS) $(APPARMOR_CFLAGS)" LDFLAGS="$(TARGET_LDFLAGS) $(APPARMOR_LDFLAGS) -lgcc_s" USE_SYSTEM=0 $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/parser \ + $(MAKE_FLAGS) apparmor_parser + # Building binutils + +$(MAKE_VARS) PYTHON=$(HOST_PYTHON) \ + CFLAGS="$(TARGET_CFLAGS) $(APPARMOR_CFLAGS)" CPPFLAGS="$(TARGET_CPPFLAGS) $(APPARMOR_CFLAGS)" LDFLAGS="$(TARGET_LDFLAGS) $(APPARMOR_LDFLAGS)" USE_SYSTEM=0 $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/binutils \ + $(MAKE_FLAGS) + # Building utils + +$(MAKE_VARS) PYTHON=$(HOST_PYTHON) \ + CFLAGS="$(TARGET_CFLAGS) $(APPARMOR_CFLAGS)" CPPFLAGS="$(TARGET_CPPFLAGS) $(APPARMOR_CFLAGS)" LDFLAGS="$(TARGET_LDFLAGS) $(APPARMOR_LDFLAGS)" USE_SYSTEM=0 $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/utils \ + $(MAKE_FLAGS) + # Building profiles + +$(MAKE_VARS) PYTHON=$(HOST_PYTHON) \ + CFLAGS="$(TARGET_CFLAGS) $(APPARMOR_CFLAGS)" CPPFLAGS="$(TARGET_CPPFLAGS) $(APPARMOR_CFLAGS")" LDFLAGS="$(TARGET_LDFLAGS) $(APPARMOR_LDFLAGS)" USE_SYSTEM=0 $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/profiles \ + $(MAKE_FLAGS) +endef + +define Build/Install + # Make sure we have python's setup tools installed + $(if $(PYTHON3_PKG_HOST_PIP_INSTALL_ARGS), \ + $(call HostPython3/PipInstall,$(PYTHON3_PKG_HOST_PIP_INSTALL_ARGS)) \ + ) + $(INSTALL_DIR) $(PKG_INSTALL_DIR)-libapparmor $(PKG_INSTALL_DIR)-utils $(PKG_INSTALL_DIR)-profiles + # Installing libapparmor + +$(MAKE_VARS) PYTHON=$(HOST_PYTHON) VERSION=$(PYTHON3_VERSION) \ + CFLAGS="$(TARGET_CFLAGS)" CPPFLAGS="$(TARGET_CPPFLAGS)" LDFLAGS="$(TARGET_LDFLAGS)" \ + $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/libraries/libapparmor \ + $(MAKE_FLAGS) DESTDIR="$(PKG_INSTALL_DIR)-libapparmor" install + # Installing parser + +$(MAKE_VARS) PYTHON=$(HOST_PYTHON) VERSION=$(PYTHON3_VERSION) \ + CFLAGS="$(TARGET_CFLAGS)" LDFLAGS="$(TARGET_LDFLAGS)" USE_SYSTEM=1 $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/parser \ + $(MAKE_FLAGS) DESTDIR="$(PKG_INSTALL_DIR)-utils" install + # Installing binutils + +$(MAKE_VARS) PYTHON=$(HOST_PYTHON) VERSION=$(PYTHON3_VERSION) \ + CFLAGS="$(TARGET_CFLAGS)" LDFLAGS="$(TARGET_LDFLAGS)" USE_SYSTEM=1 $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/binutils \ + $(MAKE_FLAGS) DESTDIR="$(PKG_INSTALL_DIR)-utils" install + # Installing utils + +$(MAKE_VARS) PYTHON=$(HOST_PYTHON) VERSION=$(PYTHON3_VERSION) \ + CFLAGS="$(TARGET_CFLAGS)" LDFLAGS="$(TARGET_LDFLAGS)" USE_SYSTEM=1 $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/utils \ + $(MAKE_FLAGS) DESTDIR="$(PKG_INSTALL_DIR)-utils" install + # Installing profiles + +$(MAKE_VARS) PYTHON=$(HOST_PYTHON) VERSION=$(PYTHON3_VERSION) \ + CFLAGS="$(TARGET_CFLAGS)" LDFLAGS="$(TARGET_LDFLAGS)" USE_SYSTEM=1 $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/profiles \ + $(MAKE_FLAGS) DESTDIR="$(PKG_INSTALL_DIR)-profiles" install +endef + +define Package/libapparmor/install + $(INSTALL_DIR) $(1)/usr/lib + $(INSTALL_BIN) $(PKG_INSTALL_DIR)-libapparmor/usr/lib/libapparmor.so.1 $(1)/usr/lib/ + $(LN) libapparmor.so.1 $(1)/usr/lib/libapparmor.so +endef + +define Package/python3-apparmor/install + $(INSTALL_DIR) \ + $(1)/usr/lib/python$(PYTHON3_VERSION)/site-packages \ + $(1)/usr/lib/python$(PYTHON3_VERSION)/site-packages/LibAppArmor + $(INSTALL_DATA) $(PKG_INSTALL_DIR)-libapparmor/usr/lib/python$(PYTHON3_VERSION)/site-packages/*.egg-info \ + $(1)/usr/lib/python$(PYTHON3_VERSION)/site-packages/ + $(INSTALL_DATA) $(PKG_INSTALL_DIR)-libapparmor/usr/lib/python$(PYTHON3_VERSION)/site-packages/LibAppArmor/*.py \ + $(1)/usr/lib/python$(PYTHON3_VERSION)/site-packages/LibAppArmor + $(INSTALL_BIN) $(PKG_INSTALL_DIR)-libapparmor/usr/lib/python$(PYTHON3_VERSION)/site-packages/LibAppArmor/*.so \ + $(1)/usr/lib/python$(PYTHON3_VERSION)/site-packages/LibAppArmor/ + $(LN) -s _LibAppArmor.cpython-$(PYTHON3_VERSION_MAJOR)$(PYTHON3_VERSION_MINOR).so \ + $(1)/usr/lib/python$(PYTHON3_VERSION)/site-packages/LibAppArmor/_LibAppArmor.so +endef + +define Package/apparmor-utils/install + $(INSTALL_DIR) $(1)/etc/apparmor $(1)/usr/sbin $(1)/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)-utils/sbin/apparmor_parser $(1)/sbin/ + $(INSTALL_CONF) $(PKG_INSTALL_DIR)-utils/etc/apparmor/*.conf $(1)/etc/apparmor/ + $(INSTALL_DATA) $(PKG_INSTALL_DIR)-utils/etc/apparmor/severity.db $(1)/etc/apparmor/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)-utils/sbin/apparmor_parser $(1)/sbin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)-utils/usr/bin/{aa-exec,aa-easyprof,aa-enabled,aa-features-abi} $(1)/usr/sbin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)-utils/usr/sbin/{aa-audit,aa-autodep,aa-cleanprof,aa-complain,aa-decode,aa-disable,aa-enforce,aa-genprof,aa-logprof,aa-mergeprof,aa-notify,aa-remove-unknown,aa-status,aa-unconfined} $(1)/usr/sbin/ + $(LN) aa-status $(1)/usr/sbin/apparmor_status + $(INSTALL_DIR) $(1)/usr/share/apparmor/easyprof/templates $(1)/usr/share/apparmor/easyprof/policygroups + $(INSTALL_DATA) $(PKG_INSTALL_DIR)-utils/usr/share/apparmor/easyprof/templates/* $(1)/usr/share/apparmor/easyprof/templates/ + $(INSTALL_DATA) $(PKG_INSTALL_DIR)-utils/usr/share/apparmor/easyprof/policygroups/* $(1)/usr/share/apparmor/easyprof/policygroups/ + $(INSTALL_DIR) $(1)/usr/lib/python3.9/site-packages $(1)/usr/lib/python3.9/site-packages/apparmor $(1)/usr/lib/python3.9/site-packages/apparmor/rule + $(INSTALL_DATA) $(PKG_INSTALL_DIR)-utils/usr/lib/python3.9/site-packages/*.egg-info \ + $(1)/usr/lib/python3.9/site-packages/ + $(INSTALL_DATA) $(PKG_INSTALL_DIR)-utils/usr/lib/python3.9/site-packages/apparmor/*.py \ + $(1)/usr/lib/python3.9/site-packages/apparmor/ + $(INSTALL_DATA) $(PKG_INSTALL_DIR)-utils/usr/lib/python3.9/site-packages/apparmor/rule/*.py \ + $(1)/usr/lib/python3.9/site-packages/apparmor/rule + $(INSTALL_DIR) $(1)/etc/init.d $(1)/lib/functions + $(INSTALL_BIN) ./files/apparmor.sh $(1)/lib/functions/ + $(INSTALL_BIN) ./files/apparmor.init $(1)/etc/init.d/apparmor +endef + +define Package/apparmor-profiles/install + $(INSTALL_DIR) $(1)/etc/apparmor.d $(1)/usr/share/apparmor/extra-profiles + $(CP) -aR $(PKG_INSTALL_DIR)-profiles/etc/apparmor.d/** $(1)/etc/apparmor.d/ + $(INSTALL_CONF) $(PKG_INSTALL_DIR)-profiles/usr/share/apparmor/extra-profiles/** $(1)/usr/share/apparmor/extra-profiles/ +endef + +$(eval $(call BuildPackage,libapparmor)) +$(eval $(call BuildPackage,python3-apparmor)) +$(eval $(call BuildPackage,apparmor-utils)) +$(eval $(call BuildPackage,apparmor-profiles)) diff --git a/utils/apparmor/files/apparmor.init b/utils/apparmor/files/apparmor.init new file mode 100755 index 0000000000..576df39ace --- /dev/null +++ b/utils/apparmor/files/apparmor.init @@ -0,0 +1,22 @@ +#!/bin/sh /etc/rc.common + +START=75 +USE_PROCD=1 + +. /lib/functions/apparmor.sh + +restart() { + apparmor_restart +} + +start_service() { + apparmor_start +} + +stop_service() { + apparmor_stop +} + +reload_service() { + apparmor_reload +} diff --git a/utils/apparmor/files/apparmor.sh b/utils/apparmor/files/apparmor.sh new file mode 100755 index 0000000000..5e9edb9dd5 --- /dev/null +++ b/utils/apparmor/files/apparmor.sh @@ -0,0 +1,380 @@ +#!/bin/sh + +log_write() { + local facility=kern.$1 + logger -t AppArmor -p $facility "$2" +} + +AA_STATUS=/usr/sbin/aa-status +SECURITYFS=/sys/kernel/security +SFS_MOUNTPOINT="${SECURITYFS}/apparmor" +PARSER=/sbin/apparmor_parser +PARSER_OPTS= +ADDITIONAL_PROFILE_DIR= + +[ -d /etc/apparmor.d ] && PROFILE_DIRS=/etc/apparmor.d || + log_write warning "Unable to find profiles: /etc/apparmor.d" + +[ -n "$ADDITIONAL_PROFILE_DIR" ] && [ -d "$ADDITIONAL_PROFILE_DIR" ] && + PROFILE_DIRS="$PROFILE_DIRS $ADDITIONAL_PROFILE_DIR" + +dir_is_empty() { + [ "$(du -s $1 | cut -f 1)" -eq 0 ] && return 0 || return 1 +} + +profiles_loaded_count() { + + [ -f ${SFS_MOUNTPOINT}/profiles ] && + return $(cat "${SFS_MOUNTPOINT}/profiles" | wc -l) || return 0 +} + +is_profiles_loaded() { + + [ -f ${SFS_MOUNTPOINT}/profiles ] && { + rc=$(cat "${SFS_MOUNTPOINT}/profiles" | wc -l) + [ "$rc" -ne 0 ] && return 0 || return 1 + } + return 1 +} + +is_container_with_internal_policy() { + + local ns_stacked_path="${SFS_MOUNTPOINT}/.ns_stacked" + local ns_name_path="${SFS_MOUNTPOINT}/.ns_name" + local ns_stacked + local ns_name + + if ! [ -f "$ns_stacked_path" ] || ! [ -f "$ns_name_path" ]; then + return 1 + fi + + read -r ns_stacked < "$ns_stacked_path" + if [ "$ns_stacked" != "yes" ]; then + return 1 + fi + + # LXD and LXC set up AppArmor namespaces starting with "lxd-" and + # "lxc-", respectively. Return non-zero for all other namespace + # identifiers. + + read -r ns_name < "$ns_name_path" + if [ "${ns_name#lxd-*}" = "$ns_name" ] && \ + [ "${ns_name#lxc-*}" = "$ns_name" ]; then + return 1 + fi + + return 0 +} + +skip_profile() { + + local profile="$1" + + if [ "${profile%.rpmnew}" != "$profile" ] || \ + [ "${profile%.rpmsave}" != "$profile" ] || \ + [ "${profile%.orig}" != "$profile" ] || \ + [ "${profile%.rej}" != "$profile" ] || \ + [ "${profile%\~}" != "$profile" ] ; then + return 1 + fi + + # Silently ignore the dpkg, pacman, ipk and xbps files + + if [ "${profile%.dpkg-new}" != "$profile" ] || \ + [ "${profile%.dpkg-old}" != "$profile" ] || \ + [ "${profile%.dpkg-dist}" != "$profile" ] || \ + [ "${profile%.dpkg-bak}" != "$profile" ] || \ + [ "${profile%.dpkg-remove}" != "$profile" ] || \ + [ "${profile%.ipk}" != "$profile" ] || \ + [ "${profile%.ipk-new}" != "$profile" ] || \ + [ "${profile%.ipk-old}" != "$profile" ] || \ + [ "${profile%.ipk-dist}" != "$profile" ] || \ + [ "${profile%.ipk-bak}" != "$profile" ] || \ + [ "${profile%.ipk-remove}" != "$profile" ] || \ + [ "${profile%.pacsave}" != "$profile" ] || \ + [ "${profile%.pacnew}" != "$profile" ] ; then + return 2 + fi + + $(echo "$profile" | grep -E -q '^.+\.new-[0-9\.]+_[0-9]+$'); [ "$?" -eq 0 ] && return 2 + + return 0 +} + +__parse_profiles_dir() { + + local parser_cmd="$1" + local profile_dir="$2" + local status=0 + + [ -x "$PARSER" ] || { + log_write err "Unable to execute AppArmor parser" + return 1 + } + + [ -d "$profile_dir" ] || { + log_write warning "AppArmor profiles not found: $profile_dir" + return 1 + } + + dir_is_empty "$profile_dir"; [ "$?" -eq 0 ] && { + log_write err "No profiles found in $profile_dir" + return 1 + } + + local nprocs=$(cat /proc/cpuinfo |grep "processor\t:"|wc -l) + local rc=0 + local xargs_args="" + [ "$nprocs" -ge 2 ] && xargs_args="--max-procs=$nprocs" + + "$PARSER" $PARSER_OPTS "$parser_cmd" -- "$profile_dir" || { + + for profile in "$profile_dir"/*; do + skip_profile "$profile" + skip=$? + [ "$skip" -ne 0 ] && { + [ "$skip" -ne 2 ] && log_write info "Skipped loading profile $profile" + continue + } + [ -f "$profile" ] || continue + echo "$profile" + done | \ + + # Use xargs to parallelize calls to the parser over all CPUs + + /usr/libexec/xargs-findutils -n1 -d"\n" $xargs_args \ + "$PARSER" $PARSER_OPTS "$parser_cmd" -- + + [ "$?" -ne 0 ] && { + rc=1 + log_write err "At least one profile failed to load" + } + } + + return $rc +} + +parse_profiles() { + + case "$1" in + load) + PARSER_CMD="--add" + PARSER_MSG="Loading profiles" + ;; + reload) + PARSER_CMD="--replace" + PARSER_MSG="Reloading profiles" + ;; + *) + log_write err "Unknown parameter $1" + log_write info "parse_profiles parameter must be either 'load' or 'reload'" + return 1 + ;; + esac + + log_write info "$PARSER_MSG" + + [ -w "$SFS_MOUNTPOINT/.load" ] || { + log_write err "${SFS_MOUNTPOINT}/.load not writable" + return 1 + } + + [ -f "$PARSER" ] || { + log_write err "AppArmor parser not found" + return 1 + } + + # run parser on all profiles + local rc=0 + for profile_dir in $PROFILE_DIRS; do + __parse_profiles_dir "$PARSER_CMD" "$profile_dir" || rc=$? + done + + return $rc +} + +is_apparmor_loaded() { + + is_securityfs_mounted; [ "$?" -eq 0 ] || { + mount_securityfs + } + + [ -f "${SFS_MOUNTPOINT}/profiles" ] && return 0 + [ -d /sys/module/apparmor ] && return 0 || return 1 +} + +is_securityfs_mounted() { + + [ -d "$SECURITYFS" ] && { + grep -q securityfs /proc/filesystems && grep -q securityfs /proc/mounts + return $? + } + return 1 +} + +mount_securityfs() { + + local rc=0 + + grep -q securityfs /proc/filesystems; [ "$?" -eq 0 ] && { + mount -t securityfs securityfs "$SECURITYFS" + rc=$? + [ "$rc" -eq 0 ] && log_write info "Mounting securityfs" || + log_write err "Failed to mount securityfs" + } + return $rc +} + +apparmor_start() { + + local announced=0 + is_securityfs_mounted; [ "$?" -ne 0 ] && { + log_write info "Starting AppArmor" + announced=1 + mount_securityfs; [ "$?" -eq 0 ] || return $? + } + + is_apparmor_loaded; [ "$?" -eq 0 ] || { + [ "$announced" -eq 0 ] && log_write info "Starting AppArmor" + announced=1 + log_write err "AppArmor kernel support is not present" + return 1 + } + + [ -d /var/lib/apparmor ] || mkdir -p /var/lib/apparmor > /dev/null + + is_profiles_loaded; [ "$?" -eq 0 ] || { + [ "$announced" -eq 0 ] && log_write info "Starting AppArmor" + announced=1 + parse_profiles load + return $? + } || { + parse_profiles reload + return $? + } +} + +remove_profiles() { + + log_write info "Unloading profiles" + + is_apparmor_loaded; [ "$?" -eq 0 ] || { + log_write err "AppArmor kernel support is not present" + return 1 + } + + [ -w "$SFS_MOUNTPOINT/.remove" ] || { + log_write err "${SFS_MOUNTPOINT}/.remove not writable" + return 1 + } + + [ -x "$PARSER" ] || { + log_write err "Unable to execute AppArmor parser" + return 1 + } + + local rc=0 + + sed -e "s/ (\(enforce\|complain\))$//" "$SFS_MOUNTPOINT/profiles" | \ + LC_COLLATE=C sort | grep -v // | { + while read -r profile ; do + printf "%s" "$profile" > "$SFS_MOUNTPOINT/.remove" + result=$? + [ "$result" -eq 0 ] || rc=$result + done + } + return $rc +} + +apparmor_stop() { + + is_apparmor_loaded; [ "$?" -eq 0 ] || return 1 + is_profiles_loaded; [ "$?" -eq 0 ] && { + log_write info "Stopping AppArmor" + remove_profiles + return $? + } || return 0 +} + +apparmor_restart() { + + is_profiles_loaded; [ "$?" -eq 0 ] || { + apparmor_start + return $? + } + + is_apparmor_loaded; [ "$?" -eq 0 ] || { + apparmor_start + return $? + } + + log_write info "Restarting AppArmor" + parse_profiles reload + return $? +} + +apparmor_reload() { + + is_profiles_loaded; [ "$?" -eq 0 ] || { + apparmor_start + return $? + } + + is_apparmor_loaded; [ "$?" -eq 0 ] || { + apparmor_start + return $? + } + + log_write info "Reloading AppArmor" + parse_profiles reload + return $? +} + +apparmor_list_profiles() { + + is_apparmor_loaded; [ "$?" -eq 0 ] || { + echo "AppArmor kernel support is not present" + return 1 + } + + [ -x "$PARSER" ] || { + echo "Unable to execute AppArmor parser" + return 1 + } + + # run parser on all profiles + for profile_dir in $PROFILE_DIRS; do + [ -d "$profile_dir" ] || { + echo "AppArmor profiles not found: $profile_dir" + continue + } + + for profile in "$profile_dir"/*; do + if skip_profile "$profile" && [ -f "$profile" ] ; then + LIST_ADD=$("$PARSER" -N "$profile" ) + [ "$?" -eq 0 ] && echo "$LIST_ADD" + fi + done + done + return 0 +} + + +apparmor_status() { + + is_apparmor_loaded; [ "$?" -eq 0 ] || { + echo "AppArmor kernel support is not present" + return 1 + } + + [ -x "$AA_STATUS" ] && { + "$AA_STATUS" --verbose + return $? + } + + echo "AppArmor is enabled." + echo "Install apparmor-utils to receive more detailed status" + echo "information or examine $SFS_MOUNTPOINT directly." + + return 0 +} diff --git a/utils/apparmor/patches/010-autoconf-libapparmor.patch b/utils/apparmor/patches/010-autoconf-libapparmor.patch new file mode 100644 index 0000000000..bcb47d0906 --- /dev/null +++ b/utils/apparmor/patches/010-autoconf-libapparmor.patch @@ -0,0 +1,10 @@ +--- /dev/null ++++ b/libraries/libapparmor/Makefile +@@ -0,0 +1,7 @@ ++package=libapparmor ++ ++configure: ++ $(STAGING_DIR_HOST)/bin/aclocal ++ $(STAGING_DIR_HOST)/bin/autoconf --force ++ $(STAGING_DIR_HOST)/bin/libtoolize --automake -c --force ++ $(STAGING_DIR_HOST)/bin/automake -ac diff --git a/utils/apparmor/patches/020-fix-ss-path.patch b/utils/apparmor/patches/020-fix-ss-path.patch new file mode 100644 index 0000000000..11e53b0219 --- /dev/null +++ b/utils/apparmor/patches/020-fix-ss-path.patch @@ -0,0 +1,11 @@ +--- a/utils/aa-unconfined ++++ b/utils/aa-unconfined +@@ -118,7 +118,7 @@ def read_proc_current(filename): + pids = set() + if paranoid: + pids = get_all_pids() +-elif args.with_ss or (not args.with_netstat and (os.path.exists('/bin/ss') or os.path.exists('/usr/bin/ss'))): ++elif args.with_ss or (not args.with_netstat and (os.path.exists('/usr/sbin/ss') or os.path.exists('/bin/ss') or os.path.exists('/usr/bin/ss') or os.path.exists('/sbin/ss'))): + pids = get_pids_ss() + else: + pids = get_pids_netstat() diff --git a/utils/apparmor/patches/030-remove-pynotify2-dep.patch b/utils/apparmor/patches/030-remove-pynotify2-dep.patch new file mode 100644 index 0000000000..7de4ddc1e1 --- /dev/null +++ b/utils/apparmor/patches/030-remove-pynotify2-dep.patch @@ -0,0 +1,416 @@ +--- a/utils/aa-notify ++++ b/utils/aa-notify +@@ -13,17 +13,6 @@ + # + # ---------------------------------------------------------------------- + # +-# /etc/apparmor/notify.conf: +-# # set to 'yes' to enable AppArmor DENIED notifications +-# show_notifications="yes" +-# +-# # only people in use_group can run this script +-# use_group="admin" +-# +-# $HOME/.apparmor/notify.conf can have: +-# # set to 'yes' to enable AppArmor DENIED notifications +-# show_notifications="yes" +-# + # In a typical desktop environment one would run as a service the + # command: + # /usr/bin/aa-notify -p -w 10 +@@ -35,7 +24,6 @@ import re + import sys + import time + import struct +-import notify2 + import psutil + import pwd + import grp +@@ -60,56 +48,9 @@ def get_user_login(): + username = os.getlogin() + return username + +- +-def get_last_login_timestamp(username): +- '''Directly read wtmp and get last login for user as epoch timestamp''' +- timestamp = 0 +- filename = '/var/log/wtmp' +- last_login = 0 +- +- debug_logger.debug('Username: {}'.format(username)) +- +- with open(filename, "rb") as wtmp_file: +- offset = 0 +- wtmp_filesize = os.path.getsize(filename) +- debug_logger.debug('WTMP filesize: {}'.format(wtmp_filesize)) +- while offset < wtmp_filesize: +- wtmp_file.seek(offset) +- offset += 384 # Increment for next entry +- +- type = struct.unpack(" +@@ -36,13 +34,15 @@ $ cat /var/log/kern.log | aa-decode + EOM + } + +-decode() { +- if echo "$1" | egrep -q "^[0-9A-Fa-f]+$" ; then +- python3 -c "import binascii; print(bytes.decode(binascii.unhexlify('$1'), errors='strict'));" +- else +- echo "" +- fi ++match_re() { ++ local result=$(echo "$1" | grep -E "$2" ) ++ [ -z "$result" ] && return 1 || return 0 ++} + ++ ++decode() { ++ $(echo "$1" | egrep -q "^[0-9A-Fa-f]+$"); [ "$?" -eq 0 ] && ++ python3 -c "import binascii; print(bytes.decode(binascii.unhexlify('$1'), errors='strict'));" || echo "" + } + + if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then +@@ -51,47 +51,61 @@ if [ "$1" = "-h" ] || [ "$1" = "--help" + fi + + # if have an argument, then use it, otherwise process stdin +-if [ -n "$1" ]; then +- e="$1" +- if ! echo "$e" | egrep -q "^[0-9A-Fa-f]+$" ; then +- echo "String should only contain hex characters (0-9, a-f, A-F)" +- exit 1 +- fi +- +- d=`decode $e` +- if [ -z "$d" ]; then +- echo "Could not decode string" +- exit 1 +- fi ++[ -n "$1" ] && { + +- echo "Decoded: $d" +- exit 0 +-fi ++ e="$1" + +-# For now just look at 'name=...' and 'profile=...', +-# so validate input against this and output based on it. +-# TODO: better handle other cases too +-while read line ; do ++ $(echo "$e" | egrep -q "^[0-9A-Fa-f]+$"); [ "$?" -ne 0 ] && { ++ echo "String should only contain hex characters (0-9, a-f, A-F)" ++ exit 1 ++ } + +- # check if line contains encoded name= or profile= +- if [[ "$line" =~ \ (name|profile|proctitle)=[0-9a-fA-F] ]]; then ++ d=$(decode $e) + +- # cut the encoded filename/profile name out of the line and decode it +- ne=`echo "$line" | sed 's/.* name=\([^ ]*\).*$/\\1/g'` +- nd="$(decode ${ne/\'/\\\'})" ++ [ -z "$d" ] && { ++ echo "Could not decode string" ++ exit 1 ++ } + +- pe=`echo "$line" | sed 's/.* profile=\([^ ]*\).*$/\\1/g'` +- pd="$(decode ${pe/\'/\\\'})" ++ echo "Decoded: $d" ++ exit 0 ++} + +- pce=`echo "$line" | sed 's/.* proctitle=\([^ ]*\).*$/\\1/g'` +- pcd="$(decode ${pce/\'/\\\'})" ++[ -t 0 ] && { ++ help ++ exit ++} ++ ++while read line ; do + +- # replace encoded name and profile with its decoded counterparts (only if it was encoded) +- test -n "$nd" && line="${line/name=$ne/name=\"$nd\"}" +- test -n "$pd" && line="${line/profile=$pe/profile=\"$pd\"}" +- test -n "$pcd" && line="${line/proctitle=$pce/proctitle=\"$pcd\"}" ++ # check if line contains encoded name= or profile= + +- fi ++ matches=0 ++ match_re "$line" "^[[:blank:]](name|profile|proctitle)=[0-9a-fA-F]+"; [ "$?" -eq 0 ] && matches=1 || { ++ match_re "$line" "^(name|profile|proctitle)=[0-9a-fA-F]+"; [ "$?" -eq 0 ] && matches=1 ++ } ++ ++ [ "$matches" -eq 0 ] || { ++ ++ # cut the encoded filename/profile name out of the line and decode it ++ ne=$(echo "$line" | sed 's/.* name=\([^ ]*\).*$/\\1/g') ++ [ "$line" = "$ne" ] && ne=$(echo "$line" | sed 's/.*name=\([^ ]*\).*$/\\1/g') ++ echo var: $ne ++ nd="$(decode ${ne/\'/\\\'})" ++ ++ pe=$(echo "$line" | sed 's/.* profile=\([^ ]*\).*$/\\1/g') ++ [ "$line" = "$pe" ] && pe=$(echo "$line" | sed 's/.*profile=\([^ ]*\).*$/\\1/g') ++ pd="$(decode ${pe/\'/\\\'})" ++ ++ pce=$(echo "$line" | sed 's/.* proctitle=\([^ ]*\).*$/\\1/g') ++ [ "$line" = "$pce" ] && pce=$(echo "$line" | sed 's/.*proctitle=\([^ ]*\).*$/\\1/g') ++ pcd="$(decode ${pce/\'/\\\'})" ++ ++ # replace encoded name and profile with its decoded counterparts (only if it was encoded) ++ test -n "$nd" && line="${line/name=$ne/name=\"$nd\"}" ++ test -n "$pd" && line="${line/profile=$pe/profile=\"$pd\"}" ++ test -n "$pcd" && line="${line/proctitle=$pce/proctitle=\"$pcd\"}" ++ } + + echo "$line" + diff --git a/utils/apparmor/patches/050-disable-man-pages.patch b/utils/apparmor/patches/050-disable-man-pages.patch new file mode 100644 index 0000000000..a0463f1521 --- /dev/null +++ b/utils/apparmor/patches/050-disable-man-pages.patch @@ -0,0 +1,69 @@ +--- a/binutils/Makefile ++++ b/binutils/Makefile +@@ -107,7 +107,7 @@ docs: manpages + indep: docs + $(Q)$(MAKE) -C po all + +-all: arch indep ++all: arch + + .PHONY: coverage + coverage: +@@ -147,7 +147,7 @@ tests: $(BINTOOLS) $(SBINTOOLS) $(TESTS) + echo "no tests atm" + + .PHONY: install +-install: install-indep install-arch ++install: install-arch + + .PHONY: install-arch + install-arch: arch +--- a/parser/Makefile ++++ b/parser/Makefile +@@ -195,7 +195,7 @@ extra_docs: pdf + indep: docs + $(Q)$(MAKE) -C po all + +-all: arch indep ++all: arch + + .PHONY: coverage + coverage: +@@ -396,7 +396,6 @@ endif + + .PHONY: install + install: +- $(MAKE) install-indep + $(MAKE) install-arch + + .PHONY: install-arch +--- a/utils/Makefile ++++ b/utils/Makefile +@@ -31,9 +31,7 @@ MANPAGES = ${TOOLS:=.8} logprof.conf.5 + + PYFLAKES ?= pyflakes3 + +-all: docs +- $(MAKE) -C po all +- $(MAKE) -C vim all ++all: clean + + .PHONY: docs + docs: ${MANPAGES} ${HTMLMANPAGES} +@@ -49,15 +47,12 @@ po/${NAME}.pot: ${TOOLS} ${PYMODULES} + $(MAKE) -C po ${NAME}.pot NAME=${NAME} SOURCES="${TOOLS} ${PYMODULES}" + + .PHONY: install +-install: ${MANPAGES} ${HTMLMANPAGES} ++install: + install -d ${CONFDIR} + install -m 644 logprof.conf severity.db notify.conf ${CONFDIR} + install -d ${BINDIR} + # aa-easyprof is installed by python-tools-setup.py + install -m 755 $(filter-out aa-easyprof, ${TOOLS}) ${BINDIR} +- $(MAKE) -C po install DESTDIR=${DESTDIR} NAME=${NAME} +- $(MAKE) install_manpages DESTDIR=${DESTDIR} +- $(MAKE) -C vim install DESTDIR=${DESTDIR} + ${PYTHON} ${PYSETUP} install --prefix=${PYPREFIX} --root=${DESTDIR} --version=${VERSION} + + .PHONY: clean diff --git a/utils/apparmor/patches/060-openwrt-dnsmasq-profile.patch b/utils/apparmor/patches/060-openwrt-dnsmasq-profile.patch new file mode 100644 index 0000000000..cc957ecdfa --- /dev/null +++ b/utils/apparmor/patches/060-openwrt-dnsmasq-profile.patch @@ -0,0 +1,190 @@ +--- a/profiles/apparmor.d/usr.sbin.dnsmasq ++++ b/profiles/apparmor.d/usr.sbin.dnsmasq +@@ -1,3 +1,10 @@ ++# Last Modified: Thu Jun 10 01:23:44 2021 ++abi , ++ ++include ++ ++@{TFTP_DIR} = /srv/tftp /srv/tftpboot /var/tftp ++ + # ------------------------------------------------------------------ + # + # Copyright (C) 2009 John Dong +@@ -9,126 +16,95 @@ + # + # ------------------------------------------------------------------ + +-abi , +- +-@{TFTP_DIR}=/var/tftp /srv/tftp /srv/tftpboot + +-include + profile dnsmasq /usr/{bin,sbin}/dnsmasq flags=(attach_disconnected) { + include + include + include ++ include ++ include if exists + + capability chown, ++ capability dac_override, ++ capability net_admin, # for DHCP server + capability net_bind_service, ++ capability net_raw, # for DHCP server ping checks + capability setgid, + capability setuid, +- capability dac_override, +- capability net_admin, # for DHCP server +- capability net_raw, # for DHCP server ping checks ++ + network inet raw, + network inet6 raw, + +- signal (receive) peer=/usr/{bin,sbin}/libvirtd, +- signal (receive) peer=libvirtd, +- ptrace (readby) peer=/usr/{bin,sbin}/libvirtd, +- ptrace (readby) peer=libvirtd, ++ signal receive peer=/usr/{bin,sbin}/libvirtd, ++ signal receive peer=libvirtd, + +- owner /dev/tty rw, ++ ptrace readby peer=/usr/{bin,sbin}/libvirtd, ++ ptrace readby peer=libvirtd, + +- @{PROC}/@{pid}/fd/ r, +- +- /etc/dnsmasq.conf r, +- /etc/dnsmasq.d/ r, +- /etc/dnsmasq.d/* r, +- /etc/dnsmasq.d-available/ r, +- /etc/dnsmasq.d-available/* r, +- /etc/ethers r, +- /etc/NetworkManager/dnsmasq.d/ r, +- /etc/NetworkManager/dnsmasq.d/* r, + /etc/NetworkManager/dnsmasq-shared.d/ r, + /etc/NetworkManager/dnsmasq-shared.d/* r, ++ /etc/NetworkManager/dnsmasq.d/ r, ++ /etc/NetworkManager/dnsmasq.d/* r, + /etc/dnsmasq-conf.conf r, + /etc/dnsmasq-resolv.conf r, +- +- /usr/{bin,sbin}/dnsmasq mr, +- +- /var/log/dnsmasq*.log w, +- ++ /etc/dnsmasq.conf r, ++ /etc/dnsmasq.d-available/ r, ++ /etc/dnsmasq.d-available/* r, ++ /etc/dnsmasq.d/ r, ++ /etc/dnsmasq.d/* r, ++ /etc/ethers r, ++ /tmp/** r, ++ /usr/libexec/libvirt_leaseshelper Cx -> libvirt_leaseshelper, ++ /usr/lib{,64}/libvirt/libvirt_leaseshelper Cx -> libvirt_leaseshelper, + /usr/share/dnsmasq{-base,}/ r, + /usr/share/dnsmasq{-base,}/* r, +- +- @{run}/*dnsmasq*.pid w, +- @{run}/dnsmasq-forwarders.conf r, +- @{run}/dnsmasq/ r, +- @{run}/dnsmasq/* rw, +- ++ /usr/{bin,sbin}/dnsmasq mr, ++ /var/lib/NetworkManager/dnsmasq-*.leases rw, ++ /var/lib/libvirt/dnsmasq/ r, ++ /var/lib/libvirt/dnsmasq/* r, ++ /var/lib/lxd-bridge/dnsmasq.*.leases rw, ++ /var/lib/lxd/networks/*/dnsmasq.* r, ++ /var/lib/lxd/networks/*/dnsmasq.leases rw, ++ /var/lib/lxd/networks/*/dnsmasq.pid rw, ++ /var/lib/misc/dnsmasq.*.leases rw, + /var/lib/misc/dnsmasq.leases rw, # Required only for DHCP server usage +- ++ /var/log/dnsmasq*.log w, + /{,usr/}bin/{ba,da,}sh ix, # Required to execute --dhcp-script argument +- +- # access to iface mtu needed for Router Advertisement messages in IPv6 +- # Neighbor Discovery protocol (RFC 2461) ++ @{PROC}/@{pid}/fd/ r, + @{PROC}/sys/net/ipv6/conf/*/mtu r, +- +- # for the read-only TFTP server + @{TFTP_DIR}/ r, + @{TFTP_DIR}/** r, +- +- # libvirt config and hosts file for dnsmasq +- /var/lib/libvirt/dnsmasq/ r, +- /var/lib/libvirt/dnsmasq/* r, +- +- # libvirt pid files for dnsmasq +- @{run}/libvirt/network/ r, ++ @{run}/*dnsmasq*.pid w, ++ @{run}/NetworkManager/NetworkManager.pid w, ++ @{run}/NetworkManager/dnsmasq.conf r, ++ @{run}/NetworkManager/dnsmasq.pid w, ++ @{run}/dnsmasq-forwarders.conf r, ++ @{run}/dnsmasq/ r, ++ @{run}/dnsmasq/* rw, ++ @{run}/libvirt/network/ r, + @{run}/libvirt/network/*.pid rw, +- +- # libvirt lease helper +- /usr/lib{,64}/libvirt/libvirt_leaseshelper Cx -> libvirt_leaseshelper, +- /usr/libexec/libvirt_leaseshelper Cx -> libvirt_leaseshelper, +- +- # lxc-net pid and lease files +- @{run}/lxc/dnsmasq.pid rw, +- /var/lib/misc/dnsmasq.*.leases rw, +- +- # lxd-bridge pid and lease files +- @{run}/lxd-bridge/dnsmasq.pid rw, +- /var/lib/lxd-bridge/dnsmasq.*.leases rw, +- /var/lib/lxd/networks/*/dnsmasq.* r, +- /var/lib/lxd/networks/*/dnsmasq.leases rw, +- /var/lib/lxd/networks/*/dnsmasq.pid rw, +- +- # NetworkManager integration +- /var/lib/NetworkManager/dnsmasq-*.leases rw, ++ @{run}/lxc/dnsmasq.pid rw, ++ @{run}/lxd-bridge/dnsmasq.pid rw, + @{run}/nm-dns-dnsmasq.conf r, + @{run}/nm-dnsmasq-*.pid rw, + @{run}/sendsigs.omit.d/*dnsmasq.pid w, +- @{run}/NetworkManager/dnsmasq.conf r, +- @{run}/NetworkManager/dnsmasq.pid w, +- @{run}/NetworkManager/NetworkManager.pid w, ++ owner /dev/tty rw, ++ + + profile libvirt_leaseshelper { + include + + /etc/libnl-3/classid r, +- +- /usr/lib{,64}/libvirt/libvirt_leaseshelper m, + /usr/libexec/libvirt_leaseshelper m, +- +- owner @{PROC}/@{pid}/net/psched r, +- owner @{PROC}/@{pid}/status r, +- ++ /usr/lib{,64}/libvirt/libvirt_leaseshelper m, ++ /var/lib/libvirt/dnsmasq/*.leases rw, ++ /var/lib/libvirt/dnsmasq/*.status* rw, ++ @{run}/leaseshelper.pid rwk, + @{sys}/devices/system/cpu/ r, + @{sys}/devices/system/node/ r, + @{sys}/devices/system/node/*/meminfo r, ++ owner @{PROC}/@{pid}/net/psched r, ++ owner @{PROC}/@{pid}/status r, + +- # libvirt lease and status files for dnsmasq +- /var/lib/libvirt/dnsmasq/*.leases rw, +- /var/lib/libvirt/dnsmasq/*.status* rw, +- +- @{run}/leaseshelper.pid rwk, + } +- +- # Site-specific additions and overrides. See local/README for details. +- include if exists + }