2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-30 13:58:22 +00:00

Compare commits

..

No commits in common. "master" and "v4.0.0-beta2" have entirely different histories.

1319 changed files with 9997 additions and 33750 deletions

83
.gitignore vendored
View File

@ -7,28 +7,15 @@ binutils/aa-exec.1
binutils/aa-features-abi
binutils/aa-features-abi.1
binutils/aa-load
binutils/aa-load.8
binutils/aa-status
binutils/aa-status.8
binutils/cJSON.o
binutils/po/*.mo
changehat/mod_apparmor/.libs
changehat/mod_apparmor/mod_apparmor.8
changehat/mod_apparmor/mod_apparmor.8.html
changehat/mod_apparmor/mod_apparmor.la
changehat/mod_apparmor/mod_apparmor.lo
changehat/mod_apparmor/mod_apparmor.slo
changehat/mod_apparmor/mod_apparmor.so
changehat/mod_apparmor/pod2htmd.tmp
changehat/pam_apparmor/get_options.o
changehat/pam_apparmor/pam_apparmor.o
changehat/pam_apparmor/pam_apparmor.so
parser/po/*.mo
parser/af_names.h
parser/cap_names.h
parser/generated_cap_names.h
parser/generated_af_names.h
parser/errnos.h
parser/tst_lib
parser/tst_misc
parser/tst_regex
@ -40,9 +27,42 @@ parser/parser_version.h
parser/parser_yacc.c
parser/parser_yacc.h
parser/pod2htm*.tmp
parser/libapparmor_re/*.o
parser/af_rule.o
parser/af_unix.o
parser/all_rule.o
parser/common_optarg.o
parser/dbus.o
parser/default_features.o
parser/lib.o
parser/libapparmor_re/aare_rules.o
parser/libapparmor_re/chfa.o
parser/libapparmor_re/expr-tree.o
parser/libapparmor_re/hfa.o
parser/libapparmor_re/libapparmor_re.a
parser/*.o
parser/libapparmor_re/parse.o
parser/mount.o
parser/mqueue.o
parser/network.o
parser/parser_alias.o
parser/parser_common.o
parser/parser_include.o
parser/parser_interface.o
parser/parser_lex.o
parser/parser_main.o
parser/parser_merge.o
parser/parser_misc.o
parser/parser_policy.o
parser/parser_regex.o
parser/parser_symtab.o
parser/parser_variable.o
parser/parser_yacc.o
parser/policy_cache.o
parser/profile.o
parser/ptrace.o
parser/rule.o
parser/signal.o
parser/userns.o
parser/io_uring.o
parser/*.7
parser/*.5
parser/*.8
@ -121,18 +141,6 @@ libraries/libapparmor/src/tst_aalogmisc
libraries/libapparmor/src/tst_aalogmisc.log
libraries/libapparmor/src/tst_aalogmisc.o
libraries/libapparmor/src/tst_aalogmisc.trs
libraries/libapparmor/src/tst_aalogparse_cpp
libraries/libapparmor/src/tst_aalogparse_cpp.log
libraries/libapparmor/src/tst_aalogparse_cpp.o
libraries/libapparmor/src/tst_aalogparse_cpp.trs
libraries/libapparmor/src/tst_aalogparse_reentrancy
libraries/libapparmor/src/tst_aalogparse_reentrancy.log
libraries/libapparmor/src/tst_aalogparse_reentrancy.o
libraries/libapparmor/src/tst_aalogparse_reentrancy.trs
libraries/libapparmor/src/tst_aalogparse_oldname
libraries/libapparmor/src/tst_aalogparse_oldname.log
libraries/libapparmor/src/tst_aalogparse_oldname.o
libraries/libapparmor/src/tst_aalogparse_oldname.trs
libraries/libapparmor/src/tst_features
libraries/libapparmor/src/tst_features.log
libraries/libapparmor/src/tst_features.o
@ -193,6 +201,7 @@ libraries/libapparmor/testsuite/libaalogparse.test/Makefile
libraries/libapparmor/testsuite/libaalogparse.test/Makefile.in
libraries/libapparmor/testsuite/test_multi/out
libraries/libapparmor/testsuite/test_multi_multi-test_multi.o
changehat/mod_apparmor/.libs
utils/*.8
utils/*.8.html
utils/*.5
@ -231,13 +240,11 @@ tests/regression/apparmor/chgrp
tests/regression/apparmor/chmod
tests/regression/apparmor/chown
tests/regression/apparmor/clone
tests/regression/apparmor/complain
tests/regression/apparmor/dbus_eavesdrop
tests/regression/apparmor/dbus_message
tests/regression/apparmor/dbus_service
tests/regression/apparmor/dbus_unrequested_reply
tests/regression/apparmor/deleted
tests/regression/apparmor/disconnected_mount_complain
tests/regression/apparmor/env_check
tests/regression/apparmor/environ
tests/regression/apparmor/exec
@ -250,19 +257,17 @@ tests/regression/apparmor/fchown
tests/regression/apparmor/fd_inheritance
tests/regression/apparmor/fd_inheritor
tests/regression/apparmor/fork
tests/regression/apparmor/getcon_verify
tests/regression/apparmor/introspect
tests/regression/apparmor/io_uring
tests/regression/apparmor/link
tests/regression/apparmor/link_subset
tests/regression/apparmor/linkat_tmpfile
tests/regression/apparmor/mkdir
tests/regression/apparmor/mmap
tests/regression/apparmor/mount
tests/regression/apparmor/move_mount
tests/regression/apparmor/named_pipe
tests/regression/apparmor/net_inet_rcv
tests/regression/apparmor/net_inet_snd
tests/regression/apparmor/net_finegrained_rcv
tests/regression/apparmor/net_finegrained_snd
tests/regression/apparmor/net_raw
tests/regression/apparmor/open
tests/regression/apparmor/openat
@ -310,15 +315,3 @@ tests/regression/apparmor/xattrs_profile
tests/regression/apparmor/coredump
**/__pycache__/
*.orig
# Patterns related to spread integration tests
*.img
*.iso
*.lock
*.log
*.qcow2
*.run
.spread-reuse.yaml
.spread-reuse.*.yaml
spread-artifacts/
spread-logs/

View File

@ -1,51 +1,28 @@
spec:
inputs:
build-test-images:
default: false
type: boolean
description: Explicitly build virtual machine images used by integration tests.
---
image: ubuntu:latest
# XXX - add a deploy stage to publish man pages, docs, and coverage
# reports
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
- if: $CI_COMMIT_TAG
- if: $CI_COMMIT_BRANCH
stages:
- build
- test
- spread
.ubuntu-common:
interruptible: true
.ubuntu-before_script:
before_script:
# Install build-dependencies by loading the package list from the ubuntu/debian cloud-init profile.
- printf '\e[0K%s:%s:%s[collapsed=true]\r\e[0K%s\n' section_start "$(date +%s)" install_deps "Installing dependencies..."
- export DEBIAN_FRONTEND=noninteractive
- apt-get update -qq
- apt-get install --yes yq make lsb-release
- |
printf 'include .image-garden.mk\n$(info $(UBUNTU_CLOUD_INIT_USER_DATA_TEMPLATE))\n.PHONY: nothing\nnothing:\n' \
| make -f - nothing \
| yq '.packages | .[]' \
| xargs apt-get install --yes --no-install-recommends
- printf '\e[0K%s:%s:%s\r\e[0K\n' section_end "$(date +%s)" install_deps
after_script:
# Inspect the kernel and lsb-release.
- apt-get install --no-install-recommends -y gcc perl liblocale-gettext-perl linux-libc-dev lsb-release make
- lsb_release -a
- uname -a
.install-c-build-deps: &install-c-build-deps
- apt-get install --no-install-recommends -y build-essential apache2-dev autoconf autoconf-archive automake bison dejagnu flex libpam-dev libtool pkg-config python3-all-dev python3-setuptools ruby-dev swig zlib1g-dev
build-all:
stage: build
extends:
- .ubuntu-common
script:
# Run the spread prepare section to build everything.
- yq -r '.prepare' <spread.yaml | SPREAD_PATH=. bash -xeu
- .ubuntu-before_script
artifacts:
name: ${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
expire_in: 30 days
@ -58,33 +35,39 @@ build-all:
- changehat/mod_apparmor/
- changehat/pam_apparmor/
- profiles/
script:
- *install-c-build-deps
- cd libraries/libapparmor && ./autogen.sh && ./configure --with-perl --with-python --prefix=/usr && make && cd ../.. || { cat config.log ; exit 1 ; }
- make -C parser
- make -C binutils
- make -C utils
- make -C changehat/mod_apparmor
- make -C changehat/pam_apparmor
- make -C profiles
test-libapparmor:
stage: test
needs: ["build-all"]
extends:
- .ubuntu-common
- .ubuntu-before_script
script:
# This is to touch the built files in the test stage to avoid needless rebuilding
- make -C libraries/libapparmor --touch
- *install-c-build-deps
- make -C libraries/libapparmor check
test-parser:
stage: test
needs: ["build-all"]
extends:
- .ubuntu-common
- .ubuntu-before_script
script:
# This is to touch the built files in the test stage to avoid needless rebuilding
- make -C parser --touch
- make -C parser -j $(nproc) tst_binaries
- *install-c-build-deps
- make -C parser check
test-binutils:
stage: test
needs: ["build-all"]
extends:
- .ubuntu-common
- .ubuntu-before_script
script:
- make -C binutils check
@ -92,16 +75,9 @@ test-utils:
stage: test
needs: ["build-all"]
extends:
- .ubuntu-common
- .ubuntu-before_script
script:
# This is to touch the built files in the test stage to avoid needless rebuilding
- make -C utils --touch
# TODO: move those to cloud-init list?
- printf '\e[0K%s:%s:%s[collapsed=true]\r\e[0K%s\n' section_start "$(date +%s)" install_extra_deps "Installing additional dependencies..."
- apt-get install --no-install-recommends -y libc6-dev libjs-jquery libjs-jquery-throttle-debounce libjs-jquery-isonscreen libjs-jquery-tablesorter flake8 python3-coverage python3-notify2 python3-psutil python3-setuptools python3-tk python3-ttkthemes python3-gi
- printf '\e[0K%s:%s:%s\r\e[0K\n' section_end "$(date +%s)" install_extra_deps
- apt-get install --no-install-recommends -y libc6-dev libjs-jquery libjs-jquery-throttle-debounce libjs-jquery-isonscreen libjs-jquery-tablesorter pyflakes3 python3-coverage python3-notify2 python3-psutil python3-setuptools
# See apparmor/apparmor#221
- make -C parser/tst gen_dbus
- make -C parser/tst gen_xtrans
@ -116,37 +92,31 @@ test-mod-apparmor:
stage: test
needs: ["build-all"]
extends:
- .ubuntu-common
- .ubuntu-before_script
script:
# This is to touch the built files in the test stage to avoid needless rebuilding
- make -C changehat/mod_apparmor --touch
- make -C changehat/mod_apparmor check
test-profiles:
stage: test
needs: ["build-all"]
extends:
- .ubuntu-common
- .ubuntu-before_script
script:
# This is to touch the built files in the test stage to avoid needless rebuilding
- make -C profiles --touch
- make -C profiles check-parser
- make -C profiles check-abstractions.d
- make -C profiles check-local
- make -C profiles check-extras
shellcheck:
stage: test
needs: []
extends:
- .ubuntu-common
- .ubuntu-before_script
script:
- printf '\e[0K%s:%s:%s[collapsed=true]\r\e[0K%s\n' section_start "$(date +%s)" install_extra_deps "Installing additional dependencies..."
- apt-get install --no-install-recommends -y python3-minimal file shellcheck xmlstarlet
- printf '\e[0K%s:%s:%s\r\e[0K\n' section_end "$(date +%s)" install_extra_deps
- shellcheck --version
- "./tests/bin/shellcheck-tree --format=checkstyle
| xmlstarlet tr tests/checkstyle2junit.xslt
> shellcheck.xml"
- apt-get install --no-install-recommends -y file shellcheck xmlstarlet
- shellcheck --version
- './tests/bin/shellcheck-tree --format=checkstyle
| xmlstarlet tr tests/checkstyle2junit.xslt
> shellcheck.xml'
artifacts:
when: always
reports:
@ -168,170 +138,29 @@ variables:
SAST_EXCLUDED_ANALYZERS: "eslint,flawfinder,semgrep,spotbugs"
SAST_BANDIT_EXCLUDED_PATHS: "*/tst/*, */test/*"
.send-to-coverity: &send-to-coverity
- curl https://scan.coverity.com/builds?project=$COVERITY_SCAN_PROJECT_NAME
--form token=$COVERITY_SCAN_TOKEN --form email=$GITLAB_USER_EMAIL
--form file=@$(ls apparmor-*-cov-int.tar.gz) --form version="$(git describe --tags)"
--form description="$(git describe --tags) / $CI_COMMIT_TITLE / $CI_COMMIT_REF_NAME:$CI_PIPELINE_ID"
coverity:
stage: .post
interruptible: true
extends:
- .ubuntu-common
- .ubuntu-before_script
only:
refs:
- master
script:
- printf '\e[0K%s:%s:%s[collapsed=true]\r\e[0K%s\n' section_start "$(date +%s)" install_extra_deps "Installing additional dependencies..."
- apt-get install --no-install-recommends -y curl git texlive-latex-recommended
- printf '\e[0K%s:%s:%s\r\e[0K\n' section_end "$(date +%s)" install_extra_deps
- curl -o /tmp/cov-analysis-linux64.tgz https://scan.coverity.com/download/linux64
--form project=$COVERITY_SCAN_PROJECT_NAME --form token=$COVERITY_SCAN_TOKEN
- tar xfz /tmp/cov-analysis-linux64.tgz
- COV_VERSION=$(ls -dt cov-analysis-linux64-* | head -1)
- PATH=$PATH:$(pwd)/$COV_VERSION/bin
- make coverity
- curl https://scan.coverity.com/builds?project=$COVERITY_SCAN_PROJECT_NAME
--form token=$COVERITY_SCAN_TOKEN --form email=$GITLAB_USER_EMAIL
--form file=@$(ls apparmor-*-cov-int.tar.gz) --form version="$(git describe --tags)"
--form description="$(git describe --tags) / $CI_COMMIT_TITLE / $CI_COMMIT_REF_NAME:$CI_PIPELINE_ID"
- apt-get install --no-install-recommends -y curl git texlive-latex-recommended
- *install-c-build-deps
- curl -o /tmp/cov-analysis-linux64.tgz https://scan.coverity.com/download/linux64
--form project=$COVERITY_SCAN_PROJECT_NAME --form token=$COVERITY_SCAN_TOKEN
- tar xfz /tmp/cov-analysis-linux64.tgz
- COV_VERSION=$(ls -dt cov-analysis-linux64-* | head -1)
- PATH=$PATH:$(pwd)/$COV_VERSION/bin
- make coverity
- *send-to-coverity
artifacts:
paths:
- "apparmor-*.tar.gz"
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PROJECT_PATH == "apparmor/apparmor"
.image-garden-x86_64:
stage: spread
interruptible: true
# TODO: use tagged release once container tagging is improved upstream.
image: registry.gitlab.com/zygoon/image-garden:latest
tags:
- linux
- x86_64
- kvm
variables:
ARCH: x86_64
GARDEN_DL_DIR: dl
CACHE_POLICY: pull-push
CACHE_COMPRESSION_LEVEL: fastest
before_script:
# Restore the mtime of the .image-garden.mk file. This helps make determine
# if there's actually something to do correctly. Git does not preserve the
# mtime of files during checkout.
- git restore-mtime .image-garden.mk
# Prepare the image in dry-run mode. This helps in debugging cache misses
# when files are not cached correctly by the runner, causing the build section
# below to always do hevy-duty work.
- printf '\e[0K%s:%s:%s[collapsed=true]\r\e[0K%s\n' section_start "$(date +%s)" prepare_image_dry_run "Prepare image (dry run)"
- image-garden make --dry-run --debug "$GARDEN_SYSTEM.$ARCH.run" "$GARDEN_SYSTEM.$ARCH.qcow2" "$GARDEN_SYSTEM.seed.iso" "$GARDEN_SYSTEM.user-data" "$GARDEN_SYSTEM.meta-data"
- printf '\e[0K%s:%s:%s\r\e[0K\n' section_end "$(date +%s)" prepare_image_dry_run
script:
# Prepare the image, for real.
- printf '\e[0K%s:%s:%s[collapsed=true]\r\e[0K%s\n' section_start "$(date +%s)" prepare_image "Prepare image"
# If there's nothing to do then remove all the files that we would normally
# cache so that GitLab skips the cache upload step. This saves significant
# time required to re-compress and upload unchanged content.
# The idea for how to do is is documented at
# https://olex.biz/2025/04/gitlab-ci-prevent-cache-reupload-without-changes/
# The GitLab issue requesting a proper feature is
# https://gitlab.com/gitlab-org/gitlab/-/issues/226068
- |
if image-garden make --question "$GARDEN_SYSTEM.$ARCH.run" "$GARDEN_SYSTEM.$ARCH.qcow2" "$GARDEN_SYSTEM.seed.iso" "$GARDEN_SYSTEM.user-data" "$GARDEN_SYSTEM.meta-data"; then
rm -f "$GARDEN_SYSTEM".* efi-code.*.img efi-vars.*.img
rm -rf "$GARDEN_DL_DIR"
else
image-garden make "$GARDEN_SYSTEM.$ARCH.run" "$GARDEN_SYSTEM.$ARCH.qcow2" "$GARDEN_SYSTEM.seed.iso" "$GARDEN_SYSTEM.user-data" "$GARDEN_SYSTEM.meta-data"
fi
- printf '\e[0K%s:%s:%s\r\e[0K\n' section_end "$(date +%s)" prepare_image
cache:
# Cache the base image (pre-customization).
- key: image-garden-base-${GARDEN_SYSTEM}.${ARCH}
policy: $CACHE_POLICY
when: always
paths:
- $GARDEN_DL_DIR
# Those are never mutated so they are safe to share.
- efi-code.*.img
- efi-vars.*.img
# Cache the customized system. This cache depends on .image-garden.mk file
# so that any customization updates are immediately acted upon.
- key:
prefix: image-garden-custom-${GARDEN_SYSTEM}.${ARCH}-
files:
- .image-garden.mk
policy: $CACHE_POLICY
when: always
paths:
- $GARDEN_SYSTEM.*
- $GARDEN_SYSTEM.seed.iso
- $GARDEN_SYSTEM.meta-data
- $GARDEN_SYSTEM.user-data
# This job builds and caches the image that the job below looks at.
image-ubuntu-cloud-24.04-x86_64:
extends: .image-garden-x86_64
variables:
GARDEN_SYSTEM: ubuntu-cloud-24.04
needs: []
dependencies: []
rules:
- if: $CI_COMMIT_TAG
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
changes:
paths:
- .image-garden.mk
- .gitlab-ci.yml
compare_to: "refs/heads/master"
- if: $CI_COMMIT_BRANCH && "$[[ inputs.build-test-images ]]" == "true"
.spread-x86_64:
extends: .image-garden-x86_64
variables:
# GitLab project identifier of zygoon/spread-dist can be seen on
# https://gitlab.com/zygoon/spread-dist, under the three-dot menu on
# top-right.
SPREAD_GITLAB_PROJECT_ID: "65375371"
# Git revision of spread to install.
# This must have been built via spread-dist.
# TODO: switch to upstream 1.0 release when available.
SPREAD_REV: 413817eda7bec07a3885e0717c178b965f8924e1
# Run all the tasks for a given system.
SPREAD_ARGS: "garden:$GARDEN_SYSTEM:"
SPREAD_GOARCH: amd64
before_script:
# Restore the mtime of the .image-garden.mk file. This helps make determine
# if there's actually something to do correctly. Git does not preserve the
# mtime of files during checkout.
- git restore-mtime .image-garden.mk
# Prepare the image in dry-run mode. This helps in debugging cache misses
# when files are not cached correctly by the runner, causing the build section
# below to always do hevy-duty work.
- printf '\e[0K%s:%s:%s[collapsed=true]\r\e[0K%s\n' section_start "$(date +%s)" prepare_image_dry_run "Prepare image (dry run)"
- image-garden make --dry-run --debug "$GARDEN_SYSTEM.$ARCH.run" "$GARDEN_SYSTEM.$ARCH.qcow2" "$GARDEN_SYSTEM.seed.iso" "$GARDEN_SYSTEM.user-data" "$GARDEN_SYSTEM.meta-data"
- stat .image-garden.mk "$GARDEN_SYSTEM".* || true
- printf '\e[0K%s:%s:%s\r\e[0K\n' section_end "$(date +%s)" prepare_image_dry_run
# Install the selected revision of spread.
- printf '\e[0K%s:%s:%s[collapsed=true]\r\e[0K%s\n' section_start "$(date +%s)" install_spread "Installing spread..."
# Install pre-built spread from https://gitlab.com/zygoon/spread-dist generic package repository.
- |
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --location --output spread "${CI_API_V4_URL}/projects/${SPREAD_GITLAB_PROJECT_ID}/packages/generic/spread/${SPREAD_REV}/spread.${SPREAD_GOARCH}"
- chmod +x spread
- printf '\e[0K%s:%s:%s\r\e[0K\n' section_end "$(date +%s)" install_spread
script:
- printf '\e[0K%s:%s:%s\r\e[0K%s\n' section_start "$(date +%s)" run_spread "Running spread for $GARDEN_SYSTEM..."
# TODO: transform to inject ^...$ to properly select jobs to run.
- mkdir -p spread-logs spread-artifacts
- ./spread -list $SPREAD_ARGS |
split --number=l/"${CI_NODE_INDEX:-1}"/"${CI_NODE_TOTAL:-1}" |
xargs --verbose ./spread -v -artifacts ./spread-artifacts -v | tee spread-logs/"$GARDEN_SYSTEM".log
- printf '\e[0K%s:%s:%s\r\e[0K\n' section_end "$(date +%s)" run_spread
artifacts:
paths:
- spread-logs
- spread-artifacts
when: always
spread-ubuntu-cloud-24.04-x86_64:
extends: .spread-x86_64
variables:
GARDEN_SYSTEM: ubuntu-cloud-24.04
SPREAD_ARGS: garden:$GARDEN_SYSTEM:tests/regression/ garden:$GARDEN_SYSTEM:tests/profiles/
CACHE_POLICY: pull
dependencies: []
needs:
- job: image-ubuntu-cloud-24.04-x86_64
optional: true
parallel: 4

View File

@ -1,129 +0,0 @@
# This file is read by image-garden when spread is allocating test machines.
# All the package installation happens through cloud-init profiles defined
# below.
# NOTE: Should the kernel be out of date, just increment this value. Make will
# re-create the image whenever the .image-garden.mk file is more recent than
# the image itself. In reality all you need is touch(1), but this is more apt.
unused=1
# This is the cloud-init user-data profile for all Debian systems. Note that it
# is an extension of the default profile necessary for operation of
# image-garden.
define DEBIAN_CLOUD_INIT_USER_DATA_TEMPLATE
$(CLOUD_INIT_USER_DATA_TEMPLATE)
packages:
- apache2-dev
- attr
- autoconf
- autoconf-archive
- automake
- bison
- build-essential
- dejagnu
- dosfstools
- flake8
- flex
- fuse-overlayfs
- gdb
- gettext
- libdbus-1-dev
- libpam0g-dev
- libtool
- liburing-dev
- pkg-config
- proftpd-core
- python3-all-dev
- python3-gi
- python3-notify2
- python3-psutil
- python3-setuptools
- python3-tk
- python3-ttkthemes
- swig
- tinyproxy
# Update all the packages. This allows us to be on the up-to-date kernel
# version that we cannot otherwise easily select with cloud init alone. Note
# that we do not need to reboot the system as image garden shuts down the image
# after first boot. On subsequent boot we will be running the latest kernel.
package_upgrade: true
package_update: true
endef
# Ubuntu shares cloud-init profile with Debian.
UBUNTU_CLOUD_INIT_USER_DATA_TEMPLATE=$(DEBIAN_CLOUD_INIT_USER_DATA_TEMPLATE)
# This is the cloud-init user-data profile for openSUSE Tumbleweed.
define OPENSUSE_tumbleweed_CLOUD_INIT_USER_DATA_TEMPLATE
$(CLOUD_INIT_USER_DATA_TEMPLATE)
- sed -i -e 's/security=selinux/security=apparmor/g' /etc/default/grub
- update-bootloader
packages:
- apache2-devel
- attr
- autoconf
- autoconf-archive
- automake
- bison
- dbus-1-devel
- dejagnu
- dosfstools
- flex
- fuse-overlayfs
- gcc
- gcc-c++
- gdb
- gettext
- gobject-introspection
- libtool
- liburing2-devel
- make
- pam-devel
- pkg-config
- python3-devel
- python3-flake8
- python3-notify2
- python3-psutil
- python3-setuptools
- python3-setuptools
- python3-tk
- python311
- python311-devel
- swig
- which
# See above for rationale.
package_upgrade: true
package_update: true
endef
define FEDORA_CLOUD_INIT_USER_DATA_TEMPLATE
$(CLOUD_INIT_USER_DATA_TEMPLATE)
packages:
- attr
- autoconf
- autoconf-archive
- automake
- bison
- dbus-devel
- dejagnu
- dosfstools
- flex
- gdb
- gettext
- httpd-devel
- libstdc++-static
- libtool
- liburing-devel
- pam-devel
- perl
- pkg-config
- python3-devel
- python3-flake8
- python3-gobject-base
- python3-notify2
- python3-tkinter
- swig
# See above for rationale.
package_upgrade: true
package_update: true
endef

View File

@ -54,9 +54,12 @@ snapshot: clean
.PHONY: coverity
coverity: snapshot
cd $(SNAPSHOT_NAME)/libraries/libapparmor && ./configure --with-python
$(foreach dir, libraries/libapparmor utils, \
cov-build --dir $(COVERITY_DIR) --no-command --fs-capture-search $(SNAPSHOT_NAME)/$(dir); \
mv $(COVERITY_DIR)/build-log.txt $(COVERITY_DIR)/build-log-python-$(subst /,.,$(dir)).txt ;)
cov-build --dir $(COVERITY_DIR) -- sh -c \
"$(foreach dir, $(filter-out utils profiles tests, $(DIRS)), \
$(MAKE) -j $$(nproc) -C $(SNAPSHOT_NAME)/$(dir);) "
$(MAKE) -C $(SNAPSHOT_NAME)/$(dir);) "
tar -cvzf $(SNAPSHOT_NAME)-$(COVERITY_DIR).tar.gz $(COVERITY_DIR)
.PHONY: export_dir

View File

@ -111,21 +111,13 @@ $ export PYTHON_VERSION=3
$ export PYTHON_VERSIONS=python3
```
Note that, in general, the build steps can be run in parallel, while the test
steps do not gain much speedup from being run in parallel. This is because the
test steps spawn a handful of long-lived test runner processes that mostly
run their tests sequentially and do not use `make`'s jobserver. Moreover,
process spawning overhead constitutes a significant part of test runtime, so
reworking the test harnesses to add parallelism (which would be a major undertaking
for the harnesses that do not have it already) would not produce much of a speedup.
### libapparmor:
```
$ cd ./libraries/libapparmor
$ sh ./autogen.sh
$ sh ./configure --prefix=/usr --with-perl --with-python # see below
$ make -j $(nproc)
$ make
$ make check
$ make install
```
@ -138,7 +130,7 @@ generate Ruby bindings to libapparmor.]
```
$ cd binutils
$ make -j $(nproc)
$ make
$ make check
$ make install
```
@ -147,8 +139,7 @@ $ make install
```
$ cd parser
$ make -j $(nproc) # depends on libapparmor having been built first
$ make -j $(nproc) tst_binaries # a build step of make check that can be parallelized
$ make # depends on libapparmor having been built first
$ make check
$ make install
```
@ -158,7 +149,7 @@ $ make install
```
$ cd utils
$ make -j $(nproc)
$ make
$ make check PYFLAKES=/usr/bin/pyflakes3
$ make install
```
@ -167,7 +158,7 @@ $ make install
```
$ cd changehat/mod_apparmor
$ make -j $(nproc) # depends on libapparmor having been built first
$ make # depends on libapparmor having been built first
$ make install
```
@ -176,7 +167,7 @@ $ make install
```
$ cd changehat/pam_apparmor
$ make -j $(nproc) # depends on libapparmor having been built first
$ make # depends on libapparmor having been built first
$ make install
```
@ -206,46 +197,6 @@ usage and how to update and add tests. Below is a quick overview of their
location and how to run them.
Using spread with local virtual machines
----------------------------------------
It may be convenient to use the spread tool to provision and run the test suite
in an ephemeral virtual machine. This allows testing in isolation from the
host, as well as testing across different commonly used distributions and their
real kernels.
Image Garden is available as a snap. If you wish to use it this way then snap
then install the snap with:
```sh
sudo snap install image-garden
```
If you need to install snapd first, see https://snapcraft.io/docs/installing-snapd
Alternatively you may build image-garden and spread from source, and install
dependencies manually.
```sh
sudo apt install git golang whois ovmf genisoimage qemu-utils qemu-system
go install github.com/snapcore/spread/cmd/spread@latest
git clone https://gitlab.com/zygoon/image-garden
make -C image-garden
sudo make -C image-garden install
image-garden make ubuntu-cloud-24.10.x86_64.run
cd $APPARMOR_PATH
git clean -xdf
~/go/bin/spread -artifacts ./spread-artifacts -v ubuntu-cloud-24.10
# or ~/go/bin/spread -v garden:ubuntu-cloud-24.04:tests/regression/apparmor:at_secure
```
Running the `run_spread.sh` script, with `image-garden` snap installed or with
`spread` on `PATH` will run all the tests across several supported systems
(Debian, Ubuntu and openSUSE).
If you include a `bzImage` file in the root of the repository then that kernel
will be used in the integration test. Please look at `spread.yaml` for details.
Regression tests
----------------
For details on structure and adding tests, see
@ -256,7 +207,7 @@ To run:
### Regression tests - using apparmor userspace installed on host
```
$ cd tests/regression/apparmor (requires root)
$ make -j $(nproc) USE_SYSTEM=1
$ make USE_SYSTEM=1
$ sudo make tests USE_SYSTEM=1
$ sudo bash open.sh -r # runs and saves the last testcase from open.sh
```
@ -269,7 +220,7 @@ $ sudo bash open.sh -r # runs and saves the last testcase from open.sh
```
$ cd tests/regression/apparmor (requires root)
$ make -j $(nproc)
$ make
$ sudo make tests
$ sudo bash open.sh -r # runs and saves the last testcase from open.sh
```
@ -403,10 +354,6 @@ The aa-notify tool's Python dependencies can be satisfied by installing the
following packages (Debian package names, other distros may vary):
* python3-notify2
* python3-psutil
* python3-sqlite (part of the python3.NN-stdlib package)
* python3-tk
* python3-ttkthemes
* python3-gi
Perl is no longer needed since none of the utilities shipped to end users depend
on it anymore.

View File

@ -21,7 +21,7 @@ DESTDIR=/
BINDIR=${DESTDIR}/usr/bin
SBINDIR=${DESTDIR}/usr/sbin
LOCALEDIR=/usr/share/locale
MANPAGES=aa-enabled.1 aa-exec.1 aa-features-abi.1 aa-load.8 aa-status.8
MANPAGES=aa-enabled.1 aa-exec.1 aa-features-abi.1 aa-status.8
WARNINGS = -Wall
CPP_WARNINGS =

View File

@ -80,109 +80,6 @@ aa-exec.
=back
=head1 RESTRICTIONS
aa-exec uses I<aa_change_profile(3)> to change application confinement.
The use of I<aa_change_profile(3)> may be restricted by policy in ways
that will cause failure or results different than expected.
Even when using I<aa-exec> from unconfined restrictions in policy can
causes failure or the confinement entered to be different than requested
See the unpriviled unconfined restriction documentation for more detail.
https://gitlab.com/apparmor/apparmor/-/wikis/unprivileged_unconfined_restriction
=head1 STACKING
aa-exec can be used to setup a stack of profiles as confinement. When an
application is confined by a stack, all profiles in the stack are checked
as if they were the profile confining the application. The resulting
mediation is the intersection of what is allowed by each profile in the
stack.
The profiles in a stack are treated independently. Each profile can have
its own flags and profile transitions. During an exec each profile gets
to specify its transition and the results brought together to form a
new canonicalized stack.
The profile separator indicating a stack is the character sequence I<//&>.
Thus a stack can be expressed using
=over 4
$ aa-exec -p "unconfined//&firefox" -- bash
$ ps -Z
LABEL PID TTY TIME CMD
unconfined 30714 pts/12 00:00:00 bash
firefox//&unconfined (unconfined) 31160 pts/12 00:00:00 bash
firefox//&unconfined (unconfined) 31171 pts/12 00:00:00 ps
=back
=head1 NAMESPACES
aa-exec can be used to enter confinement in another policy namespace
if the policy namespaces exists, is visible, and the profile exists in
the namespace. Note applications launched within the namespace will
not be able to exit the namespace, and may be restricted by additional
confinement around namespacing. Files and resources visible to the
parent that launches the application may not be visible in the policy
namespace resulting in access denials.
To enter a policy namespace the profile is prefixed with the namespace's
name, using a I<:> prefix and suffix.
Eg.
=over 4
$ aa-exec -p :ex1:unconfined -- bash
$ ps -Z
LABEL PID TTY TIME CMD
- 30714 pts/12 00:00:00 bash
unconfined 34372 pts/12 00:00:00 bash
unconfined 34379 pts/12 00:00:00 ps
=back
Confinement of processes outside of the namespace may not be visible
in which case the confinement will be represented with a -. If policy
is stacked only part of the confinement might be visible. However
confinement is usually fully visible from the parent policy namespace.
Eg. the confinement of the child can be queried in the parent to see
=over 4
$ ps -Z 34372
LABEL PID TTY STAT TIME COMMAND
:ex1:unconfined 34372 pts/12 S+ 0:00 bash
=back
And in the case of stacking with namespaces
=over 4
$ aa-exec -p "unconfined//&:ex1:unconfined" -- bash
$ ps -Z
LABEL PID TTY TIME CMD
- 30714 pts/12 00:00:00 bash
unconfined 36298 pts/12 00:00:00 bash
unconfined 36305 pts/12 00:00:00 ps
=back
while from the parent namespace the full confinement can be seen
=over 4
$ ps -Z 36298
LABEL PID TTY STAT TIME COMMAND
unconfined//&:ex1:unconfined 36298 pts/12 S+ 0:00 bash
=back
=head1 BUGS
If you find any bugs, please report them at
@ -190,7 +87,7 @@ L<https://gitlab.com/apparmor/apparmor/-/issues>
=head1 SEE ALSO
apparmor(7), apparmor.d(5), aa_change_profile(3),
aa-stack(8), aa-namespace(8), apparmor(7), apparmor.d(5), aa_change_profile(3),
aa_change_onexec(3) and L<https://wiki.apparmor.net>.
=cut

View File

@ -1,77 +0,0 @@
# This publication is intellectual property of Canonical Ltd. Its contents
# can be duplicated, either in part or in whole, provided that a copyright
# label is visibly located on each copy.
#
# All information found in this book has been compiled with utmost
# attention to detail. However, this does not guarantee complete accuracy.
# Neither Canonical Ltd, the authors, nor the translators shall be held
# liable for possible errors or the consequences thereof.
#
# Many of the software and hardware descriptions cited in this book
# are registered trademarks. All trade names are subject to copyright
# restrictions and may be registered trade marks. Canonical Ltd
# essentially adheres to the manufacturer's spelling.
#
# Names of products and trademarks appearing in this book (with or without
# specific notation) are likewise subject to trademark and trade protection
# laws and may thus fall under copyright restrictions.
#
=pod
=head1 NAME
aa-load - load precompiled AppArmor policy from cache location(s)
=head1 SYNOPSIS
B<aa-load> [options] (cache file|cache dir|cache base dir)+
=head1 DESCRIPTION
B<aa-load> loads precompiled AppArmor policy from the specified locations.
=head1 OPTIONS
B<aa-load> accepts the following arguments:
=over 4
=item -f, --force
Force B<aa-load> to load a policy even if its abi does not match the kernel abi.
=item -d, --debug
Display debug messages.
=item -v, --verbose
Display progress and error messages.
=item -n, --dry-run
Do not actually load the specified policy/policies into the kernel.
=item -h, --help
Display a brief usage guide.
=back
=head1 EXIT STATUS
Upon exiting, B<aa-load> returns 0 upon success and 1 upon an error loading
the precompiled policy.
=head1 BUGS
If you find any bugs, please report them at
L<https://gitlab.com/apparmor/apparmor/-/issues>.
=head1 SEE ALSO
apparmor(7), apparmor.d(5), apparmor_parser(8), and L<https://wiki.apparmor.net>.
=cut

View File

@ -117,13 +117,13 @@ display only counts for selected information.
=item --filter.mode=filter
Allows specifying a posix regular expression filter that will be
applied against the displayed processes and profiles apparmor profile
applied against the displayed processess and profiles apparmor profile
mode, reducing the output.
=item --filter.profiles=filter
Allows specifying a posix regular expression filter that will be
applied against the displayed processes and profiles confining
applied against the displayed processess and profiles confining
profile, reducing the output.
=item --filter.pid=filter

View File

@ -17,7 +17,6 @@
#include <fcntl.h>
#include <string.h>
#include <dirent.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
@ -173,8 +172,7 @@ static int load_policy_dir(const char *dir_path)
while ((dir = readdir(d)) != NULL) {
/* Only check regular files for now */
if (dir->d_type == DT_REG) {
/* As per POSIX dir->d_name has at most NAME_MAX characters */
len = strnlen(dir->d_name, NAME_MAX);
len = strnlen(dir->d_name, PATH_MAX);
/* Ignores .features */
if (strncmp(dir->d_name, CACHE_FEATURES_FILE, len) == 0) {
continue;
@ -310,8 +308,9 @@ static int load_arg(char *arg)
static void print_usage(const char *command)
{
printf("Usage: %s [OPTIONS] (cache file|cache dir|cache base dir)+\n"
"Load precompiled AppArmor policy from cache location(s)\n\n"
printf("Usage: %s [OPTIONS] (cache file|cache dir|cache base dir)]*\n"
"Load Precompiled AppArmor policy from a cache location or \n"
"locations.\n\n"
"Options:\n"
" -f, --force load policy even if abi does not match the kernel\n"
" -d, --debug display debug messages\n"

View File

@ -20,8 +20,6 @@
#include <ctype.h>
#include <dirent.h>
#include <regex.h>
#include <libintl.h>
#define _(s) gettext(s)
#include <sys/apparmor.h>
#include <sys/apparmor_private.h>
@ -133,7 +131,7 @@ const char *process_statuses[] = {"enforce", "complain", "prompt", "kill", "unco
#define eprintf(...) \
do { \
if (!quiet) \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, __VA_ARGS__); \
} while (0)
#define dprintf(...) \
@ -158,14 +156,14 @@ static int open_profiles(FILE **fp)
ret = stat("/sys/module/apparmor", &st);
if (ret != 0) {
eprintf(_("apparmor not present.\n"));
eprintf("apparmor not present.\n");
return AA_EXIT_DISABLED;
}
dprintf(_("apparmor module is loaded.\n"));
dprintf("apparmor module is loaded.\n");
ret = aa_find_mountpoint(&apparmorfs);
if (ret == -1) {
eprintf(_("apparmor filesystem is not mounted.\n"));
eprintf("apparmor filesystem is not mounted.\n");
return AA_EXIT_NO_CONTROL;
}
@ -178,9 +176,9 @@ static int open_profiles(FILE **fp)
*fp = fopen(apparmor_profiles, "r");
if (*fp == NULL) {
if (errno == EACCES) {
eprintf(_("You do not have enough privilege to read the profile set.\n"));
eprintf("You do not have enough privilege to read the profile set.\n");
} else {
eprintf(_("Could not open %s: %s"), apparmor_profiles, strerror(errno));
eprintf("Could not open %s: %s", apparmor_profiles, strerror(errno));
}
return AA_EXIT_NO_PERM;
}
@ -353,7 +351,7 @@ static int get_processes(struct profile *profiles,
continue;
} else if (rc == -1 ||
asprintf(&exe, "/proc/%s/exe", entry->d_name) == -1) {
eprintf(_("ERROR: Failed to allocate memory\n"));
eprintf("ERROR: Failed to allocate memory\n");
ret = AA_EXIT_INTERNAL_ERROR;
goto exit;
} else if (mode) {
@ -376,7 +374,7 @@ static int get_processes(struct profile *profiles,
// ensure enough space for NUL terminator
real_exe = calloc(PATH_MAX + 1, sizeof(char));
if (real_exe == NULL) {
eprintf(_("ERROR: Failed to allocate memory\n"));
eprintf("ERROR: Failed to allocate memory\n");
ret = AA_EXIT_INTERNAL_ERROR;
goto exit;
}
@ -490,7 +488,7 @@ static int filter_processes(struct process *processes,
*
* Return: 0 on success, else shell error code
*/
static int simple_filtered_count(FILE *outf, filters_t *filters, bool json,
static int simple_filtered_count(FILE *outf, filters_t *filters,
struct profile *profiles, size_t nprofiles)
{
struct profile *filtered = NULL;
@ -499,13 +497,7 @@ static int simple_filtered_count(FILE *outf, filters_t *filters, bool json,
ret = filter_profiles(profiles, nprofiles, filters,
&filtered, &nfiltered);
if (!json) {
fprintf(outf, "%zd\n", nfiltered);
} else {
fprintf(outf, "\"profile_count\": %zd", nfiltered);
}
fprintf(outf, "%zd\n", nfiltered);
free_profiles(filtered, nfiltered);
return ret;
@ -520,7 +512,7 @@ static int simple_filtered_count(FILE *outf, filters_t *filters, bool json,
*
* Return: 0 on success, else shell error code
*/
static int simple_filtered_process_count(FILE *outf, filters_t *filters, bool json,
static int simple_filtered_process_count(FILE *outf, filters_t *filters,
struct process *processes, size_t nprocesses) {
struct process *filtered = NULL;
size_t nfiltered;
@ -528,12 +520,7 @@ static int simple_filtered_process_count(FILE *outf, filters_t *filters, bool js
ret = filter_processes(processes, nprocesses, filters, &filtered,
&nfiltered);
if (!json) {
fprintf(outf, "%zd\n", nfiltered);
} else {
fprintf(outf, "\"process_count\": %zd", nfiltered);
}
fprintf(outf, "%zd\n", nfiltered);
free_processes(filtered, nfiltered);
return ret;
@ -552,12 +539,7 @@ static int compare_processes_by_executable(const void *a, const void *b) {
static void json_header(FILE *outf)
{
fprintf(outf, "{\"version\": \"%s\"", aa_status_json_version);
}
static void json_seperator(FILE *outf)
{
fprintf(outf, ", ");
fprintf(outf, "{\"version\": \"%s\", ", aa_status_json_version);
}
static void json_footer(FILE *outf)
@ -600,7 +582,7 @@ static int detailed_profiles(FILE *outf, filters_t *filters, bool json,
*/
subfilters.mode = &mode_filter;
if (regcomp(&mode_filter, profile_statuses[i], REG_NOSUB) != 0) {
eprintf(_("Error: failed to compile sub filter '%s'\n"),
eprintf("Error: failed to compile sub filter '%s'\n",
profile_statuses[i]);
return AA_EXIT_INTERNAL_ERROR;
}
@ -625,7 +607,7 @@ static int detailed_profiles(FILE *outf, filters_t *filters, bool json,
free_profiles(filtered, nfiltered);
}
if (json)
fprintf(outf, "}");
fprintf(outf, "}, ");
return AA_EXIT_ENABLED;
}
@ -666,7 +648,7 @@ static int detailed_processes(FILE *outf, filters_t *filters, bool json,
*/
subfilters.mode = &mode_filter;
if (regcomp(&mode_filter, process_statuses[i], REG_NOSUB) != 0) {
eprintf(_("Error: failed to compile sub filter '%s'\n"),
eprintf("Error: failed to compile sub filter '%s'\n",
profile_statuses[i]);
return AA_EXIT_INTERNAL_ERROR;
}
@ -718,7 +700,7 @@ static int detailed_processes(FILE *outf, filters_t *filters, bool json,
fprintf(outf, "]");
}
fprintf(outf, "}");
fprintf(outf, "}\n");
}
exit:
@ -728,7 +710,7 @@ exit:
static int print_legacy(const char *command)
{
printf(_("Usage: %s [OPTIONS]\n"
printf("Usage: %s [OPTIONS]\n"
"Legacy options and their equivalent command\n"
" --profiled --count --profiles\n"
" --enforced --count --profiles --mode=enforced\n"
@ -736,8 +718,8 @@ static int print_legacy(const char *command)
" --kill --count --profiles --mode=kill\n"
" --prompt --count --profiles --mode=prompt\n"
" --special-unconfined --count --profiles --mode=unconfined\n"
" --process-mixed --count --ps --mode=mixed\n"),
command);
" --process-mixed --count --ps --mode=mixed\n",
command);
exit(0);
return 0;
@ -747,7 +729,7 @@ static int usage_filters(void)
{
long unsigned int i;
printf(_("Usage of filters\n"
printf("Usage of filters\n"
"Filters are used to reduce the output of information to only\n"
"those entries that will match the filter. Filters use posix\n"
"regular expression syntax. The possible values for exes that\n"
@ -757,7 +739,7 @@ static int usage_filters(void)
" --filter.profiles: regular expression to match displayed profile names\n"
" --filter.pid: regular expression to match displayed processes pids\n"
" --filter.exe: regular expression to match executable\n"
));
);
for (i = 0; i < ARRAY_SIZE(process_statuses); i++) {
printf("%s%s", i ? ", " : "", process_statuses[i]);
}
@ -775,7 +757,7 @@ static int print_usage(const char *command, bool error)
status = EXIT_FAILURE;
}
printf(_("Usage: %s [OPTIONS]\n"
printf("Usage: %s [OPTIONS]\n"
"Displays various information about the currently loaded AppArmor policy.\n"
"Default if no options given\n"
" --show=all\n\n"
@ -792,8 +774,8 @@ static int print_usage(const char *command, bool error)
" --verbose (default) displays data points about loaded policy set\n"
" --quiet don't output error messages\n"
" -h[(legacy|filters)] this message, or info on the specified option\n"
" --help[=(legacy|filters)] this message, or info on the specified option\n"),
command);
" --help[=(legacy|filters)] this message, or info on the specified option\n",
command);
exit(status);
@ -869,7 +851,7 @@ static int parse_args(int argc, char **argv)
} else if (strcmp(optarg, "filters") == 0) {
usage_filters();
} else {
eprintf(_("Error: Invalid --help option '%s'.\n"), optarg);
eprintf("Error: Invalid --help option '%s'.\n", optarg);
print_usage(argv[0], true);
break;
}
@ -937,7 +919,7 @@ static int parse_args(int argc, char **argv)
} else if (strcmp(optarg, "processes") == 0) {
opt_show = SHOW_PROCESSES;
} else {
eprintf(_("Error: Invalid --show option '%s'.\n"), optarg);
eprintf("Error: Invalid --show option '%s'.\n", optarg);
print_usage(argv[0], true);
break;
}
@ -959,7 +941,7 @@ static int parse_args(int argc, char **argv)
break;
default:
eprintf(_("Error: Invalid command.\n"));
eprintf("Error: Invalid command.\n");
print_usage(argv[0], true);
break;
}
@ -984,7 +966,7 @@ int main(int argc, char **argv)
if (argc > 1) {
int pos = parse_args(argc, argv);
if (pos < argc) {
eprintf(_("Error: Unknown options.\n"));
eprintf("Error: Unknown options.\n");
print_usage(progname, true);
}
} else {
@ -996,24 +978,24 @@ int main(int argc, char **argv)
init_filters(&filters, &filter_set);
if (regcomp(filters.mode, opt_mode, REG_NOSUB) != 0) {
eprintf(_("Error: failed to compile mode filter '%s'\n"),
eprintf("Error: failed to compile mode filter '%s'\n",
opt_mode);
return AA_EXIT_INTERNAL_ERROR;
}
if (regcomp(filters.profile, opt_profiles, REG_NOSUB) != 0) {
eprintf(_("Error: failed to compile profiles filter '%s'\n"),
eprintf("Error: failed to compile profiles filter '%s'\n",
opt_profiles);
ret = AA_EXIT_INTERNAL_ERROR;
goto out;
}
if (regcomp(filters.pid, opt_pid, REG_NOSUB) != 0) {
eprintf(_("Error: failed to compile ps filter '%s'\n"),
eprintf("Error: failed to compile ps filter '%s'\n",
opt_pid);
ret = AA_EXIT_INTERNAL_ERROR;
goto out;
}
if (regcomp(filters.exe, opt_exe, REG_NOSUB) != 0) {
eprintf(_("Error: failed to compile exe filter '%s'\n"),
eprintf("Error: failed to compile exe filter '%s'\n",
opt_exe);
ret = AA_EXIT_INTERNAL_ERROR;
goto out;
@ -1028,7 +1010,7 @@ int main(int argc, char **argv)
outf_save = outf;
outf = open_memstream(&buffer, &buffer_size);
if (!outf) {
eprintf(_("Failed to open memstream: %m\n"));
eprintf("Failed to open memstream: %m\n");
return AA_EXIT_INTERNAL_ERROR;
}
}
@ -1038,20 +1020,16 @@ int main(int argc, char **argv)
* have policy associated.
*/
ret = get_profiles(fp, &profiles, &nprofiles);
if (ret == AA_EXIT_NO_POLICY) {
eprintf(_("No policy loaded into the kernel\n"));
} else if (ret != 0 && !opt_json) {
eprintf(_("Failed to retrieve profiles from kernel: %d....\n"), ret);
if (ret != 0) {
eprintf("Failed to get profiles: %d....\n", ret);
goto out;
}
if (opt_json)
json_header(outf);
if (opt_show & SHOW_PROFILES) {
if (opt_json)
json_seperator(outf);
if (opt_count) {
ret = simple_filtered_count(outf, &filters, opt_json,
ret = simple_filtered_count(outf, &filters,
profiles, nprofiles);
} else {
ret = detailed_profiles(outf, &filters, opt_json,
@ -1062,17 +1040,14 @@ int main(int argc, char **argv)
}
if (opt_show & SHOW_PROCESSES) {
if (opt_json)
json_seperator(outf);
struct process *processes = NULL;
size_t nprocesses = 0;
ret = get_processes(profiles, nprofiles, &processes, &nprocesses);
if (ret != 0) {
eprintf(_("Failed to get confinement information from processes: %d....\n"), ret);
eprintf("Failed to get processes: %d....\n", ret);
} else if (opt_count) {
ret = simple_filtered_process_count(outf, &filters, opt_json,
ret = simple_filtered_process_count(outf, &filters,
processes, nprocesses);
} else {
ret = detailed_processes(outf, &filters, opt_json,
@ -1096,14 +1071,14 @@ int main(int argc, char **argv)
outf = outf_save;
json = cJSON_Parse(buffer);
if (!json) {
eprintf(_("Failed to parse json output"));
eprintf("Failed to parse json output");
ret = AA_EXIT_INTERNAL_ERROR;
goto out;
}
pretty = cJSON_Print(json);
if (!pretty) {
eprintf(_("Failed to print pretty json"));
eprintf("Failed to print pretty json");
ret = AA_EXIT_INTERNAL_ERROR;
goto out;
}

View File

@ -1,14 +1,14 @@
# Translations for aa_enabled
# Copyright (C) 2024 Canonical Ltd
# This file is distributed under the same license as the AppArmor package.
# John Johansen <john.johansen@canonical.com>, 2020.
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Canonical Ltd
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n"
"POT-Creation-Date: 2024-08-31 15:59-0700\n"
"POT-Creation-Date: 2020-10-14 03:52-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"

View File

@ -1,14 +1,14 @@
# Translations for aa_exec
# Copyright (C) 2024 Canonical Ltd
# This file is distributed under the same license as the AppArmor package.
# John Johansen <john.johansen@canonical.com>, 2020.
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Canonical Ltd
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n"
"POT-Creation-Date: 2024-08-31 15:59-0700\n"
"POT-Creation-Date: 2020-10-14 03:52-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"

View File

@ -1,14 +1,14 @@
# Translations for aa_features_abi
# Copyright (C) 2024 Canonical Ltd
# This file is distributed under the same license as the AppArmor package.
# John Johansen <john.johansen@canonical.com>, 2011.
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Canonical Ltd
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n"
"POT-Creation-Date: 2024-08-31 15:59-0700\n"
"POT-Creation-Date: 2020-10-14 03:52-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"

View File

@ -1,34 +0,0 @@
# Translations for aa_load
# Copyright (C) 2024 Canonical Ltd
# This file is distributed under the same license as the AppArmor package.
# John Johansen <john.johansen@canonical.com>, 2020.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n"
"POT-Creation-Date: 2024-08-31 15:59-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: ../aa_load.c:40
msgid "aa-load: WARN: "
msgstr ""
#: ../aa_load.c:41
msgid "aa-load: ERROR: "
msgstr ""
#: ../aa_load.c:51
msgid "\n"
msgstr ""
#: ../aa_load.c:52
msgid "aa-load: DEBUG: "
msgstr ""

View File

@ -1,179 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Canonical Ltd
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n"
"POT-Creation-Date: 2025-04-26 11:12-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: ../aa_status.c:161
msgid "apparmor not present.\n"
msgstr ""
#: ../aa_status.c:164
msgid "apparmor module is loaded.\n"
msgstr ""
#: ../aa_status.c:168
msgid "apparmor filesystem is not mounted.\n"
msgstr ""
#: ../aa_status.c:181
msgid "You do not have enough privilege to read the profile set.\n"
msgstr ""
#: ../aa_status.c:183
#, c-format
msgid "Could not open %s: %s"
msgstr ""
#: ../aa_status.c:356 ../aa_status.c:379
msgid "ERROR: Failed to allocate memory\n"
msgstr ""
#: ../aa_status.c:587 ../aa_status.c:653 ../aa_status.c:603 ../aa_status.c:669
#, c-format
msgid "Error: failed to compile sub filter '%s'\n"
msgstr ""
#: ../aa_status.c:715 ../aa_status.c:731
#, c-format
msgid ""
"Usage: %s [OPTIONS]\n"
"Legacy options and their equivalent command\n"
" --profiled --count --profiles\n"
" --enforced --count --profiles --mode=enforced\n"
" --complaining --count --profiles --mode=complain\n"
" --kill --count --profiles --mode=kill\n"
" --prompt --count --profiles --mode=prompt\n"
" --special-unconfined --count --profiles --mode=unconfined\n"
" --process-mixed --count --ps --mode=mixed\n"
msgstr ""
#: ../aa_status.c:734 ../aa_status.c:750
#, c-format
msgid ""
"Usage of filters\n"
"Filters are used to reduce the output of information to only\n"
"those entries that will match the filter. Filters use posix\n"
"regular expression syntax. The possible values for exes that\n"
"support filters are below\n"
"\n"
" --filter.mode: regular expression to match the profile "
"mode modes: enforce, complain, kill, unconfined, mixed\n"
" --filter.profiles: regular expression to match displayed profile names\n"
" --filter.pid: regular expression to match displayed processes pids\n"
" --filter.exe: regular expression to match executable\n"
msgstr ""
#: ../aa_status.c:762 ../aa_status.c:778
#, c-format
msgid ""
"Usage: %s [OPTIONS]\n"
"Displays various information about the currently loaded AppArmor policy.\n"
"Default if no options given\n"
" --show=all\n"
"\n"
"OPTIONS (one only):\n"
" --enabled returns error code if AppArmor not enabled\n"
" --show=X What information to show. {profiles,processes,all}\n"
" --count print the number of entries. Implies --quiet\n"
" --filter.mode=filter see filters\n"
" --filter.profiles=filter see filters\n"
" --filter.pid=filter see filters\n"
" --filter.exe=filter see filters\n"
" --json displays multiple data points in machine-readable JSON "
"format\n"
" --pretty-json same data as --json, formatted for human consumption as "
"well\n"
" --verbose (default) displays data points about loaded policy set\n"
" --quiet don't output error messages\n"
" -h[(legacy|filters)] this message, or info on the specified option\n"
" --help[=(legacy|filters)] this message, or info on the specified option\n"
msgstr ""
#: ../aa_status.c:856 ../aa_status.c:872
#, c-format
msgid "Error: Invalid --help option '%s'.\n"
msgstr ""
#: ../aa_status.c:924 ../aa_status.c:940
#, c-format
msgid "Error: Invalid --show option '%s'.\n"
msgstr ""
#: ../aa_status.c:946 ../aa_status.c:962
msgid "Error: Invalid command.\n"
msgstr ""
#: ../aa_status.c:971 ../aa_status.c:987
msgid "Error: Unknown options.\n"
msgstr ""
#: ../aa_status.c:983 ../aa_status.c:999
#, c-format
msgid "Error: failed to compile mode filter '%s'\n"
msgstr ""
#: ../aa_status.c:988 ../aa_status.c:1004
#, c-format
msgid "Error: failed to compile profiles filter '%s'\n"
msgstr ""
#: ../aa_status.c:994 ../aa_status.c:1010
#, c-format
msgid "Error: failed to compile ps filter '%s'\n"
msgstr ""
#: ../aa_status.c:1000 ../aa_status.c:1016
#, c-format
msgid "Error: failed to compile exe filter '%s'\n"
msgstr ""
#: ../aa_status.c:1015 ../aa_status.c:1031
#, c-format
msgid "Failed to open memstream: %m\n"
msgstr ""
#: ../aa_status.c:1026
#, c-format
msgid "Failed to get profiles: %d....\n"
msgstr ""
#: ../aa_status.c:1050
#, c-format
msgid "Failed to get processes: %d....\n"
msgstr ""
#: ../aa_status.c:1076 ../aa_status.c:1099
msgid "Failed to parse json output"
msgstr ""
#: ../aa_status.c:1083 ../aa_status.c:1106
msgid "Failed to print pretty json"
msgstr ""
#: ../aa_status.c:1044
#, c-format
msgid "Failed to retrieve profiles from kernel: %d....\n"
msgstr ""
#: ../aa_status.c:1073
#, c-format
msgid "Failed to get confinement information from processes: %d....\n"
msgstr ""
#: ../aa_status.c:1042
msgid "No policy loaded into the kernel\n"
msgstr ""

View File

@ -1,67 +0,0 @@
# Belarusian translation for apparmor
# Copyright (c) 2020 Rosetta Contributors and Canonical Ltd 2020
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2020-05-05 21:55+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Belarusian <be@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2020-05-06 05:41+0000\n"
"X-Generator: Launchpad (build fbdff7602bd10fb883bf7e2ddcc7fd5a16f60398)\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr ""
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr ""
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr ""
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr ""
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr ""
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr ""
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr ""
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr ""

View File

@ -1,71 +0,0 @@
# Catalan translation for apparmor
# Copyright (c) 2024 Rosetta Contributors and Canonical Ltd 2024
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2024.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2024-09-14 10:17+0000\n"
"Last-Translator: Walter Garcia-Fontes <walter.garcia@upf.edu>\n"
"Language-Team: Catalan <ca@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2024-09-15 07:16+0000\n"
"X-Generator: Launchpad (build 1b1ed1ad2dbfc71ee62b5c5491c975135a771bf0)\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
"%s: [opcions]\n"
" opcions:\n"
" -q | --quiet No imprimeixis cap missatge\n"
" -h | --help Imprimeix l'ajuda\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "opcions desconegudes o incompatibles\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "opció desconeguda «%s»\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "Sí\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "No - no esta disponible a aquest sistema\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "No - desactivat a l'inici.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "Potser - la interfície de política no està disponible.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr "Potser - permisos insuficient per determinar la disponibilitat.\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Error - '%s'\n"

View File

@ -1,67 +0,0 @@
# Czech translation for apparmor
# Copyright (c) 2022 Rosetta Contributors and Canonical Ltd 2022
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2022.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2022-01-09 11:59+0000\n"
"Last-Translator: Marek Hladík <mhladik@seznam.cz>\n"
"Language-Team: Czech <cs@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2022-01-10 06:32+0000\n"
"X-Generator: Launchpad (build 1682fd44eec4f62371f0bed122a83482daf08e23)\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "neznámé nebo nekompatibilní volby\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "neznámá volba '%s'\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "Ano\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "Ne - není v tomto systému k dispozici.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "Ne - zakázáno při startu.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "Možná - rozhraní zásad není k dispozici.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr "Možná - nedostatečná oprávnění k určení dostupnosti.\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Chyba - '%s'\n"

View File

@ -1,67 +0,0 @@
# English (Australia) translation for apparmor
# Copyright (c) 2020 Rosetta Contributors and Canonical Ltd 2020
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2020-11-28 04:45+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: English (Australia) <en_AU@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2020-11-29 06:26+0000\n"
"X-Generator: Launchpad (build 12d09381f8e8eee3115395875b132e165fa96574)\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr ""
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr ""
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr ""
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr ""
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr ""
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr ""
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr ""
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr ""

View File

@ -1,67 +0,0 @@
# English (Canada) translation for apparmor
# Copyright (c) 2021 Rosetta Contributors and Canonical Ltd 2021
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2021.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2021-10-01 04:55+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: English (Canada) <en_CA@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2021-10-02 06:17+0000\n"
"X-Generator: Launchpad (build 1ce78163f6a09ed42b4201fe7d3f0e3a2eba7d02)\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr ""
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr ""
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr ""
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr ""
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr ""
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr ""
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr ""
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr ""

View File

@ -1,71 +0,0 @@
# Estonian translation for apparmor
# Copyright (c) 2023 Rosetta Contributors and Canonical Ltd 2023
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2023.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2023-07-04 08:52+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Estonian <et@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2023-07-05 04:31+0000\n"
"X-Generator: Launchpad (build beda0e9dd2b131780db60fe479d4b43618b27243)\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
"%s: [valikud]\n"
" valikud:\n"
" -q | --quiet Ärge printige sõnumeid välja\n"
" -h | --help Prindi abiinfo\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "tundmatud või ühildumatud valikud\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "tundmatu valik '%s'\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "Jah\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "Ei pole selles süsteemis saadaval.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "Ei käivitamisel keelatud.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "Võib-olla poliisiliides pole saadaval.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr "Võib-olla - kättesaadavuse määramiseks pole piisavalt õigusi.\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Viga '%s'\n"

View File

@ -1,67 +0,0 @@
# Galician translation for apparmor
# Copyright (c) 2020 Rosetta Contributors and Canonical Ltd 2020
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2020-04-21 14:59+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Galician <gl@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2020-04-22 06:10+0000\n"
"X-Generator: Launchpad (build aad6b57d58e2f621954298e262c1cc904860f5d2)\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr ""
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr ""
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr ""
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr ""
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr ""
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr ""
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr ""
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr ""

View File

@ -1,71 +0,0 @@
# Hebrew translation for apparmor
# Copyright (c) 2023 Rosetta Contributors and Canonical Ltd 2023
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2023.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2023-10-05 05:12+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Hebrew <he@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2023-10-06 08:32+0000\n"
"X-Generator: Launchpad (build bd6cfd0cfc024dbe1dcd7d5d91165fb4f6a6c596)\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
"%s: [אפשרויות]\n"
" אפשרויות:\n"
" -q | --quiet לא להציג הודעות\n"
" -h | --help הצגת עזרה\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "אפשרויות לא ידועות או לא נתמכות\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "האפשרות %s לא מוכרת\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "כן\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "לא - לא זמין במערכת הזאת.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "לא - מושבת בעלייה.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "אולי - מנשק המדיניות לא זמין.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr "אולי - אין מספיק הרשאות לקבוע זמינות.\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "שגיאה - %s\n"

View File

@ -1,67 +0,0 @@
# Hindi translation for apparmor
# Copyright (c) 2023 Rosetta Contributors and Canonical Ltd 2023
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2023.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2023-01-09 07:39+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Hindi <hi@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2023-01-10 06:22+0000\n"
"X-Generator: Launchpad (build 87bfee1fd14ea3245297d63eeec1e4c8a1d203a8)\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr ""
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr ""
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr ""
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr ""
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr ""
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr ""
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr ""
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr ""

View File

@ -1,71 +0,0 @@
# Croatian translation for apparmor
# Copyright (c) 2020 Rosetta Contributors and Canonical Ltd 2020
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2021-10-03 10:17+0000\n"
"Last-Translator: gogo <trebelnik2@gmail.com>\n"
"Language-Team: Croatian <hr@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2021-10-04 06:23+0000\n"
"X-Generator: Launchpad (build 1ce78163f6a09ed42b4201fe7d3f0e3a2eba7d02)\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
"%s: [mogućnosti]\n"
" options:\n"
" -q | --quiet Ne prikazuj poruke\n"
" -h | --help Prikaži pomoć\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "nepoznata ili nepotpuna mogućnost\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "nepoznata mogućnost '%s'\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "Da\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "Ne - nedostupno na ovom sustavu.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "Ne - onemogućeno pri pokretanju.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "Možda - pravilo sučelja nedostupno.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr "Možda - nedovoljna dozvola za određivanje dostupnosti.\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Greška - '%s'\n"

View File

@ -1,72 +0,0 @@
# Italian translation for apparmor
# Copyright (c) 2022 Rosetta Contributors and Canonical Ltd 2022
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2022.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2022-06-30 17:54+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Italian <it@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2022-07-01 04:30+0000\n"
"X-Generator: Launchpad (build f48158886a49da429840bcd298f0c7ed60f9ad7b)\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
"%s: [opzioni]\n"
" opzioni:\n"
" -q | --quiet Non stampa nessun messaggio\n"
" -h | --help Stampa la guida\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "opzioni sconosciute o incompatibili\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "opzione sconosciuta '%s'\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "Si\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "No - non disponibile su questo sistema.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "No - disabilitato all'avvio.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "Forse - interfaccia dei criteri non disponibile.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr ""
"Forse - autorizzazioni insufficienti per determinare la disponibilità.\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Errore - '%s'\n"

View File

@ -1,72 +0,0 @@
# Georgian translation for apparmor
# Copyright (c) 2023 Rosetta Contributors and Canonical Ltd 2023
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2023.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2023-06-26 15:06+0000\n"
"Last-Translator: NorwayFun <temuri.doghonadze@gmail.com>\n"
"Language-Team: Georgian <ka@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2023-06-27 04:31+0000\n"
"X-Generator: Launchpad (build aedf8597c50c1abc5fb7f9e871e686dfcb381fde)\n"
"Language: aa\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
"%s: [პარამეტრები]\n"
" პარამეტრები:\n"
" -q | --quiet შეტყობინებები გამოტანილი არ იქნება\n"
" -h | --help დახმარების გამოტანა\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "უცნობი ან შეუთავსებელი პარამეტრები\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "უცნობი პარამეტრი \"%s\"-სთვის\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "დიახ\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "არა - მიუწვდომელია ამ სისტემაზე\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "არა - გამორთულია ჩატვირთვისას\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "შეიძლება - პოლიტიკის ინტერფეისი ხელმისაწვდომი არაა.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr "შეიძლება - არასაკმარისი წვდომები ხელმისაწვდომობის დასადგენად.\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "შეცდომა - \"%s\"\n"

View File

@ -1,67 +0,0 @@
# Kabyle translation for apparmor
# Copyright (c) 2020 Rosetta Contributors and Canonical Ltd 2020
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2020-04-29 14:31+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Kabyle <kab@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2020-04-30 05:44+0000\n"
"X-Generator: Launchpad (build fbdff7602bd10fb883bf7e2ddcc7fd5a16f60398)\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr ""
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr ""
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr ""
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr ""
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr ""
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr ""
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr ""
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr ""

View File

@ -1,73 +0,0 @@
# Burmese translation for apparmor
# Copyright (c) 2022 Rosetta Contributors and Canonical Ltd 2022
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2022.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2022-06-26 11:50+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Burmese <my@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2022-06-27 04:30+0000\n"
"X-Generator: Launchpad (build 51a2e4fa2e9b8e45f00904ad7f53546f45ac48a5)\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
"%s- [options]\n"
" ရွေးချယ်စရာများ-\n"
" -q | --quiet မည်သည့်စာတိုကိုမှ ပရင့်မထုတ်ပါနှင့်။\n"
" -h | --help ပရင့်အကူအညီ\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "အမည်မသိ သို့မဟုတ် သဟဇာတမဖြစ်သော ရွေးချယ်စရာများ\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "အမည်မသိရွေးချယ်မှု '%s'\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "ဟုတ်\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "မဟုတ်ပါ - ဤစနစ်တွင် မရနိုင်ပါ။\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "မဟုတ်ပါ - boot တွင် ပိတ်ထားပါသည်။\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "ဖြစ်နိုင်ပါသည် - မူဝါဒ interface ကို မရနိုင်ပါ။\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr ""
"ဖြစ်နိုင်ပါသည် - ရရှိနိုင်မှုကို ဆုံးဖြတ်ရန်အတွက် ခွင့်ပြုချက်များမှာ "
"လုံလောက်မှုမရှိပါ။\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "အမှား- '%s'\n"

View File

@ -1,67 +0,0 @@
# Occitan (post 1500) translation for apparmor
# Copyright (c) 2021 Rosetta Contributors and Canonical Ltd 2021
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2021.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2021-01-14 18:26+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Occitan (post 1500) <oc@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2021-01-15 07:59+0000\n"
"X-Generator: Launchpad (build 511b4a3b6512aa3d421c5f7d74f3527e78bff26e)\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr ""
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr ""
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr ""
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr ""
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr ""
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr ""
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr ""
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr ""

View File

@ -1,71 +0,0 @@
# Polish translation for apparmor
# Copyright (c) 2021 Rosetta Contributors and Canonical Ltd 2021
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2021.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2021-07-22 20:10+0000\n"
"Last-Translator: Marek Adamski <Unknown>\n"
"Language-Team: Polish <pl@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2021-07-23 06:03+0000\n"
"X-Generator: Launchpad (build 7edebbcd0516593cf020aaa3c59299732a7c73cc)\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
"%s: [opcje]\n"
" opcje:\n"
" -q | --quiet Nie wyświetlaj żadnych komunikatów\n"
" -h | --help Wyświetl pomoc\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "nieznane lub niekompatybilne opcje\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "nieznana opcja '%s'\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "Tak\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "Nie - nie jest dostępne w tym systemie.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "Nie - wyłączone podczas rozruchu.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "Może - interfejs zasad nie jest dostępny.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr "Może - brak wystarczających uprawnień do określenia dostępności.\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Błąd - '%s'\n"

View File

@ -1,71 +0,0 @@
# Brazilian Portuguese translation for apparmor
# Copyright (c) 2020 Rosetta Contributors and Canonical Ltd 2020
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2020-04-27 20:32+0000\n"
"Last-Translator: Rodrigo Farias <Unknown>\n"
"Language-Team: Brazilian Portuguese <pt_BR@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2020-04-28 05:52+0000\n"
"X-Generator: Launchpad (build d1105341713c5be348effe2a5142c4a210ce4cde)\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
"%s: [options]\n"
" opções:\n"
" -q | --quiet Não imprimir nenhum mensagem\n"
" -h | --help Assistente de impressão\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "opções incompatíveis ou desconhecidas\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "opção desconhecida '%s'\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "Sim\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "Não - não disponível neste sistema.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "Não - desabilitado na inicialização.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "Talvez - interface de política não disponível.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr "Talvez - permissões insuficientes para determinar disponibilidade.\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Erro - '%s'\n"

View File

@ -1,26 +1,21 @@
# Romanian translation for apparmor, "apparmor-binutils" component.
# Mesajele în limba română pentru pachetul „apparmor”, componenta „apparmor-binutils”.
# Copyright © 2020 Rosetta Contributors and Canonical Ltd.
# Copyright © 2024 Canonical Ltd.
# Romanian translation for apparmor
# Copyright (c) 2020 Rosetta Contributors and Canonical Ltd 2020
# This file is distributed under the same license as the apparmor package.
#
# Daniel Slavu <Unknown>, feb-2020.
# Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>, sep-2024.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor-binutils\n"
"Report-Msgid-Bugs-To: <apparmor@lists.ubuntu.com>\n"
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2024-09-23 22:45+0000\n"
"Last-Translator: Remus-Gabriel Chelu <Unknown>\n"
"Language-Team: Romanian <debian-l10n-romanian@lists.debian.org>\n"
"PO-Revision-Date: 2020-02-20 21:47+0000\n"
"Last-Translator: Daniel Slavu <Unknown>\n"
"Language-Team: Romanian <ro@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2024-09-25 04:33+0000\n"
"X-Generator: Launchpad (build 1b1ed1ad2dbfc71ee62b5c5491c975135a771bf0)\n"
"Language: ro\n"
"X-Launchpad-Export-Date: 2020-02-21 05:39+0000\n"
"X-Generator: Launchpad (build 19413b719a8df7423ab1390528edadce9e0e4aca)\n"
#: ../aa_enabled.c:26
#, c-format
@ -32,8 +27,8 @@ msgid ""
msgstr ""
"%s: [opțiuni]\n"
" opțiuni:\n"
" -q | --quiet nu afișează niciun mesaj\n"
" -h | --help imprimă ajutorul\n"
" -q | --calm Nu imprima niciun mesaj\n"
" -h | - ajutor Imprimare ajutor\n"
#: ../aa_enabled.c:45
#, c-format
@ -43,7 +38,7 @@ msgstr "opțiuni necunoscute sau incompatibile\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "opțiune necunoscută „%s”\n"
msgstr "opțiune necunoscută '%s'\n"
#: ../aa_enabled.c:64
#, c-format
@ -63,8 +58,7 @@ msgstr "Nu - dezactivat la pornire.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr ""
"Poate - interfața politică (de directive politice) nu este disponibilă.\n"
msgstr "Poate - interfața politică nu este disponibilă.\n"
#: ../aa_enabled.c:81
#, c-format
@ -75,4 +69,4 @@ msgstr ""
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Eroare - „%s”\n"
msgstr "Eroare - '%s'\n"

View File

@ -1,67 +0,0 @@
# Serbian translation for apparmor
# Copyright (c) 2020 Rosetta Contributors and Canonical Ltd 2020
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2020-11-23 18:06+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Serbian <sr@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2020-11-24 05:55+0000\n"
"X-Generator: Launchpad (build c35ff22711d15549e2303ae18ae521fd91f6bf00)\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr ""
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr ""
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr ""
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr ""
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr ""
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr ""
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr ""
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr ""

View File

@ -1,71 +0,0 @@
# Ukrainian translation for apparmor
# Copyright (c) 2020 Rosetta Contributors and Canonical Ltd 2020
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2020-05-19 21:48+0000\n"
"Last-Translator: Nazarii Ritter <nazariy.ritter@gmail.com>\n"
"Language-Team: Ukrainian <uk@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2020-05-20 05:42+0000\n"
"X-Generator: Launchpad (build 0385b538081bc4718df6fb844a3afc89729c94ce)\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
"%s: [опції]\n"
" опції:\n"
" -q | --quiet Не виводити жодних повідомлень\n"
" -h | --help Вивести довідку\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "невідомі або несумісні опції\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "невідомий параметр «%s»\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "Так\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "Ні недоступно на цій системі.\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "Ні вимкнено під час завантаження.\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "Можливо інтерфейс політики недоступний.\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr "Можливо недостатньо дозволів для визначення наявності.\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "Помилка - '%s'\n"

View File

@ -1,71 +0,0 @@
# Chinese (Simplified) translation for apparmor
# Copyright (c) 2020 Rosetta Contributors and Canonical Ltd 2020
# This file is distributed under the same license as the apparmor package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: apparmor\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
"PO-Revision-Date: 2020-05-14 09:16+0000\n"
"Last-Translator: 玉堂白鹤 <yjwork@qq.com>\n"
"Language-Team: Chinese (Simplified) <zh_CN@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2020-05-15 05:51+0000\n"
"X-Generator: Launchpad (build 0385b538081bc4718df6fb844a3afc89729c94ce)\n"
#: ../aa_enabled.c:26
#, c-format
msgid ""
"%s: [options]\n"
" options:\n"
" -q | --quiet Don't print out any messages\n"
" -h | --help Print help\n"
msgstr ""
"%s: [选项]\n"
" 选项:\n"
" -q | --quiet 不要打印任何消息\n"
" -h | --help 打印帮助\n"
#: ../aa_enabled.c:45
#, c-format
msgid "unknown or incompatible options\n"
msgstr "未知或不兼容的选项\n"
#: ../aa_enabled.c:55
#, c-format
msgid "unknown option '%s'\n"
msgstr "未知选项 '%s'\n"
#: ../aa_enabled.c:64
#, c-format
msgid "Yes\n"
msgstr "是\n"
#: ../aa_enabled.c:71
#, c-format
msgid "No - not available on this system.\n"
msgstr "否 - 在此系统上不可用。\n"
#: ../aa_enabled.c:74
#, c-format
msgid "No - disabled at boot.\n"
msgstr "否 - 引导时被禁用。\n"
#: ../aa_enabled.c:77
#, c-format
msgid "Maybe - policy interface not available.\n"
msgstr "也许 - 策略界面不可用\n"
#: ../aa_enabled.c:81
#, c-format
msgid "Maybe - insufficient permissions to determine availability.\n"
msgstr "也许 - 没有足够的权限确定可用性。\n"
#: ../aa_enabled.c:84
#, c-format
msgid "Error - '%s'\n"
msgstr "错误 - '%s'\n"

View File

@ -35,14 +35,17 @@ VERSION=$(shell cat $(COMMONDIR)/Version)
pathsearch = $(firstword $(wildcard $(addsuffix /$(1),$(subst :, ,$(PATH)))))
map = $(foreach a,$(2),$(call $(1),$(a)))
AWK?=$(or $(shell which awk),$(error awk utility required for build but not available))
AWK:=$(shell which awk)
ifndef AWK
$(error awk utility required for build but not available)
endif
define nl
endef
REPO_VERSION_CMD=[ -x /usr/bin/git ] && /usr/bin/git describe --tags --long --abbrev=16 --match 'v*' 2> /dev/null || $(AWK) '{ print $2 }' common/.stamp_rev
REPO_VERSION_CMD=[ -x /usr/bin/git ] && /usr/bin/git describe --tags --long --abbrev=16 --match 'v*' 2> /dev/null || awk '{ print $2 }' common/.stamp_rev
ifndef PYTHON_VERSIONS
PYTHON_VERSIONS = $(call map, pathsearch, python3)

View File

@ -1 +1 @@
5.0.0~alpha1
4.0.0~beta2

View File

@ -92,16 +92,13 @@ if test "$ac_cv_prog_cc_c99" = "no"; then
AC_MSG_ERROR([C99 mode is required to build libapparmor])
fi
AC_PROG_CXX
m4_ifndef([AX_CHECK_COMPILE_FLAG], [AC_MSG_ERROR(['autoconf-archive' missing])])
EXTRA_CFLAGS="-Wall $EXTRA_WARNINGS -fPIC"
EXTRA_CFLAGS="-Wall $(EXTRA_WARNINGS) -fPIC"
AX_CHECK_COMPILE_FLAG([-flto-partition=none], , , [-Werror])
AS_VAR_IF([ax_cv_check_cflags__Werror__flto_partition_none], [yes],
[EXTRA_CFLAGS="$EXTRA_CFLAGS -flto-partition=none"]
,)
AC_SUBST([AM_CFLAGS], ["$EXTRA_CFLAGS"])
AC_SUBST([AM_CXXFLAGS], ["$EXTRA_CFLAGS"])
AC_OUTPUT(
Makefile

View File

@ -22,15 +22,15 @@
=head1 NAME
aa_change_hat - change to or from a "hat" within a AppArmor profile
aa_change_hat - change to or from a "hat" within a AppArmor profile
=head1 SYNOPSIS
B<#include E<lt>sys/apparmor.hE<gt>>
B<int aa_change_hat (const char *subprofile, unsigned long magic_token);>
B<int aa_change_hat (char *subprofile, unsigned long magic_token);>
B<int aa_change_hatv (const char *subprofiles[], unsigned long magic_token);>
B<int aa_change_hatv (char *subprofiles[], unsigned long magic_token);>
B<int aa_change_hat_vargs (unsigned long magic_token, ...);>

View File

@ -22,7 +22,7 @@
=head1 NAME
aa_change_profile, aa_change_onexec - change a task's profile
aa_change_profile, aa_change_onexec - change a tasks profile
=head1 SYNOPSIS
@ -58,8 +58,8 @@ The aa_change_onexec() function is like the aa_change_profile() function
except it specifies that the profile transition should take place on the
next exec instead of immediately. The delayed profile change takes
precedence over any exec transition rules within the confining profile.
Delaying the profile boundary has a couple of advantages: it removes the
need for stub transition profiles, and the exec boundary is a natural security
Delaying the profile boundary has a couple of advantages, it removes the
need for stub transition profiles and the exec boundary is a natural security
layer where potentially sensitive memory is unmapped.
=head1 RETURN VALUE

View File

@ -54,7 +54,7 @@ B<typedef struct aa_features aa_features;>
B<int aa_features_new(aa_features **features, int dirfd, const char *path);>
B<int aa_features_new_from_file(aa_features **features, int file);>
B<int aa_features_new_from_file(aa_features **features, int fd);>
B<int aa_features_new_from_string(aa_features **features, const char *string, size_t size);>

View File

@ -58,9 +58,6 @@ appropriately.
=head1 ERRORS
# podchecker warns about duplicate link targets for EACCES, EBUSY, ENOENT,
# and ENOMEM, but this is a warning that is safe to ignore.
B<aa_is_enabled>
=over 4

View File

@ -41,7 +41,7 @@ result is an intersection of all profiles which are stacked. Stacking profiles
together is desirable when wanting to ensure that confinement will never become
more permissive. When changing between two profiles, as performed with
aa_change_profile(2), there is always the possibility that the new profile is
more permissive than the old profile, but that possibility is eliminated when
more permissive than the old profile but that possibility is eliminated when
using aa_stack_profile().
To stack a profile with the current confinement context, a task can use the
@ -68,7 +68,7 @@ The aa_stack_onexec() function is like the aa_stack_profile() function
except it specifies that the stacking should take place on the next exec
instead of immediately. The delayed profile change takes precedence over any
exec transition rules within the confining profile. Delaying the stacking
boundary has a couple of advantages: it removes the need for stub transition
boundary has a couple of advantages, it removes the need for stub transition
profiles and the exec boundary is a natural security layer where potentially
sensitive memory is unmapped.

View File

@ -19,10 +19,6 @@
#ifndef __LIBAALOGPARSE_H_
#define __LIBAALOGPARSE_H_
#ifdef __cplusplus
extern "C" {
#endif
#define AA_RECORD_EXEC_MMAP 1
#define AA_RECORD_READ 2
#define AA_RECORD_WRITE 4
@ -30,10 +26,10 @@ extern "C" {
#define AA_RECORD_LINK 16
/**
* Enum representing which syntax version the log entry used.
* Support for V1 parsing was completely removed in 2011 and that enum entry
* is only still there for API compatibility reasons.
* This is just for convenience now that we have two
* wildly different grammars.
*/
typedef enum
{
AA_RECORD_SYNTAX_V1,
@ -52,23 +48,70 @@ typedef enum
AA_RECORD_STATUS /* Configuration change */
} aa_record_event_type;
/*
* Use this preprocessor dance to maintain backcompat for field names
* This will break C code that used the C++ reserved keywords "namespace"
* and "class" as identifiers, but this is bad practice anyways, and we
* hope that we are the only ones in a given C file that messed up this way
/**
* With the sole exception of active_hat, this is a 1:1
* mapping from the keys that the new syntax uses.
*
* TODO: document this in a man page for aalogparse?
*/
#if defined(SWIG) && defined(__cplusplus)
#error "SWIG and __cplusplus are defined together"
#elif !defined(SWIG) && !defined(__cplusplus)
/* Use SWIG's %rename feature to preserve backcompat */
#define class rule_class
#define namespace aa_namespace
#endif
* Some examples of the old syntax and how they're mapped with the aa_log_record struct:
*
* "PERMITTING r access to /path (program_name(12345) profile /profile active hat)"
* - operation: access
* - requested_mask: r
* - pid: 12345
* - profile: /profile
* - name: /path
* - info: program_name
* - active_hat: hat
*
* "REJECTING mkdir on /path/to/something (bash(23415) profile /bin/freak-aa-out active /bin/freak-aa-out"
* - operation: mkdir
* - name: /path/to/something
* - info: bash
* - pid: 23415
* - profile: /bin/freak-aa-out
* - active_hat: /bin/freak-aa-out
*
* "REJECTING xattr set on /path/to/something (bash(23415) profile /bin/freak-aa-out active /bin/freak-aa-out)"
* - operation: xattr
* - attribute: set
* - name: /path/to/something
* - info: bash
* - pid: 23415
* - profile: /bin/freak-aa-out
* - active_hat: /bin/freak-aa-out
*
* "PERMITTING attribute (something) change to /else (bash(23415) profile /bin/freak-aa-out active /bin/freak-aa-out)"
* - operation: setattr
* - attribute: something
* - name: /else
* - info: bash
* - pid: 23415
* - profile: /bin/freak-aa-out
* - active_hat: /bin/freak-aa-out
*
* "PERMITTING access to capability 'cap' (bash(23415) profile /bin/freak-aa-out active /bin/freak-aa-out)"
* - operation: capability
* - name: cap
* - info: bash
* - pid: 23415
* - profile: /bin/freak-aa-out
* - active_hat: /bin/freak-aa-out
*
* "LOGPROF-HINT unknown_hat TESTHAT pid=27764 profile=/change_hat_test/test_hat active=/change_hat_test/test_hat"
* - operation: change_hat
* - name: TESTHAT
* - info: unknown_hat
* - pid: 27764
* - profile: /change_hat_test/test_hat
* - active_hat: /change_hat_test/test_hat
*
* "LOGPROF-HINT fork pid=27764 child=38229"
* - operation: clone
* - task: 38229
* - pid: 27764
**/
typedef struct aa_log_record
typedef struct
{
aa_record_syntax_version version;
aa_record_event_type event; /* Event type */
@ -91,7 +134,7 @@ typedef struct aa_log_record
char *comm; /* Command that triggered msg */
char *name;
char *name2;
char *aa_namespace;
char *namespace;
char *attribute;
unsigned long parent;
char *info;
@ -105,7 +148,6 @@ typedef struct aa_log_record
unsigned long net_local_port;
char *net_foreign_addr;
unsigned long net_foreign_port;
char *dbus_bus;
char *dbus_path;
char *dbus_interface;
@ -118,11 +160,7 @@ typedef struct aa_log_record
char *flags;
char *src_name;
char *rule_class;
char *net_addr;
char *peer_addr;
char *execpath;
char *class;
} aa_log_record;
/**
@ -133,7 +171,7 @@ typedef struct aa_log_record
* @return Parsed data.
*/
aa_log_record *
parse_record(const char *str);
parse_record(char *str);
/**
* Frees all struct data.
@ -142,9 +180,5 @@ parse_record(const char *str);
void
free_record(aa_log_record *record);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -105,8 +105,8 @@ extern int aa_getpeercon(int fd, char **label, char **mode);
#define AA_QUERY_CMD_LABEL "label"
#define AA_QUERY_CMD_LABEL_SIZE sizeof(AA_QUERY_CMD_LABEL)
extern int aa_query_label(uint32_t mask, char *query, size_t size, int *allowed,
int *audited);
extern int aa_query_label(uint32_t mask, char *query, size_t size, int *allow,
int *audit);
extern int aa_query_file_path_len(uint32_t mask, const char *label,
size_t label_len, const char *path,
size_t path_len, int *allowed, int *audited);
@ -152,16 +152,16 @@ extern int aa_features_new_from_kernel(aa_features **features);
extern aa_features *aa_features_ref(aa_features *features);
extern void aa_features_unref(aa_features *features);
extern int aa_features_write_to_fd(const aa_features *features, int fd);
extern int aa_features_write_to_file(const aa_features *features,
extern int aa_features_write_to_fd(aa_features *features, int fd);
extern int aa_features_write_to_file(aa_features *features,
int dirfd, const char *path);
extern bool aa_features_is_equal(const aa_features *features1,
const aa_features *features2);
extern bool aa_features_is_equal(aa_features *features1,
aa_features *features2);
extern int aa_features_check(int dirfd, const char *path,
aa_features *features);
extern bool aa_features_supports(const aa_features *features, const char *str);
extern char *aa_features_id(const aa_features *features);
extern char *aa_features_value(const aa_features *features, const char *str, size_t *len);
extern bool aa_features_supports(aa_features *features, const char *str);
extern char *aa_features_id(aa_features *features);
extern char *aa_features_value(aa_features *features, const char *str, size_t *len);
typedef struct aa_kernel_interface aa_kernel_interface;
extern int aa_kernel_interface_new(aa_kernel_interface **kernel_interface,

View File

@ -32,10 +32,10 @@ INCLUDES = $(all_includes)
#
# After changing the AA_LIB_* variables, also update EXPECTED_SO_NAME.
AA_LIB_CURRENT = 25
AA_LIB_REVISION = 2
AA_LIB_AGE = 24
EXPECTED_SO_NAME = libapparmor.so.1.24.2
AA_LIB_CURRENT = 18
AA_LIB_REVISION = 1
AA_LIB_AGE = 17
EXPECTED_SO_NAME = libapparmor.so.1.17.1
SUFFIXES = .pc.in .pc
@ -44,7 +44,7 @@ include $(COMMONDIR)/Make.rules
BUILT_SOURCES = grammar.h scanner.h af_protos.h
AM_LFLAGS = -v
AM_YFLAGS = -Wno-yacc -d -p aalogparse_
AM_YFLAGS = -d -p aalogparse_
AM_CPPFLAGS = -D_GNU_SOURCE -I$(top_srcdir)/include/
scanner.h: scanner.l
$(LEX) -v $<
@ -52,7 +52,7 @@ scanner.h: scanner.l
scanner.c: scanner.l
af_protos.h:
echo '#include <netinet/in.h>' | $(CC) $(CPPFLAGS) -E -dD - | LC_ALL=C sed -n -e "/IPPROTO_MAX/d" -e "s/^\#define[ \\t]\\+IPPROTO_\\([A-Z0-9_]\\+\\)\\(.*\\)$$/AA_GEN_PROTO_ENT(\\UIPPROTO_\\1, \"\\L\\1\")/p" > $@
echo '#include <netinet/in.h>' | $(CC) $(CPPFLAGS) -E -dM - | LC_ALL=C sed -n -e "/IPPROTO_MAX/d" -e "s/^\#define[ \\t]\\+IPPROTO_\\([A-Z0-9_]\\+\\)\\(.*\\)$$/AA_GEN_PROTO_ENT(\\UIPPROTO_\\1, \"\\L\\1\")/p" > $@
lib_LTLIBRARIES = libapparmor.la
noinst_HEADERS = grammar.h parser.h scanner.h af_protos.h private.h PMurHash.h
@ -73,16 +73,6 @@ CLEANFILES = libapparmor.pc
tst_aalogmisc_SOURCES = tst_aalogmisc.c
tst_aalogmisc_LDADD = .libs/libapparmor.a
tst_aalogparse_cpp_SOURCES = tst_aalogparse_cpp.cpp
tst_aalogparse_cpp_LDADD = .libs/libapparmor.a
tst_aalogparse_oldname_SOURCES = tst_aalogparse_oldname.c
tst_aalogparse_oldname_LDADD = .libs/libapparmor.a
tst_aalogparse_reentrancy_SOURCES = tst_aalogparse_reentrancy.c
tst_aalogparse_reentrancy_LDADD = .libs/libapparmor.a
tst_aalogparse_reentrancy_LDFLAGS = -pthread
tst_features_SOURCES = tst_features.c
tst_features_LDADD = .libs/libapparmor.a
@ -90,7 +80,7 @@ tst_kernel_SOURCES = tst_kernel.c
tst_kernel_LDADD = .libs/libapparmor.a
tst_kernel_LDFLAGS = -pthread
check_PROGRAMS = tst_aalogmisc tst_aalogparse_cpp tst_aalogparse_reentrancy tst_aalogparse_oldname tst_features tst_kernel
check_PROGRAMS = tst_aalogmisc tst_features tst_kernel
TESTS = $(check_PROGRAMS)
.PHONY: check-local

View File

@ -399,10 +399,6 @@ static bool walk_one(const char **str, const struct component *component,
i = 0;
cur++;
/* Partial match, continue to search */
if (i == component->len && !isbrace_space_or_nul(*cur))
i = 0;
}
/* Return false if a full match was not found */
@ -608,11 +604,11 @@ void aa_features_unref(aa_features *features)
*
* Returns: 0 on success, -1 on error with errno set
*/
int aa_features_write_to_fd(const aa_features *features, int fd)
int aa_features_write_to_fd(aa_features *features, int fd)
{
size_t size;
ssize_t retval;
const char *string;
char *string;
string = features->string;
size = strlen(string);
@ -636,7 +632,7 @@ int aa_features_write_to_fd(const aa_features *features, int fd)
*
* Returns: 0 on success, -1 on error with errno set
*/
int aa_features_write_to_file(const aa_features *features,
int aa_features_write_to_file(aa_features *features,
int dirfd, const char *path)
{
autoclose int fd = -1;
@ -657,7 +653,7 @@ int aa_features_write_to_file(const aa_features *features,
*
* Returns: true if they're equal, false if they're not or either are NULL
*/
bool aa_features_is_equal(const aa_features *features1, const aa_features *features2)
bool aa_features_is_equal(aa_features *features1, aa_features *features2)
{
return features1 && features2 &&
strcmp(features1->string, features2->string) == 0;
@ -701,7 +697,7 @@ int aa_features_check(int dirfd, const char *path,
return 0;
}
static const char *features_lookup(const aa_features *features, const char *str)
static const char *features_lookup(aa_features *features, const char *str)
{
const char *features_string = features->string;
struct component components[32];
@ -743,7 +739,7 @@ static const char *features_lookup(const aa_features *features, const char *str)
*
* Returns: a bool specifying the support status of @str feature
*/
bool aa_features_supports(const aa_features *features, const char *str)
bool aa_features_supports(aa_features *features, const char *str)
{
const char *value = features_lookup(features, str);
@ -764,7 +760,7 @@ bool aa_features_supports(const aa_features *features, const char *str)
* EISDIR - @str is not a leaf node in the feature tree
*/
char *aa_features_value(const aa_features *features, const char *str, size_t *len)
char *aa_features_value(aa_features *features, const char *str, size_t *len)
{
const char *start, *cur = features_lookup(features, str);
@ -807,7 +803,7 @@ char *aa_features_value(const aa_features *features, const char *str, size_t *le
* Returns: a string identifying @features which must be freed by the
* caller or NULL, with errno set, upon error
*/
char *aa_features_id(const aa_features *features)
char *aa_features_id(aa_features *features)
{
return strdup(features->hash);
}

View File

@ -15,15 +15,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* aalogparse_error now requires visibility of the aa_log_record type
* Also include in a %code requires block to add it to the header
*/
%code requires{
#include <aalogparse.h>
}
%{
/* set the following to non-zero to get bison to emit debugging
* information about tokens given and rules matched.
* Also:
* Uncomment the %defines
* parse.error
* parse.trace
*/
#define YYDEBUG 0
#include <string.h>
#include <aalogparse.h>
#include "parser.h"
@ -39,10 +41,12 @@
#define debug_unused_ unused_
#endif
aa_log_record *ret_record;
/* Since we're a library, on any errors we don't want to print out any
* error messages. We should probably add a debug interface that does
* emit messages when asked for. */
void aalogparse_error(unused_ void *scanner, aa_log_record *ret_record, debug_unused_ char const *s)
void aalogparse_error(unused_ void *scanner, debug_unused_ char const *s)
{
#if (YYDEBUG != 0)
printf("ERROR: %s\n", s);
@ -85,10 +89,9 @@ aa_record_event_type lookup_aa_event(unsigned int type)
%define parse.trace
*/
%define api.pure full
%define api.pure
%lex-param{void *scanner}
%parse-param{void *scanner}
%parse-param{aa_log_record *ret_record}
%union
{
@ -111,7 +114,6 @@ aa_record_event_type lookup_aa_event(unsigned int type)
%token TOK_PERIOD
%token TOK_QUESTION_MARK
%token TOK_SINGLE_QUOTE
%token TOK_NONE
%token TOK_TYPE_REJECT
%token TOK_TYPE_AUDIT
@ -185,8 +187,6 @@ aa_record_event_type lookup_aa_event(unsigned int type)
%token TOK_KEY_FSTYPE
%token TOK_KEY_FLAGS
%token TOK_KEY_SRCNAME
%token TOK_KEY_UNIX_PEER_ADDR
%token TOK_KEY_EXECPATH
%token TOK_KEY_CLASS
%token TOK_SOCKLOGD_KERNEL
@ -281,9 +281,8 @@ audit_user_msg: TOK_KEY_MSG TOK_EQUALS audit_id audit_user_msg_tail
audit_id: TOK_AUDIT TOK_OPEN_PAREN TOK_AUDIT_DIGITS TOK_PERIOD TOK_AUDIT_DIGITS TOK_COLON TOK_AUDIT_DIGITS TOK_CLOSE_PAREN TOK_COLON
{
if (!asprintf(&ret_record->audit_id, "%s.%s:%s", $3, $5, $7)) {
yyerror(scanner, ret_record, YY_("Out of memory"));
}
if (!asprintf(&ret_record->audit_id, "%s.%s:%s", $3, $5, $7))
yyerror(scanner, YY_("Out of memory"));
ret_record->epoch = atol($3);
ret_record->audit_sub_id = atoi($7);
free($3);
@ -306,7 +305,7 @@ key: TOK_KEY_OPERATION TOK_EQUALS TOK_QUOTED_STRING
| TOK_KEY_NAME TOK_EQUALS safe_string
{ ret_record->name = $3;}
| TOK_KEY_NAMESPACE TOK_EQUALS safe_string
{ ret_record->aa_namespace = $3;}
{ ret_record->namespace = $3;}
| TOK_KEY_NAME2 TOK_EQUALS safe_string
{ ret_record->name2 = $3;}
| TOK_KEY_MASK TOK_EQUALS TOK_QUOTED_STRING
@ -355,13 +354,6 @@ key: TOK_KEY_OPERATION TOK_EQUALS TOK_QUOTED_STRING
{ ret_record->fsuid = $3;}
| TOK_KEY_OUID TOK_EQUALS TOK_DIGITS
{ ret_record->ouid = $3;}
| TOK_KEY_ADDR TOK_EQUALS TOK_QUESTION_MARK
| TOK_KEY_ADDR TOK_EQUALS TOK_NONE
| TOK_KEY_ADDR TOK_EQUALS safe_string
{ ret_record->net_addr = $3; }
| TOK_KEY_UNIX_PEER_ADDR TOK_EQUALS TOK_NONE
| TOK_KEY_UNIX_PEER_ADDR TOK_EQUALS safe_string
{ ret_record->peer_addr = $3; }
| TOK_KEY_FSUID_UPPER TOK_EQUALS TOK_QUOTED_STRING
{ free($3);} /* Ignore - fsuid username */
| TOK_KEY_OUID_UPPER TOK_EQUALS TOK_QUOTED_STRING
@ -371,7 +363,10 @@ key: TOK_KEY_OPERATION TOK_EQUALS TOK_QUOTED_STRING
| TOK_KEY_HOSTNAME TOK_EQUALS safe_string
{ free($3); /* Ignore - hostname from user AVC messages */ }
| TOK_KEY_HOSTNAME TOK_EQUALS TOK_QUESTION_MARK
| TOK_KEY_ADDR TOK_EQUALS TOK_QUESTION_MARK
| TOK_KEY_TERMINAL TOK_EQUALS TOK_QUESTION_MARK
| TOK_KEY_ADDR TOK_EQUALS safe_string
{ free($3); /* Ignore - IP address from user AVC messages */ }
| TOK_KEY_TERMINAL TOK_EQUALS safe_string
{ free($3); /* Ignore - TTY from user AVC messages */ }
| TOK_KEY_EXE TOK_EQUALS safe_string
@ -424,21 +419,21 @@ key: TOK_KEY_OPERATION TOK_EQUALS TOK_QUOTED_STRING
{ ret_record->dbus_member = $3; }
| TOK_KEY_SIGNAL TOK_EQUALS TOK_ID
{ ret_record->signal = $3; }
| TOK_KEY_FSTYPE TOK_EQUALS TOK_QUOTED_STRING
{ ret_record->fs_type = $3; }
| TOK_KEY_FLAGS TOK_EQUALS TOK_QUOTED_STRING
{ ret_record->flags = $3; }
| TOK_KEY_SRCNAME TOK_EQUALS TOK_QUOTED_STRING
{ ret_record->src_name = $3; }
| TOK_KEY_EXECPATH TOK_EQUALS TOK_QUOTED_STRING
{ ret_record->execpath = $3; }
| TOK_MSG_REST
{
ret_record->event = AA_RECORD_INVALID;
ret_record->info = $1;
}
| TOK_KEY_CLASS TOK_EQUALS TOK_QUOTED_STRING
{ ret_record->rule_class = $3; }
{ ret_record->class = $3; }
;
apparmor_event:
@ -475,3 +470,31 @@ protocol: TOK_QUOTED_STRING
}
;
%%
aa_log_record *
_parse_yacc(char *str)
{
/* yydebug = 1; */
YY_BUFFER_STATE lex_buf;
yyscan_t scanner;
ret_record = NULL;
ret_record = malloc(sizeof(aa_log_record));
_init_log_record(ret_record);
if (ret_record == NULL)
return NULL;
#if (YYDEBUG != 0)
yydebug = 1;
#endif
aalogparse_lex_init(&scanner);
lex_buf = aalogparse__scan_string(str, scanner);
/* Ignore return value to return an AA_RECORD_INVALID event */
(void)aalogparse_parse(scanner);
aalogparse__delete_buffer(lex_buf, scanner);
aalogparse_lex_destroy(scanner);
return ret_record;
}

View File

@ -34,42 +34,13 @@
#include <aalogparse.h>
#include "parser.h"
#include "grammar.h"
#include "scanner.h"
/* This is mostly just a wrapper around the code in grammar.y */
aa_log_record *parse_record(const char *str)
aa_log_record *parse_record(char *str)
{
YY_BUFFER_STATE lex_buf;
yyscan_t scanner;
aa_log_record *ret_record;
if (str == NULL)
return NULL;
ret_record = malloc(sizeof(aa_log_record));
_init_log_record(ret_record);
if (ret_record == NULL)
return NULL;
struct string_buf string_buf = {.buf = NULL, .buf_len = 0, .buf_alloc = 0};
#if (YYDEBUG != 0)
/* Warning: this is still a global even in reentrant parsers */
aalogparse_debug = 1;
#endif
aalogparse_lex_init_extra(&string_buf, &scanner);
lex_buf = aalogparse__scan_string(str, scanner);
/* Ignore return value to return an AA_RECORD_INVALID event */
(void)aalogparse_parse(scanner, ret_record);
aalogparse__delete_buffer(lex_buf, scanner);
aalogparse_lex_destroy(scanner);
/* free(NULL) is a no-op */
free(string_buf.buf);
return ret_record;
return _parse_yacc(str);
}
void free_record(aa_log_record *record)
@ -92,8 +63,8 @@ void free_record(aa_log_record *record)
free(record->name);
if (record->name2 != NULL)
free(record->name2);
if (record->aa_namespace != NULL)
free(record->aa_namespace);
if (record->namespace != NULL)
free(record->namespace);
if (record->attribute != NULL)
free(record->attribute);
if (record->info != NULL)
@ -132,15 +103,8 @@ void free_record(aa_log_record *record)
free(record->flags);
if (record->src_name != NULL)
free(record->src_name);
if (record->net_addr != NULL)
free(record->net_addr);
if (record->peer_addr != NULL)
free(record->peer_addr);
if (record->execpath != NULL)
free(record->execpath);
if (record->rule_class != NULL)
free(record->rule_class);
if (record->class != NULL)
free(record->class);
free(record);
}

View File

@ -127,7 +127,6 @@ APPARMOR_3.0 {
APPARMOR_3.1 {
global:
aa_features_check;
aa_split_overlay_str;
local:
*;
} APPARMOR_3.0;

View File

@ -19,14 +19,8 @@
#ifndef __AA_LOG_PARSER_H__
#define __AA_LOG_PARSER_H__
// Internal-only type
struct string_buf {
char *buf;
unsigned int buf_len;
unsigned int buf_alloc;
};
extern void _init_log_record(aa_log_record *record);
extern aa_log_record *_parse_yacc(char *str);
extern char *hex_to_string(char *str);
extern char *ipproto_to_string(unsigned int proto);

View File

@ -19,7 +19,6 @@
%option nounput
%option noyy_top_state
%option reentrant
%option extra-type="struct string_buf*"
%option prefix="aalogparse_"
%option bison-bridge
%option header-file="scanner.h"
@ -35,37 +34,40 @@
#define YY_NO_INPUT
void string_buf_reset(struct string_buf* char_buf)
unsigned int string_buf_alloc = 0;
unsigned int string_buf_len = 0;
char *string_buf = NULL;
void string_buf_reset()
{
/* rewind buffer to zero, possibly doing initial allocation too */
char_buf->buf_len = 0;
if (char_buf->buf == NULL) {
char_buf->buf_alloc = 128;
char_buf->buf = malloc(char_buf->buf_alloc);
assert(char_buf->buf != NULL);
string_buf_len = 0;
if (string_buf == NULL) {
string_buf_alloc = 128;
string_buf = malloc(string_buf_alloc);
assert(string_buf != NULL);
}
/* always start with a valid but empty string */
char_buf->buf[0] = '\0';
string_buf[0] = '\0';
}
void string_buf_append(struct string_buf* char_buf, unsigned int length, char *text)
void string_buf_append(unsigned int length, char *text)
{
unsigned int current_length = char_buf->buf_len;
unsigned int current_length = string_buf_len;
/* handle calling ..._append before ..._reset */
if (char_buf->buf == NULL) string_buf_reset(char_buf);
if (string_buf == NULL) string_buf_reset();
char_buf->buf_len += length;
string_buf_len += length;
/* expand allocation if this append would exceed the allocation */
while (char_buf->buf_len >= char_buf->buf_alloc) {
// TODO: overflow?
char_buf->buf_alloc *= 2;
char_buf->buf = realloc(char_buf->buf, char_buf->buf_alloc);
assert(char_buf->buf != NULL);
while (string_buf_len >= string_buf_alloc) {
string_buf_alloc *= 2;
string_buf = realloc(string_buf, string_buf_alloc);
assert(string_buf != NULL);
}
/* copy and unconditionally terminate */
memcpy(char_buf->buf+current_length, text, length);
char_buf->buf[char_buf->buf_len] = '\0';
memcpy(string_buf+current_length, text, length);
string_buf[string_buf_len] = '\0';
}
%}
@ -88,7 +90,6 @@ question_mark "?"
single_quote "'"
mode_chars ([RrWwaLlMmkXx])|([Pp][Xx])|([Uu][Xx])|([Ii][Xx])|([Pp][Ii][Xx])
modes ({mode_chars}+)|({mode_chars}+::{mode_chars}*)|(::{mode_chars}*)
none "none"
/* New message types */
aa_reject_type "APPARMOR_DENIED"
@ -156,13 +157,9 @@ key_capname "capname"
key_offset "offset"
key_target "target"
key_laddr "laddr"
key_saddr "saddr"
key_faddr "faddr"
key_daddr "daddr"
key_lport "lport"
key_srcport "src"
key_fport "fport"
key_destport "dest"
key_bus "bus"
key_dest "dest"
key_path "path"
@ -176,8 +173,6 @@ key_flags "flags"
key_srcname "srcname"
key_class "class"
key_tcontext "tcontext"
key_unix_peer_addr "peer_addr"
key_execpath "execpath"
audit "audit"
/* network addrs */
@ -230,7 +225,7 @@ yy_flex_debug = 0;
{open_paren} { return(TOK_OPEN_PAREN); }
{close_paren} { BEGIN(INITIAL); return(TOK_CLOSE_PAREN); }
{ws} { }
\" { string_buf_reset(yyextra); BEGIN(quoted_string); }
\" { string_buf_reset(); BEGIN(quoted_string); }
{ID}+ {
yylval->t_str = strdup(yytext);
BEGIN(INITIAL);
@ -239,20 +234,20 @@ yy_flex_debug = 0;
{equals} { return(TOK_EQUALS); }
}
\" { string_buf_reset(yyextra); BEGIN(quoted_string); }
\" { string_buf_reset(); BEGIN(quoted_string); }
<quoted_string>\" { /* End of the quoted string */
BEGIN(INITIAL);
yylval->t_str = strdup(yyextra->buf);
yylval->t_str = strdup(string_buf);
return(TOK_QUOTED_STRING);
}
<quoted_string>\\(.|\n) { string_buf_append(yyextra, 1, &yytext[1]); }
<quoted_string>\\(.|\n) { string_buf_append(1, &yytext[1]); }
<quoted_string>[^\\\n\"]+ { string_buf_append(yyextra, yyleng, yytext); }
<quoted_string>[^\\\n\"]+ { string_buf_append(yyleng, yytext); }
<safe_string>{
\" { string_buf_reset(yyextra); BEGIN(quoted_string); }
\" { string_buf_reset(); BEGIN(quoted_string); }
{hexstring} { yylval->t_str = hex_to_string(yytext); BEGIN(INITIAL); return(TOK_HEXSTRING);}
{equals} { return(TOK_EQUALS); }
. { /* eek, error! try another state */ BEGIN(INITIAL); yyless(0); }
@ -308,8 +303,6 @@ yy_flex_debug = 0;
{period} { return(TOK_PERIOD); }
{question_mark} { return(TOK_QUESTION_MARK); }
{single_quote} { return(TOK_SINGLE_QUOTE); }
{none} { return(TOK_NONE); }
{key_apparmor} { BEGIN(audit_types); return(TOK_KEY_APPARMOR); }
{key_type} { BEGIN(audit_types); return(TOK_KEY_TYPE); }
@ -349,7 +342,7 @@ yy_flex_debug = 0;
{key_sauid} { return(TOK_KEY_SAUID); }
{key_ses} { return(TOK_KEY_SES); }
{key_hostname} { return(TOK_KEY_HOSTNAME); }
{key_addr} { BEGIN(safe_string); return(TOK_KEY_ADDR); }
{key_addr} { return(TOK_KEY_ADDR); }
{key_terminal} { return(TOK_KEY_TERMINAL); }
{key_exe} { BEGIN(safe_string); return(TOK_KEY_EXE); }
{key_comm} { BEGIN(safe_string); return(TOK_KEY_COMM); }
@ -358,13 +351,9 @@ yy_flex_debug = 0;
{key_offset} { return(TOK_KEY_OFFSET); }
{key_target} { return(TOK_KEY_TARGET); }
{key_laddr} { yy_push_state(ip_addr, yyscanner); return(TOK_KEY_LADDR); }
{key_saddr} { yy_push_state(ip_addr, yyscanner); return(TOK_KEY_LADDR); }
{key_faddr} { yy_push_state(ip_addr, yyscanner); return(TOK_KEY_FADDR); }
{key_daddr} { yy_push_state(ip_addr, yyscanner); return(TOK_KEY_FADDR); }
{key_lport} { return(TOK_KEY_LPORT); }
{key_srcport} { return(TOK_KEY_LPORT); }
{key_fport} { return(TOK_KEY_FPORT); }
{key_destport} { return(TOK_KEY_FPORT); }
{key_bus} { return(TOK_KEY_BUS); }
{key_path} { return(TOK_KEY_PATH); }
{key_interface} { return(TOK_KEY_INTERFACE); }
@ -375,8 +364,6 @@ yy_flex_debug = 0;
{key_fstype} { return(TOK_KEY_FSTYPE); }
{key_flags} { BEGIN(safe_string); return(TOK_KEY_FLAGS); }
{key_srcname} { BEGIN(safe_string); return(TOK_KEY_SRCNAME); }
{key_unix_peer_addr} { BEGIN(safe_string); return(TOK_KEY_UNIX_PEER_ADDR); }
{key_execpath} { BEGIN(safe_string); return(TOK_KEY_EXECPATH); }
{key_class} { BEGIN(safe_string); return(TOK_KEY_CLASS); }
{socklogd_kernel} { BEGIN(dmesg_timestamp); return(TOK_SOCKLOGD_KERNEL); }

View File

@ -1,20 +0,0 @@
#include <aalogparse.h>
#include <string.h>
#include "private.h"
const char* log_line = "[23342.075380] audit: type=1400 audit(1725487203.971:1831): apparmor=\"DENIED\" operation=\"open\" class=\"file\" profile=\"snap-update-ns.firmware-updater\" name=\"/proc/202964/maps\" pid=202964 comm=\"5\" requested_mask=\"r\" denied_mask=\"r\" fsuid=1000 ouid=0";
int main(void) {
int rc = 0;
/* Very basic test to ensure we can do aalogparse stuff in C++ */
aa_log_record *record = parse_record(log_line);
MY_TEST(record != NULL, "Log failed to parse");
MY_TEST(record->version == AA_RECORD_SYNTAX_V2, "Log should have parsed as v2 form");
MY_TEST(record->aa_namespace == NULL, "Log should have NULL namespace");
MY_TEST((record->rule_class != NULL) && (strcmp(record->rule_class, "file") == 0), "Log should have file class");
free_record(record);
return rc;
}

View File

@ -1,20 +0,0 @@
#include <aalogparse.h>
#include <string.h>
#include "private.h"
const char* log_line = "[23342.075380] audit: type=1400 audit(1725487203.971:1831): apparmor=\"DENIED\" operation=\"open\" class=\"file\" profile=\"snap-update-ns.firmware-updater\" name=\"/proc/202964/maps\" pid=202964 comm=\"5\" requested_mask=\"r\" denied_mask=\"r\" fsuid=1000 ouid=0";
int main(void) {
int rc = 0;
/* Very basic test to ensure we can use the C++-incompatible field names */
aa_log_record *record = parse_record(log_line);
MY_TEST(record != NULL, "Log failed to parse");
MY_TEST(record->version == AA_RECORD_SYNTAX_V2, "Log should have parsed as v2 form");
MY_TEST(record->namespace == NULL, "Log should have NULL namespace");
MY_TEST((record->class != NULL) && (strcmp(record->class, "file") == 0), "Log should have file class");
free_record(record);
return rc;
}

View File

@ -1,154 +0,0 @@
#include <pthread.h>
#include <string.h>
#include <aalogparse.h>
#include "private.h"
const char* log_line = "[23342.075380] audit: type=1400 audit(1725487203.971:1831): apparmor=\"DENIED\" operation=\"open\" class=\"file\" profile=\"snap-update-ns.firmware-updater\" name=\"/proc/202964/maps\" pid=202964 comm=\"5\" requested_mask=\"r\" denied_mask=\"r\" fsuid=1000 ouid=0";
const char* log_line_2 = "[ 4074.372559] audit: type=1400 audit(1725553393.143:793): apparmor=\"DENIED\" operation=\"capable\" class=\"cap\" profile=\"/usr/lib/snapd/snap-confine\" pid=19034 comm=\"snap-confine\" capability=12 capname=\"net_admin\"";
static int pthread_barrier_ok(int barrier_result) {
return barrier_result == 0 || barrier_result == PTHREAD_BARRIER_SERIAL_THREAD;
}
static int nullcmp_and_strcmp(const void *s1, const void *s2)
{
/* Return 0 if both pointers are NULL & non-zero if only one is NULL */
if (!s1 || !s2)
return s1 != s2;
return strcmp(s1, s2);
}
int aa_log_record_eq(aa_log_record *record1, aa_log_record *record2) {
int are_eq = 1;
are_eq &= (record1->version == record2->version);
are_eq &= (record1->event == record2->event);
are_eq &= (record1->pid == record2->pid);
are_eq &= (record1->peer_pid == record2->peer_pid);
are_eq &= (record1->task == record2->task);
are_eq &= (record1->magic_token == record2->magic_token);
are_eq &= (record1->epoch == record2->epoch);
are_eq &= (record1->audit_sub_id == record2->audit_sub_id);
are_eq &= (record1->bitmask == record2->bitmask);
are_eq &= (nullcmp_and_strcmp(record1->audit_id, record2->audit_id) == 0);
are_eq &= (nullcmp_and_strcmp(record1->operation, record2->operation) == 0);
are_eq &= (nullcmp_and_strcmp(record1->denied_mask, record2->denied_mask) == 0);
are_eq &= (nullcmp_and_strcmp(record1->requested_mask, record2->requested_mask) == 0);
are_eq &= (record1->fsuid == record2->fsuid);
are_eq &= (record1->ouid == record2->ouid);
are_eq &= (nullcmp_and_strcmp(record1->profile, record2->profile) == 0);
are_eq &= (nullcmp_and_strcmp(record1->peer_profile, record2->peer_profile) == 0);
are_eq &= (nullcmp_and_strcmp(record1->comm, record2->comm) == 0);
are_eq &= (nullcmp_and_strcmp(record1->name, record2->name) == 0);
are_eq &= (nullcmp_and_strcmp(record1->name2, record2->name2) == 0);
are_eq &= (nullcmp_and_strcmp(record1->namespace, record2->namespace) == 0);
are_eq &= (nullcmp_and_strcmp(record1->attribute, record2->attribute) == 0);
are_eq &= (record1->parent == record2->parent);
are_eq &= (nullcmp_and_strcmp(record1->info, record2->info) == 0);
are_eq &= (nullcmp_and_strcmp(record1->peer_info, record2->peer_info) == 0);
are_eq &= (record1->error_code == record2->error_code);
are_eq &= (nullcmp_and_strcmp(record1->active_hat, record2->active_hat) == 0);
are_eq &= (nullcmp_and_strcmp(record1->net_family, record2->net_family) == 0);
are_eq &= (nullcmp_and_strcmp(record1->net_protocol, record2->net_protocol) == 0);
are_eq &= (nullcmp_and_strcmp(record1->net_sock_type, record2->net_sock_type) == 0);
are_eq &= (nullcmp_and_strcmp(record1->net_local_addr, record2->net_local_addr) == 0);
are_eq &= (record1->net_local_port == record2->net_local_port);
are_eq &= (nullcmp_and_strcmp(record1->net_foreign_addr, record2->net_foreign_addr) == 0);
are_eq &= (record1->net_foreign_port == record2->net_foreign_port);
are_eq &= (nullcmp_and_strcmp(record1->execpath, record2->execpath) == 0);
are_eq &= (nullcmp_and_strcmp(record1->dbus_bus, record2->dbus_bus) == 0);
are_eq &= (nullcmp_and_strcmp(record1->dbus_path, record2->dbus_path) == 0);
are_eq &= (nullcmp_and_strcmp(record1->dbus_interface, record2->dbus_interface) == 0);
are_eq &= (nullcmp_and_strcmp(record1->dbus_member, record2->dbus_member) == 0);
are_eq &= (nullcmp_and_strcmp(record1->signal, record2->signal) == 0);
are_eq &= (nullcmp_and_strcmp(record1->peer, record2->peer) == 0);
are_eq &= (nullcmp_and_strcmp(record1->fs_type, record2->fs_type) == 0);
are_eq &= (nullcmp_and_strcmp(record1->flags, record2->flags) == 0);
are_eq &= (nullcmp_and_strcmp(record1->src_name, record2->src_name) == 0);
are_eq &= (nullcmp_and_strcmp(record1->class, record2->class) == 0);
are_eq &= (nullcmp_and_strcmp(record1->net_addr, record2->net_addr) == 0);
are_eq &= (nullcmp_and_strcmp(record1->peer_addr, record2->peer_addr) == 0);
return are_eq;
}
typedef struct {
const char* log;
pthread_barrier_t *barrier;
} pthread_parse_args;
void* pthread_parse_log(void* args) {
pthread_parse_args *args_real = (pthread_parse_args *) args;
int barrier_wait_result = pthread_barrier_wait(args_real->barrier);
/* Return NULL and fail test if barrier wait fails */
if (!pthread_barrier_ok(barrier_wait_result)) {
return NULL;
}
aa_log_record *record = parse_record(args_real->log);
return (void*) record;
}
#define NUM_THREADS 16
int main(void) {
pthread_t thread_ids[NUM_THREADS];
pthread_barrier_t barrier;
int barrier_wait_result;
aa_log_record* parsed_logs[NUM_THREADS];
int rc = 0;
/* Set up arguments to be passed to threads */
pthread_parse_args args = {.log=log_line, .barrier=&barrier};
pthread_parse_args args2 = {.log=log_line_2, .barrier=&barrier};
MY_TEST(NUM_THREADS > 2, "Test requires more than 2 threads");
/* Use barrier to synchronize the start of log parsing among all the threads
* This increases the likelihood of tickling race conditions, if there are any
*/
MY_TEST(pthread_barrier_init(&barrier, NULL, NUM_THREADS+1) == 0,
"Could not init pthread barrier");
for (int i=0; i<NUM_THREADS; i++) {
if (i%2 == 0) {
pthread_create(&thread_ids[i], NULL, pthread_parse_log, (void *) &args);
} else {
pthread_create(&thread_ids[i], NULL, pthread_parse_log, (void *) &args2);
}
}
/* Final barrier_wait to set off the thread race */
barrier_wait_result = pthread_barrier_wait(&barrier);
MY_TEST(pthread_barrier_ok(barrier_wait_result), "Could not wait on pthread barrier");
/* Wait for threads to finish parsing the logs */
for (int i=0; i<NUM_THREADS; i++) {
MY_TEST(pthread_join(thread_ids[i], (void*) &parsed_logs[i]) == 0, "Could not join thread");
}
/* Check that all logs parsed and are equal */
for (int i=0; i<NUM_THREADS; i++) {
MY_TEST(parsed_logs[i] != NULL, "Log failed to parse");
MY_TEST(parsed_logs[i]->version == AA_RECORD_SYNTAX_V2, "Log should have parsed as v2 form");
MY_TEST(parsed_logs[i]->event == AA_RECORD_DENIED, "Log should have parsed as denied");
/* Also check i==0 and i==1 as a sanity check for aa_log_record_eq */
if (i%2 == 0) {
MY_TEST(aa_log_record_eq(parsed_logs[0], parsed_logs[i]), "Log 0 != Log even");
} else {
MY_TEST(aa_log_record_eq(parsed_logs[1], parsed_logs[i]), "Log 1 != Log odd");
}
}
MY_TEST(!aa_log_record_eq(parsed_logs[0], parsed_logs[1]), "Log 0 and log 1 shouldn't be equal");
/* Clean up */
MY_TEST(pthread_barrier_destroy(&barrier) == 0, "Could not destroy pthread barrier");
for (int i=0; i<NUM_THREADS; i++) {
free_record(parsed_logs[i]);
}
return rc;
}

View File

@ -135,7 +135,7 @@ static int do_test_walk_one(const char **str, const struct component *component,
static int test_walk_one(void)
{
struct component c = (struct component) { NULL, 0 };
struct component c;
const char *str;
int rc = 0;

View File

@ -1,3 +1,3 @@
SUBDIRS = perl python ruby
EXTRA_DIST = SWIG/*.i
EXTRA_DIST = SWIG/*.i java/Makefile.am

View File

@ -5,98 +5,9 @@
#include <sys/apparmor.h>
#include <sys/apparmor_private.h>
// Include static_assert if the C compiler supports it
// static_assert standardized since C11, assert.h not needed since C23
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && __STDC_VERSION__ < 202311L
#include <assert.h>
#endif
%}
%include "typemaps.i"
%include <cstring.i>
%include <stdint.i>
%include <exception.i>
/*
* SWIG 4.3 included https://github.com/swig/swig/pull/2907 to distinguish
* between Py_None being returned as a default void and Py_None being returned
* as the equivalent of C NULL. Unfortunately, this turns into an API breaking
* change with our use of %append_output when we want the Python function to
* return something even when the C function has a void return type. Thus, we
* need an additional macro to smooth over the differences. Include all affected
* languages, even ones we don't build bindings for, for completeness.
*/
#if SWIG_VERSION >= 0x040300
#ifdef SWIGPYTHON
#define ISVOID_APPEND_OUTPUT(value) {$result = SWIG_Python_AppendOutput($result, value, 1);}
#elif defined(SWIGRUBY)
#define ISVOID_APPEND_OUTPUT(value) {$result = SWIG_Ruby_AppendOutput($result, value, 1);}
#elif defined(SWIGPHP)
#define ISVOID_APPEND_OUTPUT(value) {$result = SWIG_Php_AppendOutput($result, value, 1);}
#else
#define ISVOID_APPEND_OUTPUT(value) %append_output(value)
#endif
#else
#define ISVOID_APPEND_OUTPUT(value) %append_output(value)
#endif
%newobject parse_record;
%delobject free_record;
/*
* Despite its name, %delobject does not hook up destructors to language
* deletion mechanisms. Instead, it sets flags so that manually calling the
* free function and then deleting by language mechanisms doesn't cause a
* double-free.
*
* Additionally, we can manually extend the struct with a C++-like
* destructor. This ensures that the record struct is freed
* automatically when the high-level object goes out of scope.
*/
%extend aa_log_record {
~aa_log_record() {
free_record($self);
}
}
/*
* Generate a no-op free_record wrapper to avoid making a double-free footgun.
* Use rename directive to avoid colliding with the actual free_record, which
* we use above to clean up when the higher-level language deletes the object.
*
* Ideally we would not expose a free_record at all, but we need to maintain
* backwards compatibility with the existing high-level code that uses it.
*/
%rename(free_record) noop_free_record;
#ifdef SWIGPYTHON
%pythonprepend noop_free_record %{
import warnings
warnings.warn("free_record is now a no-op as the record's memory is handled automatically", DeprecationWarning)
%}
#endif
%feature("autodoc",
"This function used to free aa_log_record objects. Freeing is now handled "
"automatically, so this no-op function remains for backwards compatibility.") noop_free_record;
%inline %{
void noop_free_record(aa_log_record *record) {(void) record;}
%}
/*
* Do not autogenerate a wrapper around free_record. This does not prevent us
* from calling it ourselves in %extend C code.
*/
%ignore free_record;
/*
* Map names to preserve backwards compatibility
*/
#ifdef SWIGPYTHON
%rename("_class") aa_log_record::rule_class;
#else
%rename("class") aa_log_record::rule_class;
#endif
%rename("namespace") aa_log_record::aa_namespace;
%include <aalogparse.h>
/**
@ -110,75 +21,18 @@ warnings.warn("free_record is now a no-op as the record's memory is handled auto
/* apparmor.h */
/*
* label is a heap-allocated pointer, but when label and mode occur together,
* the freeing of label must be deferred because mode points into label.
*
* %cstring_output_allocate((char **label, char **mode), free(*$1))
* does not handle multi-argument typemaps correctly, so we write our own
* typemap based on it instead.
*/
%typemap(in,noblock=1,numinputs=0) (char **label, char **mode) ($*1_ltype temp_label = 0, $*2_ltype temp_mode = 0) {
$1 = &temp_label;
$2 = &temp_mode;
}
%typemap(freearg,match="in") (char **label, char **mode) ""
%typemap(argout,noblock=1,fragment="SWIG_FromCharPtr") (char **label, char **mode) {
ISVOID_APPEND_OUTPUT(SWIG_FromCharPtr(*$1));
ISVOID_APPEND_OUTPUT(SWIG_FromCharPtr(*$2));
free(*$1);
}
/*
* mode also occurs in combination with con in aa_splitcon
* typemap based on %cstring_mutable but with substantial modifications
*/
%typemap(in,numinputs=1,fragment="SWIG_AsCharPtrAndSize") (char *con, char **mode) ($*2_ltype temp_mode = 0) {
int alloc_status = 0;
$1_ltype con_ptr = NULL;
size_t con_len = 0;
int char_ptr_res = SWIG_AsCharPtrAndSize($input, &con_ptr, &con_len, &alloc_status);
if (!SWIG_IsOK(char_ptr_res)) {
%argument_fail(char_ptr_res, "char *con", $symname, $argnum);
}
if (alloc_status != SWIG_NEWOBJ) {
// Unconditionally copy because the C function modifies the string in place
$1 = %new_copy_array(con_ptr, con_len+1, char);
} else {
$1 = con_ptr;
}
$2 = &temp_mode;
}
%typemap(freearg,noblock=1,match="in") (char *con, char **mode) {
%delete_array($1);
}
%typemap(argout,noblock=1,fragment="SWIG_FromCharPtr") (char *con, char **mode) {
/*
* aa_splitcon returns either con or NULL so we don't need to explicitly
* append it to the output, and we don't need the ISVOID helper here
*
* SWIG_FromCharPtr does NULL checks for us
*/
%append_output(SWIG_FromCharPtr(*$2));
}
%exception aa_splitcon {
$action
if (result == NULL) {
SWIG_exception_fail(SWIG_ValueError, "received invalid confinement context");
}
}
extern char *aa_splitcon(char *con, char **mode);
/* apparmor_private.h */
extern int _aa_is_blacklisted(const char *name);
#ifdef SWIGPYTHON
%exception {
$action
if (result < 0) {
// Unfortunately SWIG_exception does not support OSError
PyErr_SetFromErrno(PyExc_OSError);
SWIG_fail;
return NULL;
}
}
#endif
@ -187,248 +41,33 @@ extern char *aa_splitcon(char *con, char **mode);
/* apparmor.h */
/*
* aa_is_enabled returns a boolean as an int with failure reason in errno
* Therefore, aa_is_enabled either returns True or throws an exception
*
* Keep that behavior for backwards compatibilty but return a boolean on Python
* where it makes more sense, which isn't a breaking change because a boolean is
* a subclass of int
*/
#ifdef SWIGPYTHON
%typemap(out) int {
$result = PyBool_FromLong($1);
}
#endif
extern int aa_is_enabled(void);
#ifdef SWIGPYTHON
// Based on SWIG's argcargv.i but we don't have an argc
%typemap(in,fragment="SWIG_AsCharPtr") const char *subprofiles[] (Py_ssize_t seq_len=0, int* alloc_tracking = NULL) {
void* arg_as_ptr = NULL;
int res_convertptr = SWIG_ConvertPtr($input, &arg_as_ptr, $descriptor(char*[]), 0);
if (SWIG_IsOK(res_convertptr)) {
$1 = %static_cast(arg_as_ptr, $1_ltype);
} else {
// Clear error that would be set if ptr conversion failed
PyErr_Clear();
int is_list = PyList_Check($input);
if (is_list || PyTuple_Check($input)) {
seq_len = PySequence_Length($input);
/*
* %new_array zero-inits for cleaner error handling and memory cleanup
* %delete_array(NULL) is no-op (either free or delete), and
* alloc_tracking of 0 is uninit
*
* Further note: SWIG_exception_fail jumps to the freearg typemap
*/
$1 = %new_array(seq_len+1, char *);
if ($1 == NULL) {
SWIG_exception_fail(SWIG_MemoryError, "could not allocate C subprofiles");
}
alloc_tracking = %new_array(seq_len, int);
if (alloc_tracking == NULL) {
SWIG_exception_fail(SWIG_MemoryError, "could not allocate C alloc track arr");
}
for (Py_ssize_t i=0; i<seq_len; i++) {
PyObject *o = is_list ? PyList_GetItem($input, i) : PyTuple_GetItem($input, i);
if (o == NULL) {
// Failed to get item-Python already set exception info
SWIG_fail;
} else if (o == Py_None) {
// SWIG_AsCharPtr(Py_None, ...) succeeds with ptr output being NULL
SWIG_exception_fail(SWIG_ValueError, "sequence contains a None object");
}
int res = SWIG_AsCharPtr(o, &$1[i], &alloc_tracking[i]);
if (!SWIG_IsOK(res)) {
// Could emit idx of error here, maybe?
SWIG_exception_fail(SWIG_ArgError(res), "sequence does not contain all strings");
}
}
} else {
SWIG_exception_fail(SWIG_TypeError, "subprofiles is not a list or tuple");
}
}
}
%typemap(freearg,noblock=1) const char *subprofiles[] {
/*
* If static_assert is present, use it to verify the assumption that
* allocation uninitialized (0) != SWIG_NEWOBJ
*/
%#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
/*
* Some older versions of SWIG place this right after a goto label
* This would then be a label followed by a declaration, a C23 extension (!)
* To ensure this works for older SWIG versions and older compilers,
* make this a block element with curly braces.
*/
{static_assert(SWIG_NEWOBJ != 0, "SWIG_NEWOBJ is 0");}
%#endif
if ($1 != NULL && alloc_tracking$argnum != NULL) {
for (Py_ssize_t i=0; i<seq_len$argnum; i++) {
if (alloc_tracking$argnum[i] == SWIG_NEWOBJ) {
%delete_array($1[i]);
}
}
}
%delete_array(alloc_tracking$argnum);
%delete_array($1);
}
#endif
#ifdef SWIGPERL
// Copied from perl's argcargv.i, which should be good enough for us
%typemap(in) (const char *subprofiles[]) {
int i;
SSize_t len;
AV *av = (AV *)SvRV($input);
if (SvTYPE(av) != SVt_PVAV) {
SWIG_croak("in method '$symname', Expecting reference to argv array");
goto fail;
}
len = av_len(av) + 1;
$1 = (char **) malloc((len+1)*sizeof(char *));
for (i = 0; i < len; i++) {
SV **tv = av_fetch(av, i, 0);
$1[i] = SvPV_nolen(*tv);
}
$1[i] = NULL;
}
%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (const char *subprofiles[]) {
AV *av = (AV *)SvRV($input);
$1 = SvTYPE(av) == SVt_PVAV;
}
%typemap(freearg) (const char *subprofiles[]) {
free((void *)$1);
}
#endif
/* These should not receive the VOID_Object typemap */
extern int aa_find_mountpoint(char **mnt);
extern int aa_change_hat(const char *subprofile, unsigned long magic_token);
extern int aa_change_profile(const char *profile);
extern int aa_change_onexec(const char *profile);
extern int aa_change_hatv(const char *subprofiles[], unsigned long token);
extern int aa_change_hat_vargs(unsigned long token, int count, ...);
extern int aa_stack_profile(const char *profile);
extern int aa_stack_onexec(const char *profile);
/*
* aa_find_mountpoint mnt is an output pointer to a heap-allocated string
*
* This is a replica of %cstring_output_allocate(char **mnt, free(*$1))
* that uses the ISVOID helper to work correctly on SWIG 4.3 or later.
*/
%typemap(in,noblock=1,numinputs=0) (char **mnt) ($*1_ltype temp_mnt = 0) {
$1 = &temp_mnt;
}
%typemap(freearg,match="in") (char **mnt) ""
%typemap(argout,noblock=1,fragment="SWIG_FromCharPtr") (char **mnt) {
ISVOID_APPEND_OUTPUT(SWIG_FromCharPtr(*$1));
free(*$1);
}
/* The other errno-based functions should not always be returning the int value:
* - Python exceptions signal success/failure status instead via the %exception
* handler above.
* - Perl (the other binding) has $! for accessing errno but would check the int
* return status first.
*
* The generated C code for (out) resets the return value to None
* before appending the returned data (argout generated by %cstring stuff)
*/
#ifdef SWIGPYTHON
%typemap(out,noblock=1) int {
#if defined(VOID_Object)
$result = VOID_Object;
#endif
}
#endif
/*
* We can't use "typedef int pid_t" because we still support systems
* with 16-bit PIDs and SWIG can't find sys/types.h
*
* Capture the passed-in value as a long because pid_t is guaranteed
* to be a signed integer and because the aalogparse struct uses
* (unsigned) longs to store pid values. While intmax_t would be more
* technically correct, if sizeof(pid_t) > sizeof(long) then aalogparse
* itself would also need fixing.
*/
%typemap(in,noblock=1,fragment="SWIG_AsVal_long") pid_t (int conv_pid, long pid_large) {
%#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
static_assert(sizeof(pid_t) <= sizeof(long),
"pid_t type is too large to be stored in a long");
%#endif
conv_pid = SWIG_AsVal_long($input, &pid_large);
if (!SWIG_IsOK(conv_pid)) {
%argument_fail(conv_pid, "pid_t", $symname, $argnum);
}
/*
* Cast the long to a pid_t and then cast back to check for overflow
* Technically this is implementation-defined behaviour but we should be fine
*/
$1 = (pid_t) pid_large;
if ((long) $1 != pid_large) {
SWIG_exception_fail(SWIG_OverflowError, "pid_t is too large");
}
}
extern int aa_find_mountpoint(char **mnt);
extern int aa_getprocattr(pid_t tid, const char *attr, char **label, char **mode);
extern int aa_getprocattr_raw(pid_t tid, const char *attr, char *buf, int len,
char **mode);
extern int aa_getprocattr(pid_t tid, const char *attr, char **buf, char **mode);
extern int aa_gettaskcon(pid_t target, char **label, char **mode);
extern int aa_getcon(char **label, char **mode);
extern int aa_getpeercon_raw(int fd, char *buf, int *len, char **mode);
extern int aa_getpeercon(int fd, char **label, char **mode);
/*
* Typemaps for the boolean outputs of the query functions
* Use boolean types for Python and int types elsewhere
*/
#ifdef SWIGPYTHON
// TODO: find a way to deduplicate these
%typemap(in, numinputs=0) int *allowed (int temp) {
$1 = &temp;
}
%typemap(argout) int *allowed {
ISVOID_APPEND_OUTPUT(PyBool_FromLong(*$1));
}
%typemap(in, numinputs=0) int *audited (int temp) {
$1 = &temp;
}
%typemap(argout) int *audited {
ISVOID_APPEND_OUTPUT(PyBool_FromLong(*$1));
}
#else
%apply int *OUTPUT { int *allowed };
%apply int *OUTPUT { int *audited };
#endif
/* Sync this with the apparmor.h */
/* Permission flags for the AA_CLASS_FILE mediation class */
#define AA_MAY_EXEC (1 << 0)
#define AA_MAY_WRITE (1 << 1)
#define AA_MAY_READ (1 << 2)
#define AA_MAY_APPEND (1 << 3)
#define AA_MAY_CREATE (1 << 4)
#define AA_MAY_DELETE (1 << 5)
#define AA_MAY_OPEN (1 << 6)
#define AA_MAY_RENAME (1 << 7)
#define AA_MAY_SETATTR (1 << 8)
#define AA_MAY_GETATTR (1 << 9)
#define AA_MAY_SETCRED (1 << 10)
#define AA_MAY_GETCRED (1 << 11)
#define AA_MAY_CHMOD (1 << 12)
#define AA_MAY_CHOWN (1 << 13)
#define AA_MAY_LOCK 0x8000
#define AA_EXEC_MMAP 0x10000
#define AA_MAY_LINK 0x40000
#define AA_MAY_ONEXEC 0x20000000
#define AA_MAY_CHANGE_PROFILE 0x40000000
extern int aa_query_label(uint32_t mask, char *query, size_t size, int *allow,
int *audit);
extern int aa_query_file_path_len(uint32_t mask, const char *label,
size_t label_len, const char *path,
size_t path_len, int *allowed, int *audited);
extern int aa_query_file_path(uint32_t mask, const char *label,
const char *path, int *allowed, int *audited);
extern int aa_query_link_path_len(const char *label, size_t label_len,
const char *target, size_t target_len,
const char *link, size_t link_len,
int *allowed, int *audited);
extern int aa_query_link_path(const char *label, const char *target,
const char *link, int *allowed, int *audited);

View File

@ -0,0 +1,21 @@
WRAPPERFILES = apparmorlogparse_wrap.c
BUILT_SOURCES = apparmorlogparse_wrap.c
all-local: apparmorlogparse_wrap.o
$(CC) -module apparmorlogparse_wrap.o -o libaalogparse.so
apparmorlogparse_wrap.o: apparmorlogparse_wrap.c
$(CC) -c apparmorlogparse_wrap.c $(CFLAGS) -I../../src -I/usr/include/classpath -fno-strict-aliasing -o apparmorlogparse_wrap.o
clean-local:
rm -rf org
apparmorlogparse_wrap.c: org/aalogparse ../SWIG/*.i
$(SWIG) -java -I../SWIG -I../../src -outdir org/aalogparse \
-package org.aalogparse -o apparmorlogparse_wrap.c libaalogparse.i
org/aalogparse:
mkdir -p org/aalogparse
EXTRA_DIST = $(BUILT_SOURCES)

View File

@ -14,7 +14,7 @@ MOSTLYCLEANFILES=libapparmor_wrap.c LibAppArmor.py
all-local: libapparmor_wrap.c setup.py
if test ! -f libapparmor_wrap.c; then cp $(srcdir)/libapparmor_wrap.c . ; fi
CC="$(CC)" CFLAGS="$(PYTHON_CPPFLAGS) $(CFLAGS) $(EXTRA_WARNINGS)" LDSHARED="$(CC) -shared" LDFLAGS="$(PYTHON_LDFLAGS) $(LDFLAGS)" $(PYTHON) setup.py build
CC="$(CC)" CFLAGS="$(PYTHON_CPPFLAGS) $(EXTRA_WARNINGS)" LDSHARED="$(CC) -shared" LDFLAGS="$(PYTHON_LDFLAGS) $(LDFLAGS)" $(PYTHON) setup.py build
install-exec-local:
$(PYTHON) setup.py install --root="/$(DESTDIR)" --prefix="$(prefix)"

View File

@ -2,7 +2,7 @@ from setuptools import setup, Extension
import string
setup(name = 'LibAppArmor',
version = '@VERSION@'.replace('~', '-'),
version = '@VERSION@',
author = 'AppArmor Dev Team',
author_email = 'apparmor@lists.ubuntu.com',
url = 'https://wiki.apparmor.net',

View File

@ -15,7 +15,6 @@ PYTHON_DIST_BUILD_PATH = '$(builddir)/../build/$$($(PYTHON) buildpath.py)'
TESTS = test_python.py
TESTS_ENVIRONMENT = \
LD_LIBRARY_PATH='$(top_builddir)/src/.libs:$(PYTHON_DIST_BUILD_PATH)' \
PYTHONPATH='$(PYTHON_DIST_BUILD_PATH)' \
PYTHONDONTWRITEBYTECODE='1'
PYTHONPATH='$(PYTHON_DIST_BUILD_PATH)'
endif

View File

@ -7,7 +7,7 @@ import sysconfig
import setuptools
if tuple(map(int, setuptools.__version__.split(".")[:2])) >= (62, 1):
if tuple(map(int, setuptools.__version__.split("."))) >= (62, 1):
identifier = sys.implementation.cache_tag
else:
identifier = "%d.%d" % sys.version_info[:2]

View File

@ -55,100 +55,10 @@ NO_VALUE_MAP = {
'fsuid': int(ctypes.c_ulong(-1).value),
'ouid': int(ctypes.c_ulong(-1).value),
}
class AAPythonBindingsTests(unittest.TestCase):
def setUp(self):
# REPORT ALL THE OUTPUT
self.maxDiff = None
def test_aa_splitcon(self):
AA_SPLITCON_EXPECT = [
("unconfined", "unconfined", None),
("unconfined\n", "unconfined", None),
("/bin/ping (enforce)", "/bin/ping", "enforce"),
("/bin/ping (enforce)\n", "/bin/ping", "enforce"),
("/usr/sbin/rsyslog (complain)", "/usr/sbin/rsyslog", "complain"),
]
for context, expected_label, expected_mode in AA_SPLITCON_EXPECT:
actual_label, actual_mode = libapparmor.aa_splitcon(context)
if expected_label is None:
self.assertIsNone(actual_label)
else:
self.assertIsInstance(actual_label, str)
self.assertEqual(expected_label, actual_label)
if expected_mode is None:
self.assertIsNone(actual_mode)
else:
self.assertIsInstance(actual_mode, str)
self.assertEqual(expected_mode, actual_mode)
with self.assertRaises(ValueError):
libapparmor.aa_splitcon("")
def test_aa_is_enabled(self):
aa_enabled = libapparmor.aa_is_enabled()
self.assertIsInstance(aa_enabled, bool)
@unittest.skipUnless(libapparmor.aa_is_enabled(), "AppArmor is not enabled")
def test_aa_find_mountpoint(self):
mount_point = libapparmor.aa_find_mountpoint()
self.assertIsInstance(mount_point, str)
self.assertGreater(len(mount_point), 0, "mount point should not be empty")
self.assertTrue(os.path.isdir(mount_point))
# TODO: test commented out functions (or at least their prototypes)
# extern int aa_change_profile(const char *profile);
# extern int aa_change_onexec(const char *profile);
@unittest.skipUnless(libapparmor.aa_is_enabled(), "AppArmor is not enabled")
def test_change_hats(self):
# Changing hats will fail because we have no valid hats to change to
# However, we still verify that we get an OSError instead of a TypeError
with self.assertRaises(OSError):
libapparmor.aa_change_hat("nonexistent_profile", 12345678)
with self.assertRaises(OSError):
libapparmor.aa_change_hatv(["nonexistent_1", "nonexistent_2"], 0xabcdef)
libapparmor.aa_change_hatv(("nonexistent_1", "nonexistent_2"), 0xabcdef)
# extern int aa_stack_profile(const char *profile);
# extern int aa_stack_onexec(const char *profile);
# extern int aa_getprocattr(pid_t tid, const char *attr, char **label, char **mode);
# extern int aa_gettaskcon(pid_t target, char **label, char **mode);
@unittest.skipUnless(libapparmor.aa_is_enabled(), "AppArmor is not enabled")
def test_aa_gettaskcon(self):
# Our test harness should be running us as unconfined
# Get our own pid and this should be equivalent to aa_getcon
pid = os.getpid()
label, mode = libapparmor.aa_gettaskcon(pid)
self.assertEqual(label, "unconfined", "aa_gettaskcon label should be unconfined")
self.assertIsNone(mode, "aa_gettaskcon mode should be unconfined")
@unittest.skipUnless(libapparmor.aa_is_enabled(), "AppArmor is not enabled")
def test_aa_getcon(self):
# Our test harness should be running us as unconfined
label, mode = libapparmor.aa_getcon()
self.assertEqual(label, "unconfined", "aa_getcon label should be unconfined")
self.assertIsNone(mode, "aa_getcon mode should be unconfined")
# extern int aa_getpeercon(int fd, char **label, char **mode);
# extern int aa_query_file_path(uint32_t mask, const char *label,
# const char *path, int *allowed, int *audited);
@unittest.skipUnless(libapparmor.aa_is_enabled(), "AppArmor is not enabled")
def test_aa_query_file_path(self):
aa_query_mask = libapparmor.AA_MAY_EXEC | libapparmor.AA_MAY_READ | libapparmor.AA_MAY_WRITE
allowed, audited = libapparmor.aa_query_file_path(aa_query_mask, "unconfined", "/tmp/hello")
self.assertTrue(allowed)
self.assertFalse(audited)
# extern int aa_query_link_path(const char *label, const char *target,
# const char *link, int *allowed, int *audited);
class AALogParsePythonBindingsTests(unittest.TestCase):
def setUp(self):
# REPORT ALL THE OUTPUT
self.maxDiff = None
@ -208,9 +118,6 @@ class AALogParsePythonBindingsTests(unittest.TestCase):
# FIXME: out files should report log version?
# FIXME: or can we just deprecate v1 logs?
continue
elif key == "thisown":
# SWIG generates this key to track memory allocation
continue
elif key in NO_VALUE_MAP:
if NO_VALUE_MAP[key] == value:
continue
@ -235,7 +142,7 @@ def main():
def stub_test(self, testname=f):
self._runtest(testname)
stub_test.__doc__ = "test " + f
setattr(AALogParsePythonBindingsTests, 'test_' + f, stub_test)
setattr(AAPythonBindingsTests, 'test_' + f, stub_test)
return unittest.main(verbosity=2)

View File

@ -1,3 +1,5 @@
#define _GNU_SOURCE /* for glibc's basename version */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -5,12 +7,6 @@
#include <aalogparse.h>
static const char *basename(const char *path)
{
const char *p = strrchr(path, '/');
return p ? p + 1 : path;
}
int print_results(aa_log_record *record);
int main(int argc, char **argv)
@ -107,7 +103,7 @@ int print_results(aa_log_record *record)
print_string("Name", record->name);
print_string("Command", record->comm);
print_string("Name2", record->name2);
print_string("Namespace", record->aa_namespace);
print_string("Namespace", record->namespace);
print_string("Attribute", record->attribute);
print_long("Task", record->task, 0);
print_long("Parent", record->parent, 0);
@ -119,8 +115,6 @@ int print_results(aa_log_record *record)
print_long("Peer PID", record->peer_pid, 0);
print_string("Active hat", record->active_hat);
print_string("Net Addr", record->net_addr);
print_string("Peer Addr", record->peer_addr);
print_string("Network family", record->net_family);
print_string("Socket type", record->net_sock_type);
print_string("Protocol", record->net_protocol);
@ -140,9 +134,7 @@ int print_results(aa_log_record *record)
print_string("Flags", record->flags);
print_string("Src name", record->src_name);
print_string("Execpath", record->execpath);
print_string("Class", record->rule_class);
print_string("Class", record->class);
print_long("Epoch", record->epoch, 0);
print_long("Audit subid", (long) record->audit_sub_id, 0);

View File

@ -1,4 +1,2 @@
profile unconfined {
change_profile -> system_tor,
}

View File

@ -1,4 +1,2 @@
/home/cb/bin/hello.sh {
/usr/bin/rm mrix,
}

View File

@ -1,4 +1,2 @@
/usr/bin/wireshark {
/usr/lib64/wireshark/extcap/androiddump mrix,
}

View File

@ -1,4 +1,4 @@
/usr/lib/NetworkManager/nm-dhcp-client.action {
network inet6 dgram port=10580,
network inet6 dgram,
}

View File

@ -1,4 +1,4 @@
/usr/sbin/apache2 {
network inet6 stream ip=::ffff:192.168.236.159 port=80 peer=(ip=::ffff:192.168.103.80 port=61985),
network inet6 stream,
}

View File

@ -1,7 +1,7 @@
/usr/sbin/apache2 {
^www.xxxxxxxxxx.co.uk {
network (send) inet6 stream ip=::ffff:192.168.1.100 port=80 peer=(ip=::ffff:192.168.1.100 port=45658),
network inet6 stream,
}
}

View File

@ -1,7 +1,7 @@
/usr/local/apache-tomcat-8.0.33/bin/catalina.sh {
^/usr/local/jdk1.8.0_92/bin/java {
network (receive) inet6 stream ip=::ffff:127.0.0.1 port=8080 peer=(ip=::ffff:127.0.0.1 port=52308),
network inet6 stream,
}
}

View File

@ -1,4 +1,4 @@
/bin/ping {
/bin/ping mrix,
ping2 ix,
}

View File

@ -1,4 +1,4 @@
/bin/ping {
/bin/ping mrix,
/bin/ping ix,
}

View File

@ -1,4 +1,4 @@
/bin/ping {
/bin/ping mrix,
/bin/ping ix,
}

View File

@ -1,4 +0,0 @@
/home/steve/aa-regression-tests/link {
/tmp/sdtest.8236-29816-IN8243/target l,
}

View File

@ -1 +0,0 @@
2025-01-27T13:01:36.226987+05:30 sec-plucky-amd64 kernel: audit: type=1400 audit(1737963096.225:3240): apparmor="AUDIT" operation="getattr" class="file" profile="/usr/sbin/mosquitto" name="/etc/mosquitto/pwfile" pid=8119 comm="mosquitto" requested_mask="r" fsuid=122 ouid=122

View File

@ -1,15 +0,0 @@
START
File: testcase36.in
Event type: AA_RECORD_AUDIT
Audit ID: 1737963096.225:3240
Operation: getattr
Mask: r
fsuid: 122
ouid: 122
Profile: /usr/sbin/mosquitto
Name: /etc/mosquitto/pwfile
Command: mosquitto
PID: 8119
Class: file
Epoch: 1737963096
Audit subid: 3240

View File

@ -1,4 +0,0 @@
/usr/sbin/mosquitto {
/etc/mosquitto/pwfile r,
}

View File

@ -1,4 +1,3 @@
/tmp/apparmor-2.8.0/tests/regression/apparmor/dbus_service {
dbus send bus=system path=/org/freedesktop/systemd1 interface=org.freedesktop.systemd1.Manager member=LookupDynamicUserByName peer=(label=unconfined),
dbus send bus=system path=/org/freedesktop/systemd1 interface=org.freedesktop.systemd1.Manager member=LookupDynamicUserByName peer=( name=org.freedesktop.systemd1, label=unconfined),
}

View File

@ -1,4 +1,4 @@
/home/ubuntu/bzr/apparmor/tests/regression/apparmor/mount {
mount fstype=(ext2) options=(mand, rw) /dev/loop0/ -> /tmp/sdtest.19033-29001-MPfz98/mountpoint/,
mount fstype=ext2 options="rw, mand" /dev/loop0/ -> /tmp/sdtest.19033-29001-MPfz98/mountpoint/,
}

View File

@ -1 +0,0 @@
type=AVC msg=audit(1715045678.914:344186): apparmor="ALLOWED" operation="mount" info="failed flags match" error=-13 profile="steam" name="/newroot/dev/" pid=26487 comm="srt-bwrap" flags="rw, nosuid, nodev, remount, bind, silent, relatime"

View File

@ -1,14 +0,0 @@
START
File: testcase_mount_02.in
Event type: AA_RECORD_ALLOWED
Audit ID: 1715045678.914:344186
Operation: mount
Profile: steam
Name: /newroot/dev/
Command: srt-bwrap
Info: failed flags match
ErrorCode: 13
PID: 26487
Flags: rw, nosuid, nodev, remount, bind, silent, relatime
Epoch: 1715045678
Audit subid: 344186

View File

@ -1,4 +0,0 @@
profile steam {
mount options=(bind, nodev, nosuid, relatime, remount, rw, silent) -> /newroot/dev/,
}

View File

@ -1,4 +1,4 @@
/usr/bin/evince-thumbnailer {
network inet stream ip=192.168.66.150 port=765 peer=(ip=192.168.66.200 port=2049),
network inet stream,
}

View File

@ -1,4 +1,4 @@
/usr/bin/evince-thumbnailer {
network inet stream port=765 peer=(port=2049),
network inet stream,
}

View File

@ -1,4 +1,4 @@
/usr/lib/dovecot/imap-login {
network inet6 stream port=143,
network inet6 stream,
}

View File

@ -1,4 +1,4 @@
/home/ubuntu/tmp/nc {
network inet6 stream ip=::1 port=2048 peer=(ip=::1 port=33986),
network inet6 stream,
}

View File

@ -1,4 +1,4 @@
/home/ubuntu/tmp/nc {
network inet6 stream ip=::ffff:127.0.0.1 port=2048 peer=(ip=::ffff:127.0.0.1 port=59180),
network inet6 stream,
}

View File

@ -1 +0,0 @@
[319992.813426] audit: type=1400 audit(1716557137.764:477): apparmor="DENIED" operation="recvmsg" class="net" info="failed remote addr match" error=-13 profile="/home/ubuntu/apparmor/tests/regression/apparmor/net_inet_rcv" pid=22237 comm="net_inet_rcv" laddr=127.0.97.3 lport=3456 saddr=127.0.97.3 src=3456 family="inet" sock_type="dgram" protocol=17 requested="receive" denied="receive"

View File

@ -1,20 +0,0 @@
START
File: testcase_network_06.in
Event type: AA_RECORD_DENIED
Audit ID: 1716557137.764:477
Operation: recvmsg
Mask: receive
Denied Mask: receive
Profile: /home/ubuntu/apparmor/tests/regression/apparmor/net_inet_rcv
Command: net_inet_rcv
Info: failed remote addr match
ErrorCode: 13
PID: 22237
Network family: inet
Socket type: dgram
Protocol: udp
Local addr: 127.0.97.3
Local port: 3456
Class: net
Epoch: 1716557137
Audit subid: 477

View File

@ -1,4 +0,0 @@
/home/ubuntu/apparmor/tests/regression/apparmor/net_inet_rcv {
network (receive) inet dgram ip=127.0.97.3 port=3456,
}

View File

@ -1 +0,0 @@
[321266.557863] audit: type=1400 audit(1716558411.518:583): apparmor="DENIED" operation="bind" class="net" profile="/home/ubuntu/apparmor/tests/regression/apparmor/net_inet_rcv" pid=23602 comm="net_inet_rcv" saddr=127.0.97.3 src=3456 family="inet" sock_type="dgram" protocol=17 requested="bind" denied="bind"

View File

@ -1,18 +0,0 @@
START
File: testcase_network_07.in
Event type: AA_RECORD_DENIED
Audit ID: 1716558411.518:583
Operation: bind
Mask: bind
Denied Mask: bind
Profile: /home/ubuntu/apparmor/tests/regression/apparmor/net_inet_rcv
Command: net_inet_rcv
PID: 23602
Network family: inet
Socket type: dgram
Protocol: udp
Local addr: 127.0.97.3
Local port: 3456
Class: net
Epoch: 1716558411
Audit subid: 583

Some files were not shown because too many files have changed in this diff Show More