diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml deleted file mode 100644 index 5c2233a2..00000000 --- a/.github/workflows/cifuzz.yml +++ /dev/null @@ -1,39 +0,0 @@ ---- -name: CIFuzz -on: - push: - branches: - - master - pull_request: - branches: - - master -jobs: - Fuzzing: - runs-on: ubuntu-latest - if: github.repository == 'SELinuxProject/selinux' - strategy: - fail-fast: false - matrix: - sanitizer: [address, undefined, memory] - steps: - - name: Build Fuzzers (${{ matrix.sanitizer }}) - id: build - uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master - with: - oss-fuzz-project-name: 'selinux' - dry-run: false - allowed-broken-targets-percentage: 0 - sanitizer: ${{ matrix.sanitizer }} - - name: Run Fuzzers (${{ matrix.sanitizer }}) - uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master - with: - oss-fuzz-project-name: 'selinux' - fuzz-seconds: 180 - dry-run: false - sanitizer: ${{ matrix.sanitizer }} - - name: Upload Crash - uses: actions/upload-artifact@v1 - if: failure() && steps.build.outcome == 'success' - with: - name: ${{ matrix.sanitizer }}-artifacts - path: ./out/artifacts diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml deleted file mode 100644 index ef4be8af..00000000 --- a/.github/workflows/run_tests.yml +++ /dev/null @@ -1,189 +0,0 @@ -name: Run tests - -on: [push, pull_request] - -jobs: - build: - - runs-on: ubuntu-latest - strategy: - matrix: - compiler: [gcc, clang] - python-ruby-version: - - {python: 3.9, ruby: 2.7} - - {python: 3.9, ruby: 2.7, other: test-flags-override} - - {python: 3.9, ruby: 2.7, other: test-debug} - - {python: 3.9, ruby: 2.7, other: linker-bfd} - - {python: 3.9, ruby: 2.7, other: linker-gold} - # Test several Python versions with the latest Ruby version - - {python: 3.8, ruby: 2.7} - - {python: 3.7, ruby: 2.7} - - {python: 3.6, ruby: 2.7} - - {python: 3.5, ruby: 2.7} - - {python: pypy3, ruby: 2.7} - # Test several Ruby versions with the latest Python version - - {python: 3.9, ruby: 2.6} - - {python: 3.9, ruby: 2.5} - exclude: - - compiler: clang - python-ruby-version: {python: 3.9, ruby: 2.7, other: linker-bfd} - - compiler: clang - python-ruby-version: {python: 3.9, ruby: 2.7, other: linker-gold} - - steps: - - uses: actions/checkout@v2 - - - name: Set up Python ${{ matrix.python-ruby-version.python }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-ruby-version.python }} - - - name: Set up Ruby ${{ matrix.python-ruby-version.ruby }} - uses: actions/setup-ruby@v1 - with: - ruby-version: ${{ matrix.python-ruby-version.ruby }} - - - name: Install dependencies - run: | - sudo apt-get update -qq - sudo apt-get install -qqy \ - bison \ - clang \ - flex \ - gawk \ - gettext \ - libaudit-dev \ - libcap-dev \ - libcap-ng-dev \ - libcunit1-dev \ - libdbus-glib-1-dev \ - libpcre3-dev \ - python3-dev \ - python-dev \ - ruby-dev \ - swig \ - xmlto - - pip install flake8 - - - name: Configure the environment - run: | - DESTDIR=/tmp/destdir - echo "PYTHON=python" >> $GITHUB_ENV - echo "RUBY=ruby" >> $GITHUB_ENV - echo "DESTDIR=$DESTDIR" >> $GITHUB_ENV - - CC=${{ matrix.compiler }} - if [ "${{ matrix.python-ruby-version.other }}" = "linker-bfd" ] ; then - CC="$CC -fuse-ld=bfd" - elif [ "${{ matrix.python-ruby-version.other }}" = "linker-gold" ] ; then - CC="$CC -fuse-ld=gold" - fi - echo "CC=$CC" >> $GITHUB_ENV - - EXPLICIT_MAKE_VARS= - if [ "${{ matrix.python-ruby-version.other }}" = "test-flags-override" ] ; then - # Test that overriding CFLAGS, LDFLAGS and other variables works fine - EXPLICIT_MAKE_VARS="CFLAGS=-I$DESTDIR/usr/include LDFLAGS=-L$DESTDIR/usr/lib LDLIBS= CPPFLAGS=" - elif [ "${{ matrix.python-ruby-version.other }}" = "test-debug" ] ; then - # Test hat debug build works fine - EXPLICIT_MAKE_VARS="DEBUG=1" - else - EXPLICIT_MAKE_VARS= - fi - echo "EXPLICIT_MAKE_VARS=${EXPLICIT_MAKE_VARS}" >> $GITHUB_ENV - - # Find files in order of pkgconf to be able to find Python.h - # For example with Python 3.5: - # * python is located at /opt/hostedtoolcache/Python/3.5.10/x64/bin/python - # * sys.prefix is /opt/hostedtoolcache/Python/3.5.10/x64 - # * Python.h is located at /opt/hostedtoolcache/Python/3.5.10/x64/include/python3.5m/Python.h - # * python-3.5.pc is located at /opt/hostedtoolcache/Python/3.5.10/x64/lib/pkgconfig/python-3.5.pc - PYTHON_SYS_PREFIX="$(python -c 'import sys;print(sys.prefix)')" - echo "PKG_CONFIG_PATH=${PYTHON_SYS_PREFIX}/lib/pkgconfig" >> $GITHUB_ENV - - if [ "${{ matrix.python-ruby-version.python }}" = "pypy3" ] ; then - # PyPy does not provide a config file for pkg-config - # libpypy-c.so is provided in bin/libpypy-c.so for PyPy and bin/libpypy3-c.so for PyPy3 - echo "PYINC=-I${PYTHON_SYS_PREFIX}/include" >> $GITHUB_ENV - echo "PYLIBS=-L${PYTHON_SYS_PREFIX}/bin -lpypy3-c" >> $GITHUB_ENV - fi - - # Display the final environment file, for debugging purpose - cat $GITHUB_ENV - - - name: Download and install refpolicy headers for sepolgen tests - run: | - curl --location --retry 10 -o refpolicy.tar.bz2 https://github.com/SELinuxProject/refpolicy/releases/download/RELEASE_2_20180701/refpolicy-2.20180701.tar.bz2 - tar -xvjf refpolicy.tar.bz2 - sed -e "s,^PREFIX :=.*,PREFIX := $DESTDIR/usr," -i refpolicy/support/Makefile.devel - sudo make -C refpolicy install-headers clean - sudo mkdir -p /etc/selinux - echo 'SELINUXTYPE=refpolicy' | sudo tee /etc/selinux/config - echo 'SELINUX_DEVEL_PATH = /usr/share/selinux/refpolicy' | sudo tee /etc/selinux/sepolgen.conf - sed -e "s,\"\(/usr/bin/[cs]\),\"$DESTDIR\1," -i python/sepolgen/src/sepolgen/module.py - rm -r refpolicy refpolicy.tar.bz2 - - - name: Display versions - run: | - echo "::group::Compiler ($CC):" - $CC --version - echo "::endgroup::" - echo "::group::Python ($(which "$PYTHON")):" - $PYTHON --version - echo "::endgroup::" - echo "::group::Ruby ($(which "$RUBY")):" - $RUBY --version - echo "::endgroup::" - - - name: Run tests - run: | - echo "::group::make install" - make -j$(nproc) install $EXPLICIT_MAKE_VARS -k - echo "::endgroup::" - echo "::group::make install-pywrap" - make -j$(nproc) install-pywrap $EXPLICIT_MAKE_VARS -k - echo "::endgroup::" - echo "::group::make install-rubywrap" - make -j$(nproc) install-rubywrap $EXPLICIT_MAKE_VARS -k - echo "::endgroup::" - - # Now that everything is installed, run "make all" to build everything which may have not been built - echo "::group::make all" - make -j$(nproc) all $EXPLICIT_MAKE_VARS -k - echo "::endgroup::" - - # Set up environment variables for the tests and show variables (to help debugging issues) - echo "::group::Environment variables" - . ./scripts/env_use_destdir - echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH" - echo "PATH=$PATH" - echo "PYTHONPATH=$PYTHONPATH" - echo "RUBYLIB=$RUBYLIB" - echo "::endgroup::" - - # Run tests - echo "::group::make test" - make test $EXPLICIT_MAKE_VARS - echo "::endgroup::" - - # Test Python and Ruby wrappers - echo "::group::Test Python and Ruby wrappers" - $PYTHON -c 'import selinux;import selinux.audit2why;import semanage;print(selinux.is_selinux_enabled())' - $RUBY -e 'require "selinux";require "semanage";puts Selinux::is_selinux_enabled()' - echo "::endgroup::" - - # Run Python linter, but not on the downloaded refpolicy - echo "::group::scripts/run-flake8" - ./scripts/run-flake8 - echo "::endgroup::" - - echo "::group::Test .gitignore and make clean distclean" - # Remove every installed files - rm -rf "$DESTDIR" - # Test that "git status" looks clean, or print a clear error message - git status --short | sed -n 's/^??/error: missing .gitignore entry for/p' | (! grep '^') - # Clean up everything and show which file needs to be added to "make clean" - make clean distclean $EXPLICIT_MAKE_VARS - git ls-files --ignored --others --exclude-standard | sed 's/^/error: "make clean distclean" did not remove /' | (! grep '^') - echo "::endgroup::" diff --git a/.github/workflows/vm_testsuite.yml b/.github/workflows/vm_testsuite.yml deleted file mode 100644 index af2fad1e..00000000 --- a/.github/workflows/vm_testsuite.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Run SELinux testsuite in a virtual machine - -on: [push, pull_request] - -jobs: - vm_testsuite: - - # Use VirtualBox+vagrant on macOS, as described in https://github.com/actions/virtual-environments/issues/433 - runs-on: macos-latest - - steps: - - uses: actions/checkout@v2 - - - name: Create Vagrant VM - run: | - cd scripts/ci - vagrant up - - - name: Run SELinux testsuite in the VM - run: | - cd scripts/ci - vagrant ssh -- ./run-selinux-test.sh diff --git a/.travis.yml b/.travis.yml index 1c2c7f33..918958ac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,164 @@ # Define the building environment language: c -# Use Travis-CI Ubuntu 18.04 Bionic Beaver, "full image" variant +matrix: + fast_finish: true + +compiler: + - clang + - gcc + +env: + matrix: + # Test the last version of Python and Ruby together, with some linkers + - PYVER=python3.7 RUBYLIBVER=2.6 + - PYVER=python3.7 RUBYLIBVER=2.6 TEST_FLAGS_OVERRIDE=1 + - PYVER=python3.7 RUBYLIBVER=2.6 TEST_DEBUG=1 + - PYVER=python3.7 RUBYLIBVER=2.6 LINKER=gold + - PYVER=python3.7 RUBYLIBVER=2.6 LINKER=bfd + + # Test several Python versions + - PYVER=python3.5 RUBYLIBVER=2.6 + - PYVER=python3.6 RUBYLIBVER=2.6 + - PYVER=pypy3.5-6.0 RUBYLIBVER=2.6 + + # Test several Ruby versions (http://rubies.travis-ci.org/) + - PYVER=python3.7 RUBYLIBVER=2.5.1 + - PYVER=python3.7 RUBYLIBVER=2.4 + - PYVER=python3.7 RUBYLIBVER=2.3 + - PYVER=python3.7 RUBYLIBVER=2.2 + +matrix: + exclude: + - compiler: clang + env: PYVER=python3.7 RUBYLIBVER=2.6 LINKER=gold + - compiler: clang + env: PYVER=python3.7 RUBYLIBVER=2.6 LINKER=bfd + +# Use Travis-CI Ubuntu 16.04 Xenial Xerus infrastructure, "full image" variant sudo: required -dist: bionic +dist: xenial + +# Install SELinux userspace utilities dependencies +addons: + apt: + packages: + - bison + - flex + - gawk + - gettext + - libaudit-dev + - libbz2-dev + - libcap-dev + - libcap-ng-dev # This package is not whitelisted for the container infrastructure (https://github.com/travis-ci/apt-package-whitelist/issues/1096) + - libcunit1-dev + - libdbus-glib-1-dev + - libncurses5-dev + - libpcre3-dev + - patch + - python3-dev + - python-dev + - swig + - xmlto + +install: + # Download and install refpolicy headers for sepolgen tests + - curl --location --retry 10 -o "$TRAVIS_BUILD_DIR/refpolicy.tar.bz2" https://github.com/SELinuxProject/refpolicy/releases/download/RELEASE_2_20180701/refpolicy-2.20180701.tar.bz2 + - tar -C "$TRAVIS_BUILD_DIR" -xvjf "$TRAVIS_BUILD_DIR/refpolicy.tar.bz2" + # Make refpolicy Makefile use the new toolchain when building modules + - sed -e "s,^PREFIX :=.*,PREFIX := \$(DESTDIR)/usr," -i "$TRAVIS_BUILD_DIR/refpolicy/support/Makefile.devel" + - sudo make -C "$TRAVIS_BUILD_DIR/refpolicy" install-headers + - sudo rm -rf "$TRAVIS_BUILD_DIR/refpolicy.tar.bz2" "$TRAVIS_BUILD_DIR/refpolicy" + - sudo mkdir -p /etc/selinux + - echo 'SELINUXTYPE=refpolicy' | sudo tee /etc/selinux/config + - echo 'SELINUX_DEVEL_PATH = /usr/share/selinux/refpolicy' | sudo tee /etc/selinux/sepolgen.conf + + # Make sepolgen tests work without really installing anything in the real root (doing this would conflict with Ubuntu packages) + - sed -e "s,\"\(/usr/bin/[cs]\),\"$TRAVIS_BUILD_DIR/installdir\1," -i python/sepolgen/src/sepolgen/module.py + + # Download the required python version if it is not installed + - VIRTUAL_ENV="$HOME/virtualenv/$PYVER" + - if ! [ -d "$VIRTUAL_ENV" ] ; then + curl --retry 10 -o python.tar.bz2 "https://s3.amazonaws.com/travis-python-archives/binaries/ubuntu/16.04/x86_64/${PYVER/python/python-}.tar.bz2" && + sudo tar xjf python.tar.bz2 --directory / && + rm python.tar.bz2 ; + fi + + # Install flake8 for the given python version + - $VIRTUAL_ENV/bin/pip install flake8 + +before_script: + # Build and install in a temporary directory to run tests + - export DESTDIR="$TRAVIS_BUILD_DIR/installdir" + + # Configure the variables for Python parts + - export VIRTUAL_ENV="$HOME/virtualenv/$PYVER" + - export PYTHON="$VIRTUAL_ENV/bin/python" + # Use the header files in /opt/python/... for Python because the virtualenvs do not provide Python.h + - export PKG_CONFIG_PATH="/opt/python/$($PYTHON -c 'import sys;print("%d.%d.%d" % sys.version_info[:3])')/lib/pkgconfig" + # PyPy does not provide a config file for pkg-config + # libpypy-c.so is provided in bin/libpypy-c.so for PyPy and bin/libpypy3-c.so for PyPy3 + - if echo "$PYVER" | grep -q pypy ; then + export PYINC=-I$($PYTHON -c 'import sys;print(sys.prefix)')/include ; + export PYLIBS="$($PYTHON -c 'import sys;print("-L%s/bin -l%s" % (sys.prefix, "pypy-c" if sys.version_info < (3,) else "pypy3-c"))')" ; + fi + + # Find the Ruby executable with version $RUBYLIBVER + - rvm reinstall ruby-$RUBYLIBVER --binary + - export RUBY="$(ls -d -1 "$HOME/.rvm/rubies/ruby-$RUBYLIBVER"*/bin/ruby | head -n 1)" + + # Set the linker in $CC so that it gets used everywhere + - if [ -n "$LINKER" ]; then CC="$CC -fuse-ld=$LINKER" ; fi + + # Show variables and versions (to help debugging) + - echo "$CC" ; $CC --version + - echo "$PYTHON" ; $PYTHON --version + - echo "$RUBY" ; $RUBY --version + + # If TEST_FLAGS_OVERRIDE is defined, test that overriding CFLAGS, LDFLAGS and other variables works fine + - if [ -n "$TEST_FLAGS_OVERRIDE" ]; then EXPLICIT_MAKE_VARS="CFLAGS=-I$DESTDIR/usr/include LDFLAGS=-L$DESTDIR/usr/lib LDLIBS= CPPFLAGS=" ; fi + # If TEST_DEBUG is defined, test that debug build works fine + - if [ -n "$TEST_DEBUG" ]; then EXPLICIT_MAKE_VARS="$EXPLICIT_MAKE_VARS DEBUG=1" ; fi script: - - FEDORA_MAJOR=33 FEDORA_MINOR=1.2 scripts/ci/travis-kvm-setup.sh + # Start by installing everything into $DESTDIR + - make install $EXPLICIT_MAKE_VARS -k + - make install-pywrap $EXPLICIT_MAKE_VARS -k + - make install-rubywrap $EXPLICIT_MAKE_VARS -k + + # Now that everything is installed, run "make all" to build everything which may have not been built + - make all $EXPLICIT_MAKE_VARS -k + + # Set up environment variables for the tests + - . ./scripts/env_use_destdir + + # Show variables (to help debugging issues) + - echo "$LD_LIBRARY_PATH" + - echo "$PATH" + - echo "$PYTHONPATH" + - echo "$RUBYLIB" + + # Run tests + - make test $EXPLICIT_MAKE_VARS + + # Test Python and Ruby wrappers + - $PYTHON -c 'import selinux;import selinux.audit2why;import semanage;print(selinux.is_selinux_enabled())' + - $RUBY -e 'require "selinux";require "semanage";puts Selinux::is_selinux_enabled()' + + # Run Python linter + - PATH="$VIRTUAL_ENV/bin:$PATH" ./scripts/run-flake8 + + # Remove every installed files + - rm -rf "$DESTDIR" + + # Test that "git status" looks clean, or print a clear error message + - |- + git status --short | sed -n 's/^??/error: missing .gitignore entry for/p' | (! grep '^') + + # Clean up everything and show which file would be added to "make clean" + - make clean distclean $EXPLICIT_MAKE_VARS + - |- + git ls-files --ignored --others --exclude-standard | sed 's/^/error: "make clean distclean" did not remove /' | (! grep '^') # Do not spam by email so long as the build succeeds notifications: diff --git a/README b/README new file mode 100644 index 00000000..e4423ca2 --- /dev/null +++ b/README @@ -0,0 +1,25 @@ +Please submit all bug reports and patches to selinux@vger.kernel.org. +Subscribe by sending "subscribe selinux" in the body of an email +to majordomo@vger.kernel.org. + +Build dependencies on Fedora: +yum install audit-libs-devel bison bzip2-devel dbus-devel dbus-glib-devel flex flex-devel flex-static glib2-devel libcap-devel libcap-ng-devel pam-devel pcre-devel python3-devel python3-setools swig xmlto redhat-rpm-config + +To build and install everything under a private directory, run: +make DESTDIR=~/obj install install-pywrap + +To install as the default system libraries and binaries +(overwriting any previously installed ones - dangerous!), +on x86_64, run: +make LIBDIR=/usr/lib64 SHLIBDIR=/lib64 install install-pywrap relabel +or on x86 (32-bit), run: +make install install-pywrap relabel + +This may render your system unusable if the upstream SELinux userspace +lacks library functions or other dependencies relied upon by your +distribution. If it breaks, you get to keep both pieces. + +To install libsepol on macOS (mainly for policy analysis): +cd libsepol; make PREFIX=/usr/local install + +This requires GNU coreutils (brew install coreutils). diff --git a/README.md b/README.md deleted file mode 100644 index d1338e87..00000000 --- a/README.md +++ /dev/null @@ -1,145 +0,0 @@ -SELinux Userspace -================= - -![SELinux logo](https://github.com/SELinuxProject.png) -[![Build Status](https://travis-ci.org/SELinuxProject/selinux.svg?branch=master)](https://travis-ci.org/SELinuxProject/selinux) -[![OSS-Fuzz Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/selinux.svg)](https://oss-fuzz-build-logs.storage.googleapis.com/index.html#selinux) -[![CIFuzz Status](https://github.com/SELinuxProject/selinux/actions/workflows/cifuzz.yml/badge.svg)](https://github.com/SELinuxProject/selinux/actions/workflows/cifuzz.yml) - -Please submit all bug reports and patches to . - -Subscribe by sending "subscribe selinux" in the body of an email -to . - -Archive of this mailing list is available on https://lore.kernel.org/selinux/. - - -Installation ------------- - -SELinux libraries and tools are packaged in several Linux distributions: - -* Alpine Linux (https://pkgs.alpinelinux.org/package/edge/testing/x86/policycoreutils) -* Arch Linux User Repository (https://aur.archlinux.org/packages/policycoreutils/) -* Buildroot (https://git.buildroot.net/buildroot/tree/package/policycoreutils) -* Debian and Ubuntu (https://packages.debian.org/sid/policycoreutils) -* Gentoo (https://packages.gentoo.org/packages/sys-apps/policycoreutils) -* RHEL and Fedora (https://src.fedoraproject.org/rpms/policycoreutils) -* Yocto Project (http://git.yoctoproject.org/cgit/cgit.cgi/meta-selinux/tree/recipes-security/selinux) -* and many more (https://repology.org/project/policycoreutils/versions) - - -Building and testing --------------------- - -Build dependencies on Fedora: - -```sh -# For C libraries and programs -dnf install \ - audit-libs-devel \ - bison \ - bzip2-devel \ - CUnit-devel \ - diffutils \ - flex \ - gcc \ - gettext \ - glib2-devel \ - make \ - libcap-devel \ - libcap-ng-devel \ - pam-devel \ - pcre-devel \ - xmlto - -# For Python and Ruby bindings -dnf install \ - python3-devel \ - ruby-devel \ - swig -``` - -Build dependencies on Debian: - -```sh -# For C libraries and programs -apt-get install --no-install-recommends --no-install-suggests \ - bison \ - flex \ - gawk \ - gcc \ - gettext \ - make \ - libaudit-dev \ - libbz2-dev \ - libcap-dev \ - libcap-ng-dev \ - libcunit1-dev \ - libglib2.0-dev \ - libpcre3-dev \ - pkgconf \ - python3 \ - python3-distutils \ - systemd \ - xmlto - -# For Python and Ruby bindings -apt-get install --no-install-recommends --no-install-suggests \ - python3-dev \ - ruby-dev \ - swig -``` - -To build and install everything under a private directory, run: - - make clean distclean - - make DESTDIR=~/obj install install-rubywrap install-pywrap - -On Debian `PYTHON_SETUP_ARGS=--install-layout=deb` needs to be set when installing the python wrappers in order to create the correct python directory structure. - -To run tests with the built libraries and programs, several paths (relative to `$DESTDIR`) need to be added to variables `$LD_LIBRARY_PATH`, `$PATH` and `$PYTHONPATH`. -This can be done using [./scripts/env_use_destdir](./scripts/env_use_destdir): - - DESTDIR=~/obj ./scripts/env_use_destdir make test - -Some tests require the reference policy to be installed (for example in `python/sepolgen`). -In order to run these ones, instructions similar to the ones in section `install` of [./.travis.yml](./.travis.yml) can be executed. - -To install as the default system libraries and binaries -(overwriting any previously installed ones - dangerous!), -on x86_64, run: - - make LIBDIR=/usr/lib64 SHLIBDIR=/lib64 install install-pywrap relabel - -or on x86 (32-bit), run: - - make install install-pywrap relabel - -This may render your system unusable if the upstream SELinux userspace -lacks library functions or other dependencies relied upon by your -distribution. If it breaks, you get to keep both pieces. - - -## Setting CFLAGS - -Setting CFLAGS during the make process will cause the omission of many defaults. While the project strives -to provide a reasonable set of default flags, custom CFLAGS could break the build, or have other undesired -changes on the build output. Thus, be very careful when setting CFLAGS. CFLAGS that are encouraged to be -set when overriding are: - -- -fno-semantic-interposition for gcc or compilers that do not do this. clang does this by default. clang-10 and up - will support passing this flag, but ignore it. Previous clang versions fail. - - -macOS ------ - -To install libsepol on macOS (mainly for policy analysis): - - cd libsepol; make PREFIX=/usr/local install - -This requires GNU coreutils: - - brew install coreutils diff --git a/VERSION b/VERSION deleted file mode 100644 index e6852d8a..00000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -3.3-rc1 diff --git a/checkpolicy/Makefile b/checkpolicy/Makefile index f9e1fc7c..0d282ef9 100644 --- a/checkpolicy/Makefile +++ b/checkpolicy/Makefile @@ -10,7 +10,7 @@ TARGETS = checkpolicy checkmodule LEX = flex YACC = bison -y -CFLAGS ?= -g -Wall -Werror -Wshadow -O2 -fno-strict-aliasing +CFLAGS ?= -g -Wall -Werror -Wshadow -O2 -pipe -fno-strict-aliasing # If no specific libsepol.a is specified, fall back on LDFLAGS search path # Otherwise, as $(LIBSEPOLA) already appears in the dependencies, there @@ -30,10 +30,10 @@ all: $(TARGETS) $(MAKE) -C test checkpolicy: $(CHECKPOLOBJS) $(LIBSEPOLA) - $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LDLIBS_LIBSEPOLA) + $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS_LIBSEPOLA) checkmodule: $(CHECKMODOBJS) $(LIBSEPOLA) - $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LDLIBS_LIBSEPOLA) + $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS_LIBSEPOLA) %.o: %.c $(CC) $(CFLAGS) -o $@ -c $< diff --git a/checkpolicy/VERSION b/checkpolicy/VERSION index e6852d8a..9f55b2cc 100644 --- a/checkpolicy/VERSION +++ b/checkpolicy/VERSION @@ -1 +1 @@ -3.3-rc1 +3.0 diff --git a/checkpolicy/checkmodule.8 b/checkpolicy/checkmodule.8 index c4b1592b..e597d9d4 100644 --- a/checkpolicy/checkmodule.8 +++ b/checkpolicy/checkmodule.8 @@ -28,9 +28,6 @@ module file. This option is a development/debugging aid. .B \-C,\-\-cil Write CIL policy file rather than binary policy file. .TP -.B \-E,\-\-werror -Treat warnings as errors -.TP .B \-h,\-\-help Print usage. .TP @@ -67,6 +64,6 @@ SELinux Reference Policy documentation at https://github.com/SELinuxProject/refp .SH AUTHOR This manual page was copied from the checkpolicy man page -written by Árpád Magosányi , +written by Arpad Magosanyi , and edited by Dan Walsh . The program was written by Stephen Smalley . diff --git a/checkpolicy/checkmodule.c b/checkpolicy/checkmodule.c index 316b2898..c9efaf8b 100644 --- a/checkpolicy/checkmodule.c +++ b/checkpolicy/checkmodule.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -40,7 +41,6 @@ extern int optind; static sidtab_t sidtab; extern int mlspol; -extern int werror; static int handle_unknown = SEPOL_DENY_UNKNOWN; static const char *txtfile = "policy.conf"; @@ -126,7 +126,7 @@ static int write_binary_policy(policydb_t * p, FILE *outfp) static __attribute__((__noreturn__)) void usage(const char *progname) { - printf("usage: %s [-h] [-V] [-b] [-C] [-E] [-U handle_unknown] [-m] [-M] [-o FILE] [INPUT]\n", progname); + printf("usage: %s [-h] [-V] [-b] [-C] [-U handle_unknown] [-m] [-M] [-o FILE] [INPUT]\n", progname); printf("Build base and policy modules.\n"); printf("Options:\n"); printf(" INPUT build module from INPUT (else read from \"%s\")\n", @@ -134,7 +134,6 @@ static __attribute__((__noreturn__)) void usage(const char *progname) printf(" -V show policy versions created by this program\n"); printf(" -b treat input as a binary policy file\n"); printf(" -C output CIL policy instead of binary policy\n"); - printf(" -E treat warnings as errors\n"); printf(" -h print usage\n"); printf(" -U OPTION How to handle unknown classes and permissions\n"); printf(" deny: Deny unknown kernel checks\n"); @@ -163,11 +162,10 @@ int main(int argc, char **argv) {"handle-unknown", required_argument, NULL, 'U'}, {"mls", no_argument, NULL, 'M'}, {"cil", no_argument, NULL, 'C'}, - {"werror", no_argument, NULL, 'E'}, {NULL, 0, NULL, 0} }; - while ((ch = getopt_long(argc, argv, "ho:bVEU:mMCc:", long_options, NULL)) != -1) { + while ((ch = getopt_long(argc, argv, "ho:bVU:mMCc:", long_options, NULL)) != -1) { switch (ch) { case 'h': usage(argv[0]); @@ -182,9 +180,6 @@ int main(int argc, char **argv) case 'V': show_version = 1; break; - case 'E': - werror = 1; - break; case 'U': if (!strcasecmp(optarg, "deny")) { handle_unknown = DENY_UNKNOWN; @@ -288,16 +283,14 @@ int main(int argc, char **argv) } if (policy_type != POLICY_BASE && outfile) { - char *out_name; - char *separator; char *mod_name = modpolicydb.name; char *out_path = strdup(outfile); if (out_path == NULL) { fprintf(stderr, "%s: out of memory\n", argv[0]); exit(1); } - out_name = basename(out_path); - separator = strrchr(out_name, '.'); + char *out_name = basename(out_path); + char *separator = strrchr(out_name, '.'); if (separator) { *separator = '\0'; } diff --git a/checkpolicy/checkpolicy.8 b/checkpolicy/checkpolicy.8 index f4e6fb24..97e10ca7 100644 --- a/checkpolicy/checkpolicy.8 +++ b/checkpolicy/checkpolicy.8 @@ -53,9 +53,6 @@ Specify the target platform (selinux or xen). .B \-O,\-\-optimize Optimize the final kernel policy (remove redundant rules). .TP -.B \-E,\-\-werror -Treat warnings as errors -.TP .B \-V,\-\-version Show version information. .TP @@ -67,6 +64,6 @@ SELinux Reference Policy documentation at https://github.com/SELinuxProject/refp .SH AUTHOR -This manual page was written by Árpád Magosányi , +This manual page was written by Arpad Magosanyi , and edited by Stephen Smalley . The program was written by Stephen Smalley . diff --git a/checkpolicy/checkpolicy.c b/checkpolicy/checkpolicy.c index e6cfd337..7c5b63f8 100644 --- a/checkpolicy/checkpolicy.c +++ b/checkpolicy/checkpolicy.c @@ -85,6 +85,7 @@ #include #include #include +#include #include #include @@ -100,33 +101,29 @@ static sidtab_t sidtab; extern policydb_t *policydbp; extern int mlspol; -extern int werror; static int handle_unknown = SEPOL_DENY_UNKNOWN; static const char *txtfile = "policy.conf"; static const char *binfile = "policy"; -unsigned int policyvers = 0; +unsigned int policyvers = POLICYDB_VERSION_MAX; static __attribute__((__noreturn__)) void usage(const char *progname) { printf ("usage: %s [-b[F]] [-C] [-d] [-U handle_unknown (allow,deny,reject)] [-M] " "[-c policyvers (%d-%d)] [-o output_file|-] [-S] " - "[-t target_platform (selinux,xen)] [-E] [-V] [input_file]\n", + "[-t target_platform (selinux,xen)] [-V] [input_file]\n", progname, POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX); exit(1); } #define FGETS(out, size, in) \ -do { \ - if (fgets(out,size,in)==NULL) { \ - fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__, \ - strerror(errno)); \ - exit(1);\ - } \ -} while (0) - +if (fgets(out,size,in)==NULL) { \ + fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__,\ + strerror(errno)); \ + exit(1);\ +} static int print_sid(sepol_security_id_t sid, context_struct_t * context __attribute__ ((unused)), void *data @@ -424,12 +421,11 @@ int main(int argc, char **argv) {"conf",no_argument, NULL, 'F'}, {"sort", no_argument, NULL, 'S'}, {"optimize", no_argument, NULL, 'O'}, - {"werror", no_argument, NULL, 'E'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0} }; - while ((ch = getopt_long(argc, argv, "o:t:dbU:MCFSVc:OEh", long_options, NULL)) != -1) { + while ((ch = getopt_long(argc, argv, "o:t:dbU:MCFSVc:Oh", long_options, NULL)) != -1) { switch (ch) { case 'o': outfile = optarg; @@ -504,12 +500,10 @@ int main(int argc, char **argv) usage(argv[0]); exit(1); } - policyvers = n; + if (policyvers != n) + policyvers = n; break; } - case 'E': - werror = 1; - break; case 'h': default: usage(argv[0]); @@ -517,8 +511,7 @@ int main(int argc, char **argv) } if (show_version) { - printf("%d (compatibility range %d-%d)\n", - policyvers ? policyvers : POLICYDB_VERSION_MAX , + printf("%d (compatibility range %d-%d)\n", policyvers, POLICYDB_VERSION_MAX, POLICYDB_VERSION_MIN); exit(0); } @@ -591,16 +584,6 @@ int main(int argc, char **argv) exit(1); } } - - if (policydbp->policyvers <= POLICYDB_VERSION_PERMISSIVE) { - if (policyvers > policydbp->policyvers) { - fprintf(stderr, "Binary policies with version <= %u cannot be upgraded\n", POLICYDB_VERSION_PERMISSIVE); - } else if (policyvers) { - policydbp->policyvers = policyvers; - } - } else { - policydbp->policyvers = policyvers ? policyvers : POLICYDB_VERSION_MAX; - } } else { if (conf) { fprintf(stderr, "Can only generate policy.conf from binary policy\n"); @@ -642,8 +625,6 @@ int main(int argc, char **argv) policydb_destroy(policydbp); policydbp = &policydb; } - - policydbp->policyvers = policyvers ? policyvers : POLICYDB_VERSION_MAX; } if (policydb_load_isids(&policydb, &sidtab)) @@ -669,6 +650,8 @@ int main(int argc, char **argv) } } + policydb.policyvers = policyvers; + if (!cil) { if (!conf) { policydb.policy_type = POLICY_KERN; @@ -970,12 +953,8 @@ int main(int argc, char **argv) printf("fs kdevname? "); FGETS(ans, sizeof(ans), stdin); ans[strlen(ans) - 1] = 0; - ret = sepol_fs_sid(ans, &ssid, &tsid); - if (ret) { - printf("unknown fs kdevname\n"); - } else { - printf("fs_sid %d default_file_sid %d\n", ssid, tsid); - } + sepol_fs_sid(ans, &ssid, &tsid); + printf("fs_sid %d default_file_sid %d\n", ssid, tsid); break; case '9': printf("protocol? "); @@ -1003,12 +982,8 @@ int main(int argc, char **argv) printf("netif name? "); FGETS(ans, sizeof(ans), stdin); ans[strlen(ans) - 1] = 0; - ret = sepol_netif_sid(ans, &ssid, &tsid); - if (ret) { - printf("unknown name\n"); - } else { - printf("if_sid %d default_msg_sid %d\n", ssid, tsid); - } + sepol_netif_sid(ans, &ssid, &tsid); + printf("if_sid %d default_msg_sid %d\n", ssid, tsid); break; case 'b':{ char *p; @@ -1187,6 +1162,8 @@ int main(int argc, char **argv) printf("\nNo such class.\n"); break; } + cladatum = + policydb.class_val_to_struct[tclass - 1]; } else { ans[strlen(ans) - 1] = 0; cladatum = @@ -1238,6 +1215,8 @@ int main(int argc, char **argv) printf("\nNo such class.\n"); break; } + cladatum = + policydb.class_val_to_struct[tclass - 1]; } else { ans[strlen(ans) - 1] = 0; cladatum = diff --git a/checkpolicy/parse_util.c b/checkpolicy/parse_util.c index 1795e93c..f2809b48 100644 --- a/checkpolicy/parse_util.c +++ b/checkpolicy/parse_util.c @@ -28,6 +28,7 @@ extern int yyparse(void); extern void yyrestart(FILE *); extern queue_t id_queue; extern unsigned int policydb_errors; +extern unsigned long policydb_lineno; extern policydb_t *policydbp; extern int mlspol; extern void set_source_file(const char *name); diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c index 75a67d5c..e295bc52 100644 --- a/checkpolicy/policy_define.c +++ b/checkpolicy/policy_define.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include "queue.h" @@ -77,7 +78,7 @@ extern int yyerror(const char *msg); #define ERRORMSG_LEN 255 static char errormsg[ERRORMSG_LEN + 1] = {0}; -static int id_has_dot(const char *id); +static int id_has_dot(char *id); static int parse_security_context(context_struct_t *c); /* initialize all of the state variables for the scanner/parser */ @@ -141,7 +142,7 @@ int insert_id(const char *id, int push) /* If the identifier has a dot within it and that its first character is not a dot then return 1, else return 0. */ -static int id_has_dot(const char *id) +static int id_has_dot(char *id) { if (strchr(id, '.') >= id + 1) { return 1; @@ -1168,6 +1169,11 @@ int expand_attrib(void) ebitmap_init(&attrs); while ((id = queue_remove(id_queue))) { + if (!id) { + yyerror("No attribute name for expandattribute statement?"); + goto exit; + } + if (!is_id_in_scope(SYM_TYPES, id)) { yyerror2("attribute %s is not within scope", id); goto exit; @@ -1796,7 +1802,7 @@ int define_bool_tunable(int is_tunable) return -1; } - datum->state = (bool_value[0] == 'T') ? 1 : 0; + datum->state = (int)(bool_value[0] == 'T') ? 1 : 0; free(bool_value); return 0; cleanup: @@ -1904,9 +1910,8 @@ int avrule_read_ioctls(struct av_ioctl_range_list **rangehead) { char *id; struct av_ioctl_range_list *rnew, *r = NULL; - uint8_t omit = 0; - *rangehead = NULL; + uint8_t omit = 0; /* read in all the ioctl commands */ while ((id = queue_remove(id_queue))) { @@ -1943,9 +1948,7 @@ int avrule_read_ioctls(struct av_ioctl_range_list **rangehead) } } r = *rangehead; - if (r) { - r->omit = omit; - } + r->omit = omit; return 0; error: yyerror("out of memory"); @@ -2145,7 +2148,7 @@ out: /* index of the u32 containing the permission */ #define XPERM_IDX(x) (x >> 5) /* set bits 0 through x-1 within the u32 */ -#define XPERM_SETBITS(x) ((1U << (x & 0x1f)) - 1) +#define XPERM_SETBITS(x) ((1 << (x & 0x1f)) - 1) /* low value for this u32 */ #define XPERM_LOW(x) (x << 5) /* high value for this u32 */ @@ -2172,7 +2175,7 @@ void avrule_xperm_setrangebits(uint16_t low, uint16_t high, } } -int avrule_xperms_used(const av_extended_perms_t *xperms) +int avrule_xperms_used(av_extended_perms_t *xperms) { unsigned int i; @@ -2347,7 +2350,7 @@ unsigned int xperms_for_each_bit(unsigned int *bit, av_extended_perms_t *xperms) return 0; } -int avrule_cpy(avrule_t *dest, const avrule_t *src) +int avrule_cpy(avrule_t *dest, avrule_t *src) { class_perm_node_t *src_perms; class_perm_node_t *dest_perms, *dest_tail; @@ -2395,7 +2398,7 @@ int avrule_cpy(avrule_t *dest, const avrule_t *src) return 0; } -int define_te_avtab_ioctl(const avrule_t *avrule_template) +int define_te_avtab_ioctl(avrule_t *avrule_template) { avrule_t *avrule; struct av_ioctl_range_list *rangelist; @@ -3301,6 +3304,8 @@ int define_filename_trans(void) ebitmap_t e_stypes, e_ttypes; ebitmap_t e_tclasses; ebitmap_node_t *snode, *tnode, *cnode; + filename_trans_t *ft; + filename_trans_datum_t *ftdatum; filename_trans_rule_t *ftr; type_datum_t *typdatum; uint32_t otype; @@ -3384,19 +3389,40 @@ int define_filename_trans(void) ebitmap_for_each_positive_bit(&e_tclasses, cnode, c) { ebitmap_for_each_positive_bit(&e_stypes, snode, s) { ebitmap_for_each_positive_bit(&e_ttypes, tnode, t) { - rc = policydb_filetrans_insert( - policydbp, s+1, t+1, c+1, name, - NULL, otype, NULL - ); - if (rc != SEPOL_OK) { - if (rc == SEPOL_EEXIST) { - yyerror2("duplicate filename transition for: filename_trans %s %s %s:%s", - name, - policydbp->p_type_val_to_name[s], - policydbp->p_type_val_to_name[t], - policydbp->p_class_val_to_name[c]); - goto bad; - } + ft = calloc(1, sizeof(*ft)); + if (!ft) { + yyerror("out of memory"); + goto bad; + } + ft->stype = s+1; + ft->ttype = t+1; + ft->tclass = c+1; + ft->name = strdup(name); + if (!ft->name) { + yyerror("out of memory"); + goto bad; + } + + ftdatum = hashtab_search(policydbp->filename_trans, + (hashtab_key_t)ft); + if (ftdatum) { + yyerror2("duplicate filename transition for: filename_trans %s %s %s:%s", + name, + policydbp->p_type_val_to_name[s], + policydbp->p_type_val_to_name[t], + policydbp->p_class_val_to_name[c]); + goto bad; + } + + ftdatum = calloc(1, sizeof(*ftdatum)); + if (!ftdatum) { + yyerror("out of memory"); + goto bad; + } + rc = hashtab_insert(policydbp->filename_trans, + (hashtab_key_t)ft, + ftdatum); + if (rc) { yyerror("out of memory"); goto bad; } @@ -3444,10 +3470,9 @@ bad: return -1; } -static constraint_expr_t *constraint_expr_clone(const constraint_expr_t * expr) +static constraint_expr_t *constraint_expr_clone(constraint_expr_t * expr) { - constraint_expr_t *h = NULL, *l = NULL, *newe; - const constraint_expr_t *e; + constraint_expr_t *h = NULL, *l = NULL, *e, *newe; for (e = expr; e; e = e->next) { newe = malloc(sizeof(*newe)); if (!newe) @@ -3478,7 +3503,12 @@ static constraint_expr_t *constraint_expr_clone(const constraint_expr_t * expr) return h; oom: - constraint_expr_destroy(h); + e = h; + while (e) { + l = e; + e = e->next; + constraint_expr_destroy(l); + } return NULL; } @@ -4087,6 +4117,8 @@ cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void *arg2) static int set_user_roles(role_set_t * set, char *id) { role_datum_t *r; + unsigned int i; + ebitmap_node_t *node; if (strcmp(id, "*") == 0) { free(id); @@ -4112,9 +4144,12 @@ static int set_user_roles(role_set_t * set, char *id) return -1; } + /* set the role and every role it dominates */ + ebitmap_for_each_positive_bit(&r->dominates, node, i) { + if (ebitmap_set_bit(&set->roles, i, TRUE)) + goto oom; + } free(id); - if (ebitmap_set_bit(&set->roles, r->s.value - 1, TRUE)) - goto oom; return 0; oom: yyerror("out of memory"); @@ -5474,9 +5509,7 @@ int define_genfs_context_helper(char *fstype, int has_type) { struct genfs *genfs_p, *genfs, *newgenfs; ocontext_t *newc, *c, *head, *p; - class_datum_t *cladatum; char *type = NULL; - const char *sclass; int len, len2; if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { @@ -5538,39 +5571,30 @@ int define_genfs_context_helper(char *fstype, int has_type) } switch (type[0]) { case 'b': - sclass = "blk_file"; + newc->v.sclass = SECCLASS_BLK_FILE; break; case 'c': - sclass = "chr_file"; + newc->v.sclass = SECCLASS_CHR_FILE; break; case 'd': - sclass = "dir"; + newc->v.sclass = SECCLASS_DIR; break; case 'p': - sclass = "fifo_file"; + newc->v.sclass = SECCLASS_FIFO_FILE; break; case 'l': - sclass = "lnk_file"; + newc->v.sclass = SECCLASS_LNK_FILE; break; case 's': - sclass = "sock_file"; + newc->v.sclass = SECCLASS_SOCK_FILE; break; case '-': - sclass = "file"; + newc->v.sclass = SECCLASS_FILE; break; default: yyerror2("invalid type %s", type); goto fail; } - - cladatum = hashtab_search(policydbp->p_classes.table, - sclass); - if (!cladatum) { - yyerror2("could not find class %s for " - "genfscon statement", sclass); - goto fail; - } - newc->v.sclass = cladatum->s.value; } if (parse_security_context(&newc->context[0])) goto fail; diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y index 6098eb50..abb7d885 100644 --- a/checkpolicy/policy_parse.y +++ b/checkpolicy/policy_parse.y @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include "queue.h" diff --git a/checkpolicy/policy_scan.l b/checkpolicy/policy_scan.l index 4067268b..e2f676e4 100644 --- a/checkpolicy/policy_scan.l +++ b/checkpolicy/policy_scan.l @@ -36,8 +36,6 @@ typedef int (* require_func_t)(void); static char linebuf[2][255]; static unsigned int lno = 0; -int werror = 0; -int yyerror(const char *msg); int yywarn(const char *msg); void set_source_file(const char *name); @@ -292,7 +290,7 @@ GLBLUB { return(GLBLUB); } "]" | "~" | "*" { return(yytext[0]); } -. { yyerror("unrecognized character");} +. { yywarn("unrecognized character");} %% int yyerror(const char *msg) { @@ -312,9 +310,6 @@ int yyerror(const char *msg) int yywarn(const char *msg) { - if (werror) - return yyerror(msg); - if (source_file[0]) fprintf(stderr, "%s:%ld:", source_file, source_lineno); diff --git a/checkpolicy/ru/checkmodule.8 b/checkpolicy/ru/checkmodule.8 index d7d3f65c..a1d687e3 100644 --- a/checkpolicy/ru/checkmodule.8 +++ b/checkpolicy/ru/checkmodule.8 @@ -50,7 +50,7 @@ $ checkmodule \-M \-m httpd.te \-o httpd.mod .SH АВТОРЫ -Эта страница руководства была скопирована со страницы руководства checkpolicy, написанной Árpád Magosányi , +Эта страница руководства была скопирована со страницы руководства checkpolicy, написанной Arpad Magosanyi , и отредактирована Dan Walsh . Программа была написана Stephen Smalley . -Перевод на русский язык выполнила Олеся Герасименко . +Перевод на русский язык выполнила Герасименко Олеся . diff --git a/checkpolicy/ru/checkpolicy.8 b/checkpolicy/ru/checkpolicy.8 index f08d1dc9..25b0e555 100644 --- a/checkpolicy/ru/checkpolicy.8 +++ b/checkpolicy/ru/checkpolicy.8 @@ -54,7 +54,7 @@ checkpolicy \- компилятор политики SELinux Документация SELinux Reference Policy по адресу https://github.com/SELinuxProject/refpolicy/wiki .SH АВТОРЫ -Эта страница руководства была написана Árpád Magosányi , +Эта страница руководства была написана Arpad Magosanyi , и отредактирована Stephen Smalley . Программа была написана Stephen Smalley . -Перевод на русский язык выполнила Олеся Герасименко . +Перевод на русский язык выполнила Герасименко Олеся . diff --git a/checkpolicy/test/Makefile b/checkpolicy/test/Makefile index 8e5d16b3..89e7557c 100644 --- a/checkpolicy/test/Makefile +++ b/checkpolicy/test/Makefile @@ -1,7 +1,7 @@ # # Makefile for building the dispol program # -CFLAGS ?= -g -Wall -W -Werror -O2 +CFLAGS ?= -g -Wall -W -Werror -O2 -pipe # If no specific libsepol.a is specified, fall back on LDFLAGS search path # Otherwise, as $(LIBSEPOLA) already appears in the dependencies, there @@ -13,10 +13,10 @@ endif all: dispol dismod dispol: dispol.o $(LIBSEPOLA) - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS_LIBSEPOLA) + $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS_LIBSEPOLA) dismod: dismod.o $(LIBSEPOLA) - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS_LIBSEPOLA) + $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS_LIBSEPOLA) clean: -rm -f dispol dismod *.o diff --git a/checkpolicy/test/dismod.c b/checkpolicy/test/dismod.c index 90c29318..41bde48f 100644 --- a/checkpolicy/test/dismod.c +++ b/checkpolicy/test/dismod.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -111,7 +112,7 @@ static void display_id(policydb_t * p, FILE * fp, uint32_t symbol_type, } } -static int display_type_set(type_set_t * set, uint32_t flags, policydb_t * policy, +int display_type_set(type_set_t * set, uint32_t flags, policydb_t * policy, FILE * fp) { unsigned int i, num_types; @@ -175,7 +176,7 @@ static int display_type_set(type_set_t * set, uint32_t flags, policydb_t * polic return 0; } -static int display_mod_role_set(role_set_t * roles, policydb_t * p, FILE * fp) +int display_mod_role_set(role_set_t * roles, policydb_t * p, FILE * fp) { unsigned int i, num = 0; @@ -210,7 +211,7 @@ static int display_mod_role_set(role_set_t * roles, policydb_t * p, FILE * fp) } -static int display_avrule(avrule_t * avrule, policydb_t * policy, +int display_avrule(avrule_t * avrule, policydb_t * policy, FILE * fp) { class_perm_node_t *cur; @@ -313,7 +314,7 @@ static int display_avrule(avrule_t * avrule, policydb_t * policy, return 0; } -static int display_type_callback(hashtab_key_t key, hashtab_datum_t datum, void *data) +int display_type_callback(hashtab_key_t key, hashtab_datum_t datum, void *data) { type_datum_t *type; FILE *fp; @@ -355,14 +356,14 @@ static int display_type_callback(hashtab_key_t key, hashtab_datum_t datum, void return 0; } -static int display_types(policydb_t * p, FILE * fp) +int display_types(policydb_t * p, FILE * fp) { if (hashtab_map(p->p_types.table, display_type_callback, fp)) return -1; return 0; } -static int display_users(policydb_t * p, FILE * fp) +int display_users(policydb_t * p, FILE * fp) { unsigned int i, j; ebitmap_t *bitmap; @@ -381,7 +382,7 @@ static int display_users(policydb_t * p, FILE * fp) return 0; } -static int display_bools(policydb_t * p, FILE * fp) +int display_bools(policydb_t * p, FILE * fp) { unsigned int i; @@ -392,7 +393,7 @@ static int display_bools(policydb_t * p, FILE * fp) return 0; } -static void display_expr(policydb_t * p, cond_expr_t * exp, FILE * fp) +void display_expr(policydb_t * p, cond_expr_t * exp, FILE * fp) { cond_expr_t *cur; @@ -427,14 +428,14 @@ static void display_expr(policydb_t * p, cond_expr_t * exp, FILE * fp) } } -static void display_policycon(FILE * fp) +void display_policycon(FILE * fp) { /* There was an attempt to implement this at one time. Look through * git history to find it. */ fprintf(fp, "Sorry, not implemented\n"); } -static void display_initial_sids(policydb_t * p, FILE * fp) +void display_initial_sids(policydb_t * p, FILE * fp) { ocontext_t *cur; char *user, *role, *type; @@ -459,7 +460,7 @@ static void display_initial_sids(policydb_t * p, FILE * fp) #endif } -static void display_class_set(ebitmap_t *classes, policydb_t *p, FILE *fp) +void display_class_set(ebitmap_t *classes, policydb_t *p, FILE *fp) { unsigned int i, num = 0; @@ -482,7 +483,7 @@ static void display_class_set(ebitmap_t *classes, policydb_t *p, FILE *fp) fprintf(fp, " }"); } -static void display_role_trans(role_trans_rule_t * tr, policydb_t * p, FILE * fp) +void display_role_trans(role_trans_rule_t * tr, policydb_t * p, FILE * fp) { for (; tr; tr = tr->next) { fprintf(fp, "role transition "); @@ -495,7 +496,7 @@ static void display_role_trans(role_trans_rule_t * tr, policydb_t * p, FILE * fp } } -static void display_role_allow(role_allow_rule_t * ra, policydb_t * p, FILE * fp) +void display_role_allow(role_allow_rule_t * ra, policydb_t * p, FILE * fp) { for (; ra; ra = ra->next) { fprintf(fp, "role allow "); @@ -517,7 +518,7 @@ static void display_filename_trans(filename_trans_rule_t * tr, policydb_t * p, F } } -static int role_display_callback(hashtab_key_t key __attribute__((unused)), +int role_display_callback(hashtab_key_t key __attribute__((unused)), hashtab_datum_t datum, void *data) { role_datum_t *role; @@ -611,7 +612,7 @@ int change_bool(char *name, int state, policydb_t * p, FILE * fp) } #endif -static int display_avdecl(avrule_decl_t * decl, int field, +int display_avdecl(avrule_decl_t * decl, int field, policydb_t * policy, FILE * out_fp) { fprintf(out_fp, "decl %u:%s\n", decl->decl_id, @@ -692,13 +693,13 @@ static int display_avdecl(avrule_decl_t * decl, int field, return 0; /* should never get here */ } -static int display_avblock(int field, policydb_t * policy, +int display_avblock(int field, policydb_t * policy, FILE * out_fp) { avrule_block_t *block = policydb.global; while (block != NULL) { - avrule_decl_t *decl = block->branch_list; fprintf(out_fp, "--- begin avrule block ---\n"); + avrule_decl_t *decl = block->branch_list; while (decl != NULL) { if (display_avdecl(decl, field, policy, out_fp)) { return -1; @@ -710,7 +711,7 @@ static int display_avblock(int field, policydb_t * policy, return 0; } -static int display_handle_unknown(policydb_t * p, FILE * out_fp) +int display_handle_unknown(policydb_t * p, FILE * out_fp) { if (p->handle_unknown == ALLOW_UNKNOWN) fprintf(out_fp, "Allow unknown classes and perms\n"); @@ -827,14 +828,14 @@ static void display_policycaps(policydb_t * p, FILE * fp) ebitmap_for_each_positive_bit(&p->policycaps, node, i) { capname = sepol_polcap_getname(i); if (capname == NULL) { - snprintf(buf, sizeof(buf), "unknown (%u)", i); + snprintf(buf, sizeof(buf), "unknown (%d)", i); capname = buf; } fprintf(fp, "\t%s\n", capname); } } -static int menu(void) +int menu(void) { printf("\nSelect a command:\n"); printf("1) display unconditional AVTAB\n"); diff --git a/checkpolicy/test/dispol.c b/checkpolicy/test/dispol.c index 8ddefb04..d72d9fb3 100644 --- a/checkpolicy/test/dispol.c +++ b/checkpolicy/test/dispol.c @@ -42,7 +42,7 @@ static __attribute__((__noreturn__)) void usage(const char *progname) exit(1); } -static int render_access_mask(uint32_t mask, avtab_key_t * key, policydb_t * p, +int render_access_mask(uint32_t mask, avtab_key_t * key, policydb_t * p, FILE * fp) { char *perm; @@ -54,13 +54,13 @@ static int render_access_mask(uint32_t mask, avtab_key_t * key, policydb_t * p, return 0; } -static int render_type(uint32_t type, policydb_t * p, FILE * fp) +int render_type(uint32_t type, policydb_t * p, FILE * fp) { fprintf(fp, "%s", p->p_type_val_to_name[type - 1]); return 0; } -static int render_key(avtab_key_t * key, policydb_t * p, FILE * fp) +int render_key(avtab_key_t * key, policydb_t * p, FILE * fp) { char *stype, *ttype, *tclass; stype = p->p_type_val_to_name[key->source_type - 1]; @@ -84,7 +84,7 @@ static int render_key(avtab_key_t * key, policydb_t * p, FILE * fp) #define RENDER_DISABLED 0x0004 #define RENDER_CONDITIONAL (RENDER_ENABLED|RENDER_DISABLED) -static int render_av_rule(avtab_key_t * key, avtab_datum_t * datum, uint32_t what, +int render_av_rule(avtab_key_t * key, avtab_datum_t * datum, uint32_t what, policydb_t * p, FILE * fp) { if (!(what & RENDER_UNCONDITIONAL)) { @@ -163,7 +163,7 @@ static int render_av_rule(avtab_key_t * key, avtab_datum_t * datum, uint32_t wha return 0; } -static int display_avtab(avtab_t * a, uint32_t what, policydb_t * p, FILE * fp) +int display_avtab(avtab_t * a, uint32_t what, policydb_t * p, FILE * fp) { unsigned int i; avtab_ptr_t cur; @@ -178,7 +178,7 @@ static int display_avtab(avtab_t * a, uint32_t what, policydb_t * p, FILE * fp) return 0; } -static int display_bools(policydb_t * p, FILE * fp) +int display_bools(policydb_t * p, FILE * fp) { unsigned int i; @@ -189,7 +189,7 @@ static int display_bools(policydb_t * p, FILE * fp) return 0; } -static void display_expr(policydb_t * p, cond_expr_t * exp, FILE * fp) +void display_expr(policydb_t * p, cond_expr_t * exp, FILE * fp) { cond_expr_t *cur; @@ -224,7 +224,7 @@ static void display_expr(policydb_t * p, cond_expr_t * exp, FILE * fp) } } -static int display_cond_expressions(policydb_t * p, FILE * fp) +int display_cond_expressions(policydb_t * p, FILE * fp) { cond_node_t *cur; cond_av_list_t *av_cur; @@ -249,7 +249,7 @@ static int display_cond_expressions(policydb_t * p, FILE * fp) return 0; } -static int display_handle_unknown(policydb_t * p, FILE * out_fp) +int display_handle_unknown(policydb_t * p, FILE * out_fp) { if (p->handle_unknown == ALLOW_UNKNOWN) fprintf(out_fp, "Allow unknown classes and permissions\n"); @@ -260,7 +260,7 @@ static int display_handle_unknown(policydb_t * p, FILE * out_fp) return 0; } -static int change_bool(char *name, int state, policydb_t * p, FILE * fp) +int change_bool(char *name, int state, policydb_t * p, FILE * fp) { cond_bool_datum_t *bool; @@ -285,7 +285,7 @@ static void display_policycaps(policydb_t * p, FILE * fp) ebitmap_for_each_positive_bit(&p->policycaps, node, i) { capname = sepol_polcap_getname(i); if (capname == NULL) { - snprintf(buf, sizeof(buf), "unknown (%u)", i); + snprintf(buf, sizeof(buf), "unknown (%d)", i); capname = buf; } fprintf(fp, "\t%s\n", capname); @@ -335,25 +335,17 @@ static int filenametr_display(hashtab_key_t key, hashtab_datum_t datum, void *ptr) { - struct filename_trans_key *ft = (struct filename_trans_key *)key; + struct filename_trans *ft = (struct filename_trans *)key; struct filename_trans_datum *ftdatum = datum; struct filenametr_display_args *args = ptr; policydb_t *p = args->p; FILE *fp = args->fp; - ebitmap_node_t *node; - uint32_t bit; - - do { - ebitmap_for_each_positive_bit(&ftdatum->stypes, node, bit) { - display_id(p, fp, SYM_TYPES, bit, ""); - display_id(p, fp, SYM_TYPES, ft->ttype - 1, ""); - display_id(p, fp, SYM_CLASSES, ft->tclass - 1, ":"); - display_id(p, fp, SYM_TYPES, ftdatum->otype - 1, ""); - fprintf(fp, " %s\n", ft->name); - } - ftdatum = ftdatum->next; - } while (ftdatum); + display_id(p, fp, SYM_TYPES, ft->stype - 1, ""); + display_id(p, fp, SYM_TYPES, ft->ttype - 1, ""); + display_id(p, fp, SYM_CLASSES, ft->tclass - 1, ":"); + display_id(p, fp, SYM_TYPES, ftdatum->otype - 1, ""); + fprintf(fp, " %s\n", ft->name); return 0; } @@ -368,7 +360,7 @@ static void display_filename_trans(policydb_t *p, FILE *fp) hashtab_map(p->filename_trans, filenametr_display, &args); } -static int menu(void) +int menu(void) { printf("\nSelect a command:\n"); printf("1) display unconditional AVTAB\n"); diff --git a/dbus/VERSION b/dbus/VERSION index e6852d8a..9f55b2cc 100644 --- a/dbus/VERSION +++ b/dbus/VERSION @@ -1 +1 @@ -3.3-rc1 +3.0 diff --git a/dbus/selinux_server.py b/dbus/selinux_server.py index a969f226..be4f4557 100644 --- a/dbus/selinux_server.py +++ b/dbus/selinux_server.py @@ -2,36 +2,28 @@ import dbus import dbus.service -from dbus.mainloop.glib import DBusGMainLoop +import dbus.mainloop.glib from gi.repository import GObject -from gi.repository import GLib +import slip.dbus.service +from slip.dbus import polkit import os import selinux from subprocess import Popen, PIPE, STDOUT -class selinux_server(dbus.service.Object): +class selinux_server(slip.dbus.service.Object): default_polkit_auth_required = "org.selinux.semanage" def __init__(self, *p, **k): super(selinux_server, self).__init__(*p, **k) - def is_authorized(self, sender, action_id): - bus = dbus.SystemBus() - proxy = bus.get_object('org.freedesktop.PolicyKit1', '/org/freedesktop/PolicyKit1/Authority') - authority = dbus.Interface(proxy, dbus_interface='org.freedesktop.PolicyKit1.Authority') - subject = ('system-bus-name', {'name': sender}) - result = authority.CheckAuthorization(subject, action_id, {}, 1, '') - return result[0] - # # The semanage method runs a transaction on a series of semanage commands, # these commands can take the output of customized # - @dbus.service.method("org.selinux", in_signature='s', sender_keyword="sender") - def semanage(self, buf, sender): - if not self.is_authorized(sender, "org.selinux.semanage"): - raise dbus.exceptions.DBusException("Not authorized") + @slip.dbus.polkit.require_auth("org.selinux.semanage") + @dbus.service.method("org.selinux", in_signature='s') + def semanage(self, buf): p = Popen(["/usr/sbin/semanage", "import"], stdout=PIPE, stderr=PIPE, stdin=PIPE, universal_newlines=True) p.stdin.write(buf) output = p.communicate() @@ -43,10 +35,9 @@ class selinux_server(dbus.service.Object): # on the server. This output can be used with the semanage method on # another server to make the two systems have duplicate policy. # - @dbus.service.method("org.selinux", in_signature='', out_signature='s', sender_keyword="sender") - def customized(self, sender): - if not self.is_authorized(sender, "org.selinux.customized"): - raise dbus.exceptions.DBusException("Not authorized") + @slip.dbus.polkit.require_auth("org.selinux.customized") + @dbus.service.method("org.selinux", in_signature='', out_signature='s') + def customized(self): p = Popen(["/usr/sbin/semanage", "export"], stdout=PIPE, stderr=PIPE, universal_newlines=True) buf = p.stdout.read() output = p.communicate() @@ -58,10 +49,9 @@ class selinux_server(dbus.service.Object): # The semodule_list method will return the output of semodule --list=full, using the customized polkit, # since this is a readonly behaviour # - @dbus.service.method("org.selinux", in_signature='', out_signature='s', sender_keyword="sender") - def semodule_list(self, sender): - if not self.is_authorized(sender, "org.selinux.semodule_list"): - raise dbus.exceptions.DBusException("Not authorized") + @slip.dbus.polkit.require_auth("org.selinux.semodule_list") + @dbus.service.method("org.selinux", in_signature='', out_signature='s') + def semodule_list(self): p = Popen(["/usr/sbin/semodule", "--list=full"], stdout=PIPE, stderr=PIPE, universal_newlines=True) buf = p.stdout.read() output = p.communicate() @@ -72,28 +62,25 @@ class selinux_server(dbus.service.Object): # # The restorecon method modifies any file path to the default system label # - @dbus.service.method("org.selinux", in_signature='s', sender_keyword="sender") - def restorecon(self, path, sender): - if not self.is_authorized(sender, "org.selinux.restorecon"): - raise dbus.exceptions.DBusException("Not authorized") + @slip.dbus.polkit.require_auth("org.selinux.restorecon") + @dbus.service.method("org.selinux", in_signature='s') + def restorecon(self, path): selinux.restorecon(str(path), recursive=1) # # The setenforce method turns off the current enforcement of SELinux # - @dbus.service.method("org.selinux", in_signature='i', sender_keyword="sender") - def setenforce(self, value, sender): - if not self.is_authorized(sender, "org.selinux.setenforce"): - raise dbus.exceptions.DBusException("Not authorized") + @slip.dbus.polkit.require_auth("org.selinux.setenforce") + @dbus.service.method("org.selinux", in_signature='i') + def setenforce(self, value): selinux.security_setenforce(value) # # The setenforce method turns off the current enforcement of SELinux # - @dbus.service.method("org.selinux", in_signature='i', sender_keyword="sender") - def relabel_on_boot(self, value, sender): - if not self.is_authorized(sender, "org.selinux.relabel_on_boot"): - raise dbus.exceptions.DBusException("Not authorized") + @slip.dbus.polkit.require_auth("org.selinux.relabel_on_boot") + @dbus.service.method("org.selinux", in_signature='i') + def relabel_on_boot(self, value): if value == 1: fd = open("/.autorelabel", "w") fd.close() @@ -124,10 +111,9 @@ class selinux_server(dbus.service.Object): # # The change_default_enforcement modifies the current enforcement mode # - @dbus.service.method("org.selinux", in_signature='s', sender_keyword="sender") - def change_default_mode(self, value, sender): - if not self.is_authorized(sender, "org.selinux.change_default_mode"): - raise dbus.exceptions.DBusException("Not authorized") + @slip.dbus.polkit.require_auth("org.selinux.change_default_mode") + @dbus.service.method("org.selinux", in_signature='s') + def change_default_mode(self, value): values = ["enforcing", "permissive", "disabled"] if value not in values: raise ValueError("Enforcement mode must be %s" % ", ".join(values)) @@ -136,20 +122,19 @@ class selinux_server(dbus.service.Object): # # The change_default_policy method modifies the policy type # - @dbus.service.method("org.selinux", in_signature='s', sender_keyword="sender") - def change_default_policy(self, value, sender): - if not self.is_authorized(sender, "org.selinux.change_default_policy"): - raise dbus.exceptions.DBusException("Not authorized") + @slip.dbus.polkit.require_auth("org.selinux.change_default_policy") + @dbus.service.method("org.selinux", in_signature='s') + def change_default_policy(self, value): path = selinux.selinux_path() + value if os.path.isdir(path): return self.write_selinux_config(policy=value) raise ValueError("%s does not exist" % path) if __name__ == "__main__": - DBusGMainLoop(set_as_default=True) - mainloop = GLib.MainLoop() - + mainloop = GObject.MainLoop() + dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) system_bus = dbus.SystemBus() name = dbus.service.BusName("org.selinux", system_bus) - server = selinux_server(system_bus, "/org/selinux/object") + object = selinux_server(system_bus, "/org/selinux/object") + slip.dbus.service.set_mainloop(mainloop) mainloop.run() diff --git a/gui/VERSION b/gui/VERSION index e6852d8a..9f55b2cc 100644 --- a/gui/VERSION +++ b/gui/VERSION @@ -1 +1 @@ -3.3-rc1 +3.0 diff --git a/gui/fcontextPage.py b/gui/fcontextPage.py index d26aa1b4..370bbee4 100644 --- a/gui/fcontextPage.py +++ b/gui/fcontextPage.py @@ -102,13 +102,6 @@ class fcontextPage(semanagePage): self.load() self.fcontextEntry = xml.get_object("fcontextEntry") self.fcontextFileTypeCombo = xml.get_object("fcontextFileTypeCombo") - # Populate file type combo_box - liststore = self.fcontextFileTypeCombo.get_model() - for ftype in seobject.file_type_str_to_option.keys(): - iter = liststore.append() - liststore.set_value(iter, 0, ftype) - iter = liststore.get_iter_first() - self.fcontextFileTypeCombo.set_active_iter(iter) self.fcontextTypeEntry = xml.get_object("fcontextTypeEntry") self.fcontextMLSEntry = xml.get_object("fcontextMLSEntry") diff --git a/gui/system-config-selinux.ui b/gui/system-config-selinux.ui index e7b84a64..7cc1cc53 100644 --- a/gui/system-config-selinux.ui +++ b/gui/system-config-selinux.ui @@ -401,6 +401,32 @@ Level + + + all files + + + regular file + + + directory + + + character device + + + block device + + + socket file + + + symbolic link + + + named pipe + + False diff --git a/libselinux/Makefile b/libselinux/Makefile index 439bc6a9..16531fe9 100644 --- a/libselinux/Makefile +++ b/libselinux/Makefile @@ -1,10 +1,9 @@ -SUBDIRS = include src utils man +SUBDIRS = src include utils man PKG_CONFIG ?= pkg-config DISABLE_SETRANS ?= n DISABLE_RPM ?= n ANDROID_HOST ?= n -LABEL_BACKEND_ANDROID ?= n ifeq ($(ANDROID_HOST),y) override DISABLE_SETRANS=y override DISABLE_BOOL=y @@ -18,10 +17,7 @@ endif ifeq ($(DISABLE_BOOL),y) DISABLE_FLAGS+= -DDISABLE_BOOL endif -ifeq ($(DISABLE_X11),y) - DISABLE_FLAGS+= -DNO_X_BACKEND -endif -export DISABLE_SETRANS DISABLE_RPM DISABLE_FLAGS ANDROID_HOST DISABLE_X11 LABEL_BACKEND_ANDROID +export DISABLE_SETRANS DISABLE_RPM DISABLE_FLAGS ANDROID_HOST USE_PCRE2 ?= n ifeq ($(USE_PCRE2),y) @@ -50,24 +46,24 @@ all install relabel clean distclean indent: done swigify: all - $(MAKE) -C src $@ + $(MAKE) -C src swigify $@ pywrap: - $(MAKE) -C src $@ + $(MAKE) -C src pywrap $@ rubywrap: - $(MAKE) -C src $@ + $(MAKE) -C src rubywrap $@ install-pywrap: - $(MAKE) -C src $@ + $(MAKE) -C src install-pywrap $@ install-rubywrap: - $(MAKE) -C src $@ + $(MAKE) -C src install-rubywrap $@ clean-pywrap: - $(MAKE) -C src $@ + $(MAKE) -C src clean-pywrap $@ clean-rubywrap: - $(MAKE) -C src $@ + $(MAKE) -C src clean-rubywrap $@ test: diff --git a/libselinux/VERSION b/libselinux/VERSION index e6852d8a..9f55b2cc 100644 --- a/libselinux/VERSION +++ b/libselinux/VERSION @@ -1 +1 @@ -3.3-rc1 +3.0 diff --git a/libselinux/include/selinux/avc.h b/libselinux/include/selinux/avc.h index 9b23357a..46c51419 100644 --- a/libselinux/include/selinux/avc.h +++ b/libselinux/include/selinux/avc.h @@ -64,11 +64,7 @@ extern int avc_context_to_sid_raw(const char * ctx, security_id_t * sid); * reference count). Note that avc_context_to_sid() also * increments reference counts. */ -extern int sidget(security_id_t sid) -#ifdef __GNUC__ -__attribute__ ((deprecated)) -#endif -; +extern int sidget(security_id_t sid); /** * sidput - decrement SID reference counter. @@ -80,11 +76,7 @@ __attribute__ ((deprecated)) * zero, the SID is invalid, and avc_context_to_sid() must * be called to obtain a new SID for the security context. */ -extern int sidput(security_id_t sid) -#ifdef __GNUC__ -__attribute__ ((deprecated)) -#endif -; +extern int sidput(security_id_t sid); /** * avc_get_initial_sid - get SID for an initial kernel security identifier @@ -200,11 +192,7 @@ extern int avc_init(const char *msgprefix, const struct avc_memory_callback *mem_callbacks, const struct avc_log_callback *log_callbacks, const struct avc_thread_callback *thread_callbacks, - const struct avc_lock_callback *lock_callbacks) -#ifdef __GNUC__ - __attribute__ ((deprecated("Use avc_open and selinux_set_callback"))) -#endif -; + const struct avc_lock_callback *lock_callbacks); /** * avc_open - Initialize the AVC. diff --git a/libselinux/include/selinux/get_context_list.h b/libselinux/include/selinux/get_context_list.h index 6b2f14f3..db8641a4 100644 --- a/libselinux/include/selinux/get_context_list.h +++ b/libselinux/include/selinux/get_context_list.h @@ -17,14 +17,14 @@ extern "C" { If 'fromcon' is NULL, defaults to current context. Caller must free via freeconary. */ extern int get_ordered_context_list(const char *user, - const char *fromcon, + char * fromcon, char *** list); /* As above, but use the provided MLS level rather than the default level for the user. */ extern int get_ordered_context_list_with_level(const char *user, const char *level, - const char *fromcon, + char * fromcon, char *** list); /* Get the default security context for a user session for 'user' @@ -35,14 +35,14 @@ extern "C" { Returns 0 on success or -1 otherwise. Caller must free via freecon. */ extern int get_default_context(const char *user, - const char *fromcon, + char * fromcon, char ** newcon); /* As above, but use the provided MLS level rather than the default level for the user. */ extern int get_default_context_with_level(const char *user, const char *level, - const char *fromcon, + char * fromcon, char ** newcon); /* Same as get_default_context, but only return a context @@ -50,7 +50,7 @@ extern "C" { for the user with that role, then return -1. */ extern int get_default_context_with_role(const char *user, const char *role, - const char *fromcon, + char * fromcon, char ** newcon); /* Same as get_default_context, but only return a context @@ -59,7 +59,7 @@ extern "C" { extern int get_default_context_with_rolelevel(const char *user, const char *role, const char *level, - const char *fromcon, + char * fromcon, char ** newcon); /* Given a list of authorized security contexts for the user, diff --git a/libselinux/include/selinux/restorecon.h b/libselinux/include/selinux/restorecon.h index 466de39a..754b8645 100644 --- a/libselinux/include/selinux/restorecon.h +++ b/libselinux/include/selinux/restorecon.h @@ -30,82 +30,77 @@ extern int selinux_restorecon(const char *pathname, * Force the checking of labels even if the stored SHA1 digest * matches the specfiles SHA1 digest (requires CAP_SYS_ADMIN). */ -#define SELINUX_RESTORECON_IGNORE_DIGEST 0x00001 +#define SELINUX_RESTORECON_IGNORE_DIGEST 0x0001 /* * Do not change file labels. */ -#define SELINUX_RESTORECON_NOCHANGE 0x00002 +#define SELINUX_RESTORECON_NOCHANGE 0x0002 /* * If set, change file label to that in spec file. * If not, only change type component to that in spec file. */ -#define SELINUX_RESTORECON_SET_SPECFILE_CTX 0x00004 +#define SELINUX_RESTORECON_SET_SPECFILE_CTX 0x0004 /* * Recursively descend directories. */ -#define SELINUX_RESTORECON_RECURSE 0x00008 +#define SELINUX_RESTORECON_RECURSE 0x0008 /* * Log changes to selinux log. Note that if VERBOSE and * PROGRESS are set, then PROGRESS will take precedence. */ -#define SELINUX_RESTORECON_VERBOSE 0x00010 +#define SELINUX_RESTORECON_VERBOSE 0x0010 /* * If SELINUX_RESTORECON_PROGRESS is true and * SELINUX_RESTORECON_MASS_RELABEL is true, then output approx % complete, * else output the number of files in 1k blocks processed to stdout. */ -#define SELINUX_RESTORECON_PROGRESS 0x00020 +#define SELINUX_RESTORECON_PROGRESS 0x0020 /* * Convert passed-in pathname to canonical pathname. */ -#define SELINUX_RESTORECON_REALPATH 0x00040 +#define SELINUX_RESTORECON_REALPATH 0x0040 /* * Prevent descending into directories that have a different * device number than the pathname from which the descent began. */ -#define SELINUX_RESTORECON_XDEV 0x00080 +#define SELINUX_RESTORECON_XDEV 0x0080 /* * Attempt to add an association between an inode and a specification. * If there is already an association for the inode and it conflicts * with the specification, then use the last matching specification. */ -#define SELINUX_RESTORECON_ADD_ASSOC 0x00100 +#define SELINUX_RESTORECON_ADD_ASSOC 0x0100 /* * Abort on errors during the file tree walk. */ -#define SELINUX_RESTORECON_ABORT_ON_ERROR 0x00200 +#define SELINUX_RESTORECON_ABORT_ON_ERROR 0x0200 /* * Log any label changes to syslog. */ -#define SELINUX_RESTORECON_SYSLOG_CHANGES 0x00400 +#define SELINUX_RESTORECON_SYSLOG_CHANGES 0x0400 /* * Log what spec matched each file. */ -#define SELINUX_RESTORECON_LOG_MATCHES 0x00800 +#define SELINUX_RESTORECON_LOG_MATCHES 0x0800 /* * Ignore files that do not exist. */ -#define SELINUX_RESTORECON_IGNORE_NOENTRY 0x01000 +#define SELINUX_RESTORECON_IGNORE_NOENTRY 0x1000 /* * Do not read /proc/mounts to obtain a list of non-seclabel * mounts to be excluded from relabeling checks. */ -#define SELINUX_RESTORECON_IGNORE_MOUNTS 0x02000 +#define SELINUX_RESTORECON_IGNORE_MOUNTS 0x2000 /* * Set if there is a mass relabel required. * See SELINUX_RESTORECON_PROGRESS flag for details. */ -#define SELINUX_RESTORECON_MASS_RELABEL 0x04000 +#define SELINUX_RESTORECON_MASS_RELABEL 0x4000 /* * Set if no digest is to be read or written (as only processes * running with CAP_SYS_ADMIN can read/write digests). */ -#define SELINUX_RESTORECON_SKIP_DIGEST 0x08000 - -/* - * Set to treat conflicting specifications as errors. - */ -#define SELINUX_RESTORECON_CONFLICT_ERROR 0x10000 +#define SELINUX_RESTORECON_SKIP_DIGEST 0x8000 /** * selinux_restorecon_set_sehandle - Set the global fc handle. diff --git a/libselinux/include/selinux/selinux.h b/libselinux/include/selinux/selinux.h index ae98a92e..7922d96b 100644 --- a/libselinux/include/selinux/selinux.h +++ b/libselinux/include/selinux/selinux.h @@ -8,17 +8,13 @@ extern "C" { #endif -/* Return 1 if we are running on a SELinux kernel, or 0 otherwise. */ +/* Return 1 if we are running on a SELinux kernel, or 0 if not or -1 if we get an error. */ extern int is_selinux_enabled(void); /* Return 1 if we are running on a SELinux MLS kernel, or 0 otherwise. */ extern int is_selinux_mls_enabled(void); /* No longer used; here for compatibility with legacy callers. */ -typedef char *security_context_t -#ifdef __GNUC__ -__attribute__ ((deprecated)) -#endif -; +typedef char *security_context_t; /* Free the memory allocated for a context by any of the below get* calls. */ extern void freecon(char * con); @@ -182,8 +178,6 @@ extern void selinux_set_callback(int type, union selinux_callback cb); #define SELINUX_WARNING 1 #define SELINUX_INFO 2 #define SELINUX_AVC 3 -#define SELINUX_POLICYLOAD 4 -#define SELINUX_SETENFORCE 5 #define SELINUX_TRANS_DIR "/var/run/setrans" /* Compute an access decision. */ @@ -252,12 +246,8 @@ extern int security_compute_member_raw(const char * scon, security_class_t tclass, char ** newcon); -/* - * Compute the set of reachable user contexts and set *con to refer to - * the NULL-terminated array of contexts. Caller must free via freeconary. - * These interfaces are deprecated. Use get_ordered_context_list() or - * one of its variant interfaces instead. - */ +/* Compute the set of reachable user contexts and set *con to refer to + the NULL-terminated array of contexts. Caller must free via freeconary. */ extern int security_compute_user(const char * scon, const char *username, char *** con); @@ -329,13 +319,9 @@ extern int security_set_boolean_list(size_t boolcnt, SELboolean * boollist, int permanent); /* Load policy boolean settings. Deprecated as local policy booleans no - * longer supported. Will always return -1. + * longer supported. Will always return 0. */ -extern int security_load_booleans(char *path) -#ifdef __GNUC__ -__attribute__ ((deprecated)) -#endif -; +extern int security_load_booleans(char *path); /* Check the validity of a security context. */ extern int security_check_context(const char * con); @@ -471,22 +457,14 @@ extern void set_matchpathcon_flags(unsigned int flags); function also checks for a 'path'.homedirs file and a 'path'.local file and loads additional specifications from them if present. */ -extern int matchpathcon_init(const char *path) -#ifdef __GNUC__ - __attribute__ ((deprecated("Use selabel_open with backend SELABEL_CTX_FILE"))) -#endif -; +extern int matchpathcon_init(const char *path); /* Same as matchpathcon_init, but only load entries with regexes that have stems that are prefixes of 'prefix'. */ extern int matchpathcon_init_prefix(const char *path, const char *prefix); /* Free the memory allocated by matchpathcon_init. */ -extern void matchpathcon_fini(void) -#ifdef __GNUC__ - __attribute__ ((deprecated("Use selabel_close"))) -#endif -; +extern void matchpathcon_fini(void); /* Resolve all of the symlinks and relative portions of a pathname, but NOT * the final component (same a realpath() unless the final component is a @@ -500,11 +478,7 @@ extern int realpath_not_final(const char *name, char *resolved_path); If matchpathcon_init has not already been called, then this function will call it upon its first invocation with a NULL path. */ extern int matchpathcon(const char *path, - mode_t mode, char ** con) -#ifdef __GNUC__ - __attribute__ ((deprecated("Use selabel_lookup instead"))) -#endif -; + mode_t mode, char ** con); /* Same as above, but return a specification index for later use in a matchpathcon_filespec_add() call - see below. */ @@ -597,18 +571,10 @@ extern const char *selinux_contexts_path(void); extern const char *selinux_securetty_types_path(void); extern const char *selinux_booleans_subs_path(void); /* Deprecated as local policy booleans no longer supported. */ -extern const char *selinux_booleans_path(void) -#ifdef __GNUC__ -__attribute__ ((deprecated)) -#endif -; +extern const char *selinux_booleans_path(void); extern const char *selinux_customizable_types_path(void); /* Deprecated as policy ./users no longer supported. */ -extern const char *selinux_users_path(void) -#ifdef __GNUC__ -__attribute__ ((deprecated)) -#endif -; +extern const char *selinux_users_path(void); extern const char *selinux_usersconf_path(void); extern const char *selinux_translations_path(void); extern const char *selinux_colors_path(void); @@ -636,17 +602,8 @@ extern int selinux_check_access(const char * scon, const char * tcon, const char /* Check a permission in the passwd class. Return 0 if granted or -1 otherwise. */ -extern int selinux_check_passwd_access(access_vector_t requested) -#ifdef __GNUC__ - __attribute__ ((deprecated("Use selinux_check_access"))) -#endif -; - -extern int checkPasswdAccess(access_vector_t requested) -#ifdef __GNUC__ - __attribute__ ((deprecated("Use selinux_check_access"))) -#endif -; +extern int selinux_check_passwd_access(access_vector_t requested); +extern int checkPasswdAccess(access_vector_t requested); /* Check if the tty_context is defined as a securetty Return 0 if secure, < 0 otherwise. */ @@ -672,11 +629,7 @@ extern int setexecfilecon(const char *filename, const char *fallback_type); /* Execute a helper for rpm in an appropriate security context. */ extern int rpm_execcon(unsigned int verified, const char *filename, - char *const argv[], char *const envp[]) -#ifdef __GNUC__ - __attribute__((deprecated("Use setexecfilecon and execve"))) -#endif -; + char *const argv[], char *const envp[]); #endif /* Returns whether a file context is customizable, and should not diff --git a/libselinux/man/man3/avc_init.3 b/libselinux/man/man3/avc_init.3 index a5dc7c93..e26c3be6 100644 --- a/libselinux/man/man3/avc_init.3 +++ b/libselinux/man/man3/avc_init.3 @@ -117,8 +117,6 @@ argument, which does not return under normal conditions. The callback should cancel the running thread referenced by .IR thread . By default, threading is not used; see -.B KERNEL STATUS PAGE -and .B NETLINK NOTIFICATION below. @@ -155,49 +153,14 @@ callback should destroy .IR lock , freeing any resources associated with it. The default behavior is not to perform any locking. Note that undefined behavior may result if threading is used without appropriate locking. . -.SH "KERNEL STATUS PAGE" -Linux kernel version 2.6.37 supports the SELinux kernel status page, enabling userspace applications to -.BR mmap (2) -SELinux status state in read-only mode to avoid system calls during the cache hit code path. - -.BR avc_init () -calls -.BR selinux_status_open (3) -to initialize the selinux status state. If successfully initialized, the userspace AVC will default to single-threaded mode and ignore the -.B func_create_thread -and -.B func_stop_thread -callbacks. All callbacks set via -.BR selinux_set_callback (3) -will still be honored. - -.BR avc_has_perm (3) -and -.BR selinux_check_access (3) -both check for status updates through calls to -.BR selinux_status_updated (3) -at the start of each permission query and take the appropriate action. - -Two status types are currently implemented. -.B setenforce -events will change the effective enforcing state used within the AVC, and -.B policyload -events will result in a cache flush. -. .SH "NETLINK NOTIFICATION" -In the event that the kernel status page is not successfully -.BR mmap (2)'ed -the AVC will default to the netlink fallback mechanism, which opens a netlink socket for receiving status updates. -.B setenforce -and -.B policyload -events will have the same results as for the status page implementation, but all status update checks will now require a system call. +Beginning with version 2.6.4, the Linux kernel supports SELinux status change notification via netlink. Two message types are currently implemented, indicating changes to the enforcing mode and to the loaded policy in the kernel, respectively. The userspace AVC listens for these messages and takes the appropriate action, modifying the behavior of +.BR avc_has_perm (3) +to reflect the current enforcing mode and flushing the cache on receipt of a policy load notification. Audit messages are produced when netlink notifications are processed. -By default, -.BR avc_open (3) -does not set threading or locking callbacks. In the fallback case, the userspace AVC checks for new netlink messages at the start of each permission query. If threading and locking callbacks are passed to -.BR avc_init (), -a dedicated thread will be started to listen on the netlink socket. This may increase performance in the absence of the status page and will ensure that log messages are generated immediately rather than at the time of the next permission query. +In the default single-threaded mode, the userspace AVC checks for new netlink messages at the start of each permission query. If threading and locking callbacks are passed to +.BR avc_init () +however, a dedicated thread will be started to listen on the netlink socket. This may increase performance and will ensure that log messages are generated immediately rather than at the time of the next permission query. . .SH "RETURN VALUE" Functions with a return value return zero on success. On error, \-1 is returned and @@ -229,7 +192,5 @@ Eamon Walsh . .SH "SEE ALSO" .BR avc_open (3), -.BR selinux_status_open (3), -.BR selinux_status_updated (3), .BR selinux_set_callback (3), .BR selinux (8) diff --git a/libselinux/man/man3/avc_netlink_loop.3 b/libselinux/man/man3/avc_netlink_loop.3 index f03d7813..c8268a12 100644 --- a/libselinux/man/man3/avc_netlink_loop.3 +++ b/libselinux/man/man3/avc_netlink_loop.3 @@ -54,11 +54,6 @@ closes the netlink socket. This function is called automatically by returns the netlink socket descriptor number and informs the userspace AVC not to check the socket descriptor automatically on calls to .BR avc_has_perm (3). -If no such socket descriptor exists, -.BR avc_netlink_acquire_fd (3) -will first call -.BR avc_netlink_open (3) -and then return the resulting fd. .BR avc_netlink_release_fd () returns control of the netlink socket to the userspace AVC, re-enabling @@ -83,9 +78,6 @@ with a return value return zero on success. On error, \-1 is returned and .I errno is set appropriately. . -.SH "AUTHOR" -Originally KaiGai Kohei. Updated by Mike Palmiotto -. .SH "SEE ALSO" .BR avc_open (3), .BR selinux_set_callback (3), diff --git a/libselinux/man/man3/avc_open.3 b/libselinux/man/man3/avc_open.3 index 55683bb6..5b275a8e 100644 --- a/libselinux/man/man3/avc_open.3 +++ b/libselinux/man/man3/avc_open.3 @@ -26,9 +26,6 @@ initializes the userspace AVC and must be called before any other AVC operation destroys the userspace AVC, freeing all internal memory structures. After this call has been made, .BR avc_open () must be called again before any AVC operations can be performed. -.BR avc_destroy () -also closes the SELinux status page, which might have been opened manually by -.BR selinux_status_open (3). .BR avc_reset () flushes the userspace AVC, causing it to forget any cached access decisions. The userspace AVC normally calls this function automatically when needed, see @@ -49,37 +46,10 @@ include the following: .B AVC_OPT_SETENFORCE This option forces the userspace AVC into enforcing mode if the option value is non-NULL; permissive mode otherwise. The system enforcing mode will be ignored. . -.SH "KERNEL STATUS PAGE" -Linux kernel version 2.6.37 supports the SELinux kernel status page, enabling userspace applications to -.BR mmap (2) -SELinux status state in read-only mode to avoid system calls during the cache hit code path. - -.BR avc_open () -calls -.BR selinux_status_open (3) -to initialize the selinux status state. - -.BR avc_has_perm (3) -and -.BR selinux_check_access (3) -both check for status updates through calls to -.BR selinux_status_updated (3) -at the start of each permission query and take the appropriate action. - -Two status types are currently implemented. -.B setenforce -events will change the effective enforcing state used within the AVC, and -.B policyload -events will result in a cache flush. -. .SH "NETLINK NOTIFICATION" -In the event that the kernel status page is not successfully -.BR mmap (2)'ed -the AVC will default to the netlink fallback mechanism, which opens a netlink socket for receiving status updates. -.B setenforce -and -.B policyload -events will have the same results as for the status page implementation, but all status update checks will now require a system call. +Beginning with version 2.6.4, the Linux kernel supports SELinux status change notification via netlink. Two message types are currently implemented, indicating changes to the enforcing mode and to the loaded policy in the kernel, respectively. The userspace AVC listens for these messages and takes the appropriate action, modifying the behavior of +.BR avc_has_perm (3) +to reflect the current enforcing mode and flushing the cache on receipt of a policy load notification. Audit messages are produced when netlink notifications are processed. . .SH "RETURN VALUE" Functions with a return value return zero on success. On error, \-1 is returned and @@ -91,12 +61,9 @@ Eamon Walsh . .SH "SEE ALSO" .BR selinux (8), -.BR selinux_check_access (3), .BR avc_has_perm (3), .BR avc_context_to_sid (3), .BR avc_cache_stats (3), .BR avc_add_callback (3), -.BR selinux_status_open (3), -.BR selinux_status_updated (3), .BR selinux_set_callback (3), .BR security_compute_av (3) diff --git a/libselinux/man/man3/get_ordered_context_list.3 b/libselinux/man/man3/get_ordered_context_list.3 index 2a1e08f0..e084da40 100644 --- a/libselinux/man/man3/get_ordered_context_list.3 +++ b/libselinux/man/man3/get_ordered_context_list.3 @@ -7,17 +7,17 @@ get_ordered_context_list, get_ordered_context_list_with_level, get_default_conte .br .B #include .sp -.BI "int get_ordered_context_list(const char *" user ", const char *" fromcon ", char ***" list ); +.BI "int get_ordered_context_list(const char *" user ", char *" fromcon ", char ***" list ); .sp -.BI "int get_ordered_context_list_with_level(const char *" user ", const char *" level ", const char *" fromcon ", char ***" list ); +.BI "int get_ordered_context_list_with_level(const char *" user ", const char *" level ", char *" fromcon ", char ***" list ); .sp -.BI "int get_default_context(const char *" user ", const char *" fromcon ", char **" newcon ); +.BI "int get_default_context(const char *" user ", char *" fromcon ", char **" newcon ); .sp -.BI "int get_default_context_with_level(const char *" user ", const char *" level ", const char *" fromcon ", char **" newcon ); +.BI "int get_default_context_with_level(const char *" user ", const char *" level ", char *" fromcon ", char **" newcon ); .sp -.BI "int get_default_context_with_role(const char *" user ", const char *" role ", const char *" fromcon ", char **" newcon "); +.BI "int get_default_context_with_role(const char *" user ", const char *" role ", char *" fromcon ", char **" newcon "); .sp -.BI "int get_default_context_with_rolelevel(const char *" user ", const char *" role ", const char *" level ", const char *" fromcon ", char **" newcon "); +.BI "int get_default_context_with_rolelevel(const char *" user ", const char *" role ", const char *" level ", char *" fromcon ", char **" newcon "); .sp .BI "int query_user_context(char **" list ", char **" newcon ); .sp @@ -26,28 +26,14 @@ get_ordered_context_list, get_ordered_context_list_with_level, get_default_conte .BI "int get_default_type(const char *" role ", char **" type ); . .SH "DESCRIPTION" - -This family of functions can be used to obtain either a prioritized list of -all reachable security contexts for a given SELinux user or a single default -(highest priority) context for a given SELinux user for use by login-like -programs. These functions takes a SELinux user identity that must -be defined in the SELinux policy as their input, not a Linux username. -Most callers should typically first call -.BR getseuserbyname(3) -to look up the SELinux user identity and level for a given -Linux username and then invoke one of -.BR get_ordered_context_list_with_level () -or -.BR get_default_context_with_level () -with the returned SELinux user and level as inputs. - .BR get_ordered_context_list () -obtains the list of contexts for the specified -SELinux +invokes the +.BR security_compute_user (3) +function to obtain the list of contexts for the specified .I user -identity that are reachable from the specified +that are reachable from the specified .I fromcon -context based on the global +context. The function then orders the resulting list based on the global .I \%/etc/selinux/{SELINUXTYPE}/contexts/default_contexts file and the per-user .I \%/etc/selinux/{SELINUXTYPE}/contexts/users/ diff --git a/libselinux/man/man3/getcon.3 b/libselinux/man/man3/getcon.3 index e7e394f3..67872a4d 100644 --- a/libselinux/man/man3/getcon.3 +++ b/libselinux/man/man3/getcon.3 @@ -7,7 +7,7 @@ freecon, freeconary \- free memory associated with SELinux security contexts getpeercon \- get security context of a peer socket setcon \- set current security context of a process - +. .SH "SYNOPSIS" .B #include .sp @@ -31,39 +31,30 @@ setcon \- set current security context of a process .sp .BI "void freeconary(char **" con ); .sp -.BI "int setcon(const char *" context ); +.BI "int setcon(char *" context ); .sp -.BI "int setcon_raw(const char *" context ); - +.BI "int setcon_raw(char *" context ); +. .SH "DESCRIPTION" -.TP .BR getcon () retrieves the context of the current process, which must be free'd with -.BR freecon (). +freecon. -.TP .BR getprevcon () same as getcon but gets the context before the last exec. -.TP .BR getpidcon () -returns the process context for the specified PID, which must be free'd with -.BR freecon (). +returns the process context for the specified PID. -.TP .BR getpeercon () -retrieves the context of the peer socket, which must be free'd with +retrieves context of peer socket, and set +.BI * context +to refer to it, which must be free'd with .BR freecon (). -.TP .BR freecon () frees the memory allocated for a security context. -If -.I con -is NULL, no operation is performed. - -.TP .BR freeconary () frees the memory allocated for a context array. @@ -71,7 +62,6 @@ If .I con is NULL, no operation is performed. -.TP .BR setcon () sets the current security context of the process to a new value. Note that use of this function requires that the entire application be @@ -120,8 +110,6 @@ context and the .BR setcon () will fail if it is not allowed by policy. -.TP -.BR *_raw() .BR getcon_raw (), .BR getprevcon_raw (), .BR getpidcon_raw (), @@ -130,14 +118,9 @@ and .BR setcon_raw () behave identically to their non-raw counterparts but do not perform context translation. - +. .SH "RETURN VALUE" -On error \-1 is returned with errno set. On success 0 is returned. - -.SH "NOTES" -The retrieval functions might return success and set -.I *context -to NULL if and only if SELinux is not enabled. - +On error \-1 is returned. On success 0 is returned. +. .SH "SEE ALSO" .BR selinux "(8), " setexeccon "(3)" diff --git a/libselinux/man/man3/is_selinux_enabled.3 b/libselinux/man/man3/is_selinux_enabled.3 index a887b48c..df62c225 100644 --- a/libselinux/man/man3/is_selinux_enabled.3 +++ b/libselinux/man/man3/is_selinux_enabled.3 @@ -15,6 +15,7 @@ is_selinux_mls_enabled \- check whether SELinux is enabled for (Multi Level Secu .SH "DESCRIPTION" .BR is_selinux_enabled () returns 1 if SELinux is running or 0 if it is not. +On error, \-1 is returned. .BR is_selinux_mls_enabled () returns 1 if SELinux is capable of running in MLS mode or 0 if it is not. To diff --git a/libselinux/man/man3/security_check_context.3 b/libselinux/man/man3/security_check_context.3 index 213ac282..2b9a2d4c 100644 --- a/libselinux/man/man3/security_check_context.3 +++ b/libselinux/man/man3/security_check_context.3 @@ -5,9 +5,9 @@ security_check_context \- check the validity of a SELinux context .SH "SYNOPSIS" .B #include .sp -.BI "int security_check_context(const char *" con ); +.BI "int security_check_context(char *" con ); .sp -.BI "int security_check_context_raw(const char *" con ); +.BI "int security_check_context_raw(char *" con ); . .SH "DESCRIPTION" .BR security_check_context () diff --git a/libselinux/man/man3/security_compute_av.3 b/libselinux/man/man3/security_compute_av.3 index efa4baf3..3de1b0fe 100644 --- a/libselinux/man/man3/security_compute_av.3 +++ b/libselinux/man/man3/security_compute_av.3 @@ -134,9 +134,8 @@ instance. .BR security_compute_user () is used to determine the set of user contexts that can be reached from a -source context. This function is deprecated; use -.BR get_ordered_context_list (3) -instead. +source context. It is mainly used by +.BR get_ordered_context_list (3). .BR security_validatetrans () is used to determine if a transition from scon to newcon using tcon as the object diff --git a/libselinux/man/man3/selinux_restorecon.3 b/libselinux/man/man3/selinux_restorecon.3 index ad637406..f6e5f2d7 100644 --- a/libselinux/man/man3/selinux_restorecon.3 +++ b/libselinux/man/man3/selinux_restorecon.3 @@ -152,10 +152,6 @@ Setting .B SELINUX_RESTORECON_IGNORE_MOUNTS is useful where there is a non-seclabel fs mounted with a seclabel fs mounted on a directory below this. -.sp -.B SELINUX_RESTORECON_CONFLICT_ERROR -to treat conflicting specifications, such as where two hardlinks for the -same inode have different contexts, as errors. .RE .sp The behavior regarding the checking and updating of the SHA1 digest described diff --git a/libselinux/man/man3/selinux_set_callback.3 b/libselinux/man/man3/selinux_set_callback.3 index 75f49b06..a4c613ad 100644 --- a/libselinux/man/man3/selinux_set_callback.3 +++ b/libselinux/man/man3/selinux_set_callback.3 @@ -46,20 +46,6 @@ argument indicates the type of message and will be set to one of the following: .B SELINUX_INFO .B SELINUX_AVC - -.B SELINUX_POLICYLOAD - -.B SELINUX_SETENFORCE - -SELINUX_ERROR, SELINUX_WARNING, and SELINUX_INFO indicate standard log severity -levels and are not auditable messages. - -The SELINUX_AVC, SELINUX_POLICYLOAD, and SELINUX_SETENFORCE message types can be -audited with AUDIT_USER_AVC, AUDIT_USER_MAC_POLICY_LOAD, and AUDIT_USER_MAC_STATUS -values from libaudit, respectively. If they are not audited, SELINUX_AVC should be -considered equivalent to SELINUX_ERROR; similarly, SELINUX_POLICYLOAD and -SELINUX_SETENFORCE should be considered equivalent to SELINUX_INFO. - . .TP .B SELINUX_CB_AUDIT diff --git a/libselinux/man/man3/selinux_status_open.3 b/libselinux/man/man3/selinux_status_open.3 index 5c9da2f6..2d44be57 100644 --- a/libselinux/man/man3/selinux_status_open.3 +++ b/libselinux/man/man3/selinux_status_open.3 @@ -48,7 +48,7 @@ Set 1 on the argument to handle a case of older kernels without kernel status page support. In this case, this function tries to open a netlink socket using .BR avc_netlink_open (3) -and overwrite corresponding callbacks (setenforce and policyload). +and overwrite corresponding callbacks ( setenforce and policyload). Thus, we need to pay attention to the interaction with these interfaces, when fallback mode is enabled. .sp @@ -57,14 +57,9 @@ unmap the kernel status page and close its file descriptor, or close the netlink socket if fallbacked. .sp .BR selinux_status_updated () -processes status update events. There are two kinds of status updates. -.B setenforce -events will change the effective enforcing state used within the AVC, and -.B policyload -events will result in a cache flush. - -This function returns 0 if there have been no updates since the last call, -1 if there have been updates since the last call, or \-1 on error. +informs us whether something has been updated since the last call. +It returns 0 if nothing was happened, however, 1 if something has been +updated in this duration, or \-1 on error. .sp .BR selinux_status_getenforce () returns 0 if SELinux is running in permissive mode, 1 if enforcing mode, diff --git a/libselinux/man/man5/selabel_file.5 b/libselinux/man/man5/selabel_file.5 index baba7776..e97bd826 100644 --- a/libselinux/man/man5/selabel_file.5 +++ b/libselinux/man/man5/selabel_file.5 @@ -125,14 +125,7 @@ Where: .RS .I pathname .RS -An entry that defines the path to be labeled. -May contain either a fully qualified path, -or a Perl compatible regular expression (PCRE), -describing fully qualified path(s). -The only PCRE flag in use is PCRE2_DOTALL, -which causes a wildcard '.' to match anything, including a new line. -Strings representing paths are processed as bytes (as opposed to Unicode), -meaning that non-ASCII characters are not matched by a single wildcard. +An entry that defines the pathname that may be in the form of a regular expression. .RE .I file_type .RS diff --git a/libselinux/man/man8/selinux.8 b/libselinux/man/man8/selinux.8 index 5842150b..31364271 100644 --- a/libselinux/man/man8/selinux.8 +++ b/libselinux/man/man8/selinux.8 @@ -19,36 +19,18 @@ enabled or disabled, and if enabled, whether SELinux operates in permissive mode or enforcing mode. The .B SELINUX variable may be set to -any one of \fIdisabled\fR, \fIpermissive\fR, or \fIenforcing\fR to -select one of these options. The \fIdisabled\fR disables most of the -SELinux kernel and application code, leaving the system -running without any SELinux protection. The \fIpermissive\fR option -enables the SELinux code, but causes it to operate in a mode where -accesses that would be denied by policy are permitted but audited. The -\fIenforcing\fR option enables the SELinux code and causes it to enforce -access denials as well as auditing them. \fIpermissive\fR mode may -yield a different set of denials than enforcing mode, both because -enforcing mode will prevent an operation from proceeding past the first -denial and because some application code will fall back to a less -privileged mode of operation if denied access. - -.B NOTE: -Disabling SELinux by setting -.B SELINUX=disabled -in -.I /etc/selinux/config -is deprecated and depending on kernel version and configuration it might -not lead to SELinux being completely disabled. Specifically, the -SELinux hooks will still be executed internally, but the SELinux policy -will not be loaded and no operation will be denied. In such state, the -system will act as if SELinux was disabled, although some operations -might behave slightly differently. To properly disable SELinux, it is -recommended to use the -.B selinux=0 -kernel boot option instead. In that case SELinux will be disabled -regardless of what is set in the -.I /etc/selinux/config -file. +any one of disabled, permissive, or enforcing to select one of these +options. The disabled option completely disables the SELinux kernel +and application code, leaving the system running without any SELinux +protection. The permissive option enables the SELinux code, but +causes it to operate in a mode where accesses that would be denied by +policy are permitted but audited. The enforcing option enables the +SELinux code and causes it to enforce access denials as well as +auditing them. Permissive mode may yield a different set of denials +than enforcing mode, both because enforcing mode will prevent an +operation from proceeding past the first denial and because some +application code will fall back to a less privileged mode of operation +if denied access. The .I /etc/selinux/config @@ -94,13 +76,6 @@ and reboot. also has this capability. The .BR restorecon / fixfiles commands are also available for relabeling files. - -Please note that using mount flag -.I nosuid -also disables SELinux domain transitions, unless permission -.I nosuid_transition -is used in the policy to allow this, which in turn needs also policy capability -.IR nnp_nosuid_transition . . .SH AUTHOR This manual page was written by Dan Walsh . diff --git a/libselinux/man/ru/man5/failsafe_context.5 b/libselinux/man/ru/man5/failsafe_context.5 index 54cecf39..01d6b0ea 100644 --- a/libselinux/man/ru/man5/failsafe_context.5 +++ b/libselinux/man/ru/man5/failsafe_context.5 @@ -1,6 +1,6 @@ .TH "failsafe_context" "5" "28 ноября 2011" "Security Enhanced Linux" "Конфигурация SELinux" .SH "ИМЯ" -failsafe_context \- файл конфигурации резервного контекста SELinux +failsafe_context \- файл конфигурации надёжного контекста SELinux . .SH "ОПИСАНИЕ" Файл @@ -10,7 +10,7 @@ failsafe_context \- файл конфигурации резервного ко получать известный действительный контекст входа для администратора, если в других расположениях отсутствуют действительные записи по умолчанию. .sp .BR selinux_failsafe_context_path "(3) " -возвращает путь активной политики к этому файлу. Файл резервного контекста по умолчанию: +возвращает путь активной политики к этому файлу. Файл надёжного контекста по умолчанию: .RS .I /etc/selinux/{SELINUXTYPE}/contexts/failsafe_context .RE diff --git a/libselinux/src/Makefile b/libselinux/src/Makefile index 52c40f01..7f5a5d74 100644 --- a/libselinux/src/Makefile +++ b/libselinux/src/Makefile @@ -15,7 +15,7 @@ INCLUDEDIR ?= $(PREFIX)/include PYINC ?= $(shell $(PKG_CONFIG) --cflags $(PYPREFIX)) PYLIBS ?= $(shell $(PKG_CONFIG) --libs $(PYPREFIX)) PYTHONLIBDIR ?= $(shell $(PYTHON) -c "from distutils.sysconfig import *; print(get_python_lib(plat_specific=1, prefix='$(PREFIX)'))") -PYCEXT ?= $(shell $(PYTHON) -c 'import importlib.machinery;print(importlib.machinery.EXTENSION_SUFFIXES[0])') +PYCEXT ?= $(shell $(PYTHON) -c 'import imp;print([s for s,m,t in imp.get_suffixes() if t == imp.C_EXTENSION][0])') RUBYINC ?= $(shell $(RUBY) -e 'puts "-I" + RbConfig::CONFIG["rubyarchhdrdir"] + " -I" + RbConfig::CONFIG["rubyhdrdir"]') RUBYLIBS ?= $(shell $(RUBY) -e 'puts "-L" + RbConfig::CONFIG["libdir"] + " -L" + RbConfig::CONFIG["archlibdir"] + " " + RbConfig::CONFIG["LIBRUBYARG_SHARED"]') RUBYINSTALL ?= $(shell $(RUBY) -e 'puts RbConfig::CONFIG["vendorarchdir"]') @@ -65,7 +65,7 @@ EXTRA_CFLAGS = -fipa-pure-const -Wlogical-op -Wpacked-bitfield-compat -Wsync-nan -Wcoverage-mismatch -Wcpp -Wformat-contains-nul -Wnormalized=nfc -Wsuggest-attribute=const \ -Wsuggest-attribute=noreturn -Wsuggest-attribute=pure -Wtrampolines -Wjump-misses-init \ -Wno-suggest-attribute=pure -Wno-suggest-attribute=const -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 \ - -Wstrict-overflow=5 -fno-semantic-interposition + -Wstrict-overflow=5 else EXTRA_CFLAGS = -Wunused-command-line-argument endif @@ -90,7 +90,7 @@ CFLAGS ?= -O -Wall -W -Wundef -Wformat-y2k -Wformat-security -Winit-self -Wmissi -Werror -Wno-aggregate-return -Wno-redundant-decls \ $(EXTRA_CFLAGS) -LD_SONAME_FLAGS=-soname,$(LIBSO),--version-script=libselinux.map,-z,defs,-z,relro +LD_SONAME_FLAGS=-soname,$(LIBSO),-z,defs,-z,relro ifeq ($(OS), Darwin) override CFLAGS += -I/opt/local/include @@ -105,8 +105,7 @@ FTS_LDLIBS ?= override CFLAGS += -I../include -D_GNU_SOURCE $(DISABLE_FLAGS) $(PCRE_CFLAGS) SWIG_CFLAGS += -Wno-error -Wno-unused-variable -Wno-unused-but-set-variable -Wno-unused-parameter \ - -Wno-shadow -Wno-uninitialized -Wno-missing-prototypes -Wno-missing-declarations \ - -Wno-deprecated-declarations + -Wno-shadow -Wno-uninitialized -Wno-missing-prototypes -Wno-missing-declarations RANLIB ?= ranlib @@ -122,16 +121,8 @@ SRCS= callbacks.c freecon.c label.c label_file.c \ label_backends_android.c regex.c label_support.c \ matchpathcon.c setrans_client.c sha1.c booleans.c else -LABEL_BACKEND_ANDROID=y -endif - -ifneq ($(LABEL_BACKEND_ANDROIDT),y) -SRCS:= $(filter-out label_backends_android.c, $(SRCS)) DISABLE_FLAGS+= -DNO_ANDROID_BACKEND -endif - -ifeq ($(DISABLE_X11),y) -SRCS:= $(filter-out label_x.c, $(SRCS)) +SRCS:= $(filter-out label_backends_android.c, $(SRCS)) endif SWIGRUBY = swig -Wall -ruby -o $(SWIGRUBYCOUT) -outdir ./ $(DISABLE_FLAGS) @@ -182,7 +173,7 @@ install: all ln -sf --relative $(DESTDIR)$(SHLIBDIR)/$(LIBSO) $(DESTDIR)$(LIBDIR)/$(TARGET) install-pywrap: pywrap - $(PYTHON) setup.py install --prefix=$(PREFIX) `test -n "$(DESTDIR)" && echo --root $(DESTDIR)` $(PYTHON_SETUP_ARGS) + $(PYTHON) setup.py install --prefix=$(PREFIX) `test -n "$(DESTDIR)" && echo --root $(DESTDIR)` install -m 644 $(SWIGPYOUT) $(DESTDIR)$(PYTHONLIBDIR)/selinux/__init__.py ln -sf --relative $(DESTDIR)$(PYTHONLIBDIR)/selinux/_selinux$(PYCEXT) $(DESTDIR)$(PYTHONLIBDIR)/_selinux$(PYCEXT) diff --git a/libselinux/src/audit2why.c b/libselinux/src/audit2why.c index ca38e13c..d56b56eb 100644 --- a/libselinux/src/audit2why.c +++ b/libselinux/src/audit2why.c @@ -204,8 +204,8 @@ static int __policy_init(const char *init_path) fp = fopen(path, "re"); if (!fp) { snprintf(errormsg, sizeof(errormsg), - "unable to open %s: %m\n", - path); + "unable to open %s: %s\n", + path, strerror(errno)); PyErr_SetString( PyExc_ValueError, errormsg); return 1; } @@ -221,8 +221,9 @@ static int __policy_init(const char *init_path) fp = fopen(curpolicy, "re"); if (!fp) { snprintf(errormsg, sizeof(errormsg), - "unable to open %s: %m\n", - curpolicy); + "unable to open %s: %s\n", + curpolicy, + strerror(errno)); PyErr_SetString( PyExc_ValueError, errormsg); return 1; } @@ -241,7 +242,7 @@ static int __policy_init(const char *init_path) if (sepol_policy_file_create(&pf) || sepol_policydb_create(&avc->policydb)) { snprintf(errormsg, sizeof(errormsg), - "policydb_init failed: %m\n"); + "policydb_init failed: %s\n", strerror(errno)); PyErr_SetString( PyExc_RuntimeError, errormsg); fclose(fp); return 1; @@ -274,7 +275,7 @@ static int __policy_init(const char *init_path) } sepol_bool_iterate(avc->handle, avc->policydb, - load_booleans, NULL); + load_booleans, (void *)NULL); /* Initialize the sidtab for subsequent use by sepol_context_to_sid and sepol_compute_av_reason. */ diff --git a/libselinux/src/avc.c b/libselinux/src/avc.c index 7493e4b2..5230efd2 100644 --- a/libselinux/src/avc.c +++ b/libselinux/src/avc.c @@ -50,6 +50,7 @@ struct avc_callback_node { struct avc_callback_node *next; }; +static void *avc_netlink_thread = NULL; static void *avc_lock = NULL; static void *avc_log_lock = NULL; static struct avc_node *avc_node_freelist = NULL; @@ -144,7 +145,22 @@ int avc_get_initial_sid(const char * name, security_id_t * sid) return rc; } -static int avc_init_internal(const char *prefix, +int avc_open(struct selinux_opt *opts, unsigned nopts) +{ + avc_setenforce = 0; + + while (nopts--) + switch(opts[nopts].type) { + case AVC_OPT_SETENFORCE: + avc_setenforce = 1; + avc_enforcing = !!opts[nopts].value; + break; + } + + return avc_init("avc", NULL, NULL, NULL, NULL); +} + +int avc_init(const char *prefix, const struct avc_memory_callback *mem_cb, const struct avc_log_callback *log_cb, const struct avc_thread_callback *thread_cb, @@ -206,49 +222,30 @@ static int avc_init_internal(const char *prefix, rc = security_getenforce(); if (rc < 0) { avc_log(SELINUX_ERROR, - "%s: could not determine enforcing mode: %m\n", - avc_prefix); + "%s: could not determine enforcing mode: %s\n", + avc_prefix, + strerror(errno)); goto out; } avc_enforcing = rc; } - rc = selinux_status_open(0); + rc = avc_netlink_open(0); if (rc < 0) { avc_log(SELINUX_ERROR, - "%s: could not open selinux status page: %d (%m)\n", - avc_prefix, errno); + "%s: can't open netlink socket: %d (%s)\n", + avc_prefix, errno, strerror(errno)); goto out; } + if (avc_using_threads) { + avc_netlink_thread = avc_create_thread(&avc_netlink_loop); + avc_netlink_trouble = 0; + } avc_running = 1; out: return rc; } -int avc_open(struct selinux_opt *opts, unsigned nopts) -{ - avc_setenforce = 0; - - while (nopts--) - switch(opts[nopts].type) { - case AVC_OPT_SETENFORCE: - avc_setenforce = 1; - avc_enforcing = !!opts[nopts].value; - break; - } - - return avc_init_internal("avc", NULL, NULL, NULL, NULL); -} - -int avc_init(const char *prefix, - const struct avc_memory_callback *mem_cb, - const struct avc_log_callback *log_cb, - const struct avc_thread_callback *thread_cb, - const struct avc_lock_callback *lock_cb) -{ - return avc_init_internal(prefix, mem_cb, log_cb, thread_cb, lock_cb); -} - void avc_cache_stats(struct avc_cache_stats *p) { memcpy(p, &cache_stats, sizeof(cache_stats)); @@ -297,6 +294,7 @@ void avc_av_stats(void) slots_used, AVC_CACHE_SLOTS, max_chain_len); } +hidden_def(avc_av_stats) static inline struct avc_node *avc_reclaim_node(void) { @@ -496,6 +494,7 @@ void avc_cleanup(void) { } +hidden_def(avc_cleanup) int avc_reset(void) { @@ -540,6 +539,7 @@ int avc_reset(void) return rc; } +hidden_def(avc_reset) void avc_destroy(void) { @@ -551,7 +551,9 @@ void avc_destroy(void) avc_get_lock(avc_lock); - selinux_status_close(); + if (avc_using_threads) + avc_stop_thread(avc_netlink_thread); + avc_netlink_close(); for (i = 0; i < AVC_CACHE_SLOTS; i++) { node = avc_cache.slots[i]; @@ -731,6 +733,7 @@ void avc_audit(security_id_t ssid, security_id_t tsid, avc_release_lock(avc_log_lock); } +hidden_def(avc_audit) static void avd_init(struct av_decision *avd) @@ -758,7 +761,7 @@ int avc_has_perm_noaudit(security_id_t ssid, avd_init(avd); if (!avc_using_threads && !avc_app_main_loop) { - (void) selinux_status_updated(); + (void)avc_netlink_check_nb(); } if (!aeref) { @@ -822,6 +825,7 @@ int avc_has_perm_noaudit(security_id_t ssid, return rc; } +hidden_def(avc_has_perm_noaudit) int avc_has_perm(security_id_t ssid, security_id_t tsid, security_class_t tclass, access_vector_t requested, diff --git a/libselinux/src/avc_internal.c b/libselinux/src/avc_internal.c index 71a1357b..568a3d92 100644 --- a/libselinux/src/avc_internal.c +++ b/libselinux/src/avc_internal.c @@ -53,49 +53,6 @@ int avc_enforcing = 1; int avc_setenforce = 0; int avc_netlink_trouble = 0; -/* process setenforce events for netlink and sestatus */ -int avc_process_setenforce(int enforcing) -{ - int rc = 0; - - avc_log(SELINUX_SETENFORCE, - "%s: op=setenforce lsm=selinux enforcing=%d res=1", - avc_prefix, enforcing); - if (avc_setenforce) - goto out; - avc_enforcing = enforcing; - if (avc_enforcing && (rc = avc_ss_reset(0)) < 0) { - avc_log(SELINUX_ERROR, - "%s: cache reset returned %d (errno %d)\n", - avc_prefix, rc, errno); - return rc; - } - -out: - return selinux_netlink_setenforce(enforcing); -} - -/* process policyload events for netlink and sestatus */ -int avc_process_policyload(uint32_t seqno) -{ - int rc = 0; - - avc_log(SELINUX_POLICYLOAD, - "%s: op=load_policy lsm=selinux seqno=%u res=1", - avc_prefix, seqno); - rc = avc_ss_reset(seqno); - if (rc < 0) { - avc_log(SELINUX_ERROR, - "%s: cache reset returned %d (errno %d)\n", - avc_prefix, rc, errno); - return rc; - } - - selinux_flush_class_cache(); - - return selinux_netlink_policyload(seqno); -} - /* netlink socket code */ static int fd = -1; @@ -220,7 +177,20 @@ static int avc_netlink_process(void *buf) case SELNL_MSG_SETENFORCE:{ struct selnl_msg_setenforce *msg = NLMSG_DATA(nlh); - rc = avc_process_setenforce(!!msg->val); + msg->val = !!msg->val; + avc_log(SELINUX_INFO, + "%s: received setenforce notice (enforcing=%d)\n", + avc_prefix, msg->val); + if (avc_setenforce) + break; + avc_enforcing = msg->val; + if (avc_enforcing && (rc = avc_ss_reset(0)) < 0) { + avc_log(SELINUX_ERROR, + "%s: cache reset returned %d (errno %d)\n", + avc_prefix, rc, errno); + return rc; + } + rc = selinux_netlink_setenforce(msg->val); if (rc < 0) return rc; break; @@ -228,7 +198,18 @@ static int avc_netlink_process(void *buf) case SELNL_MSG_POLICYLOAD:{ struct selnl_msg_policyload *msg = NLMSG_DATA(nlh); - rc = avc_process_policyload(msg->seqno); + avc_log(SELINUX_INFO, + "%s: received policyload notice (seqno=%u)\n", + avc_prefix, msg->seqno); + rc = avc_ss_reset(msg->seqno); + if (rc < 0) { + avc_log(SELINUX_ERROR, + "%s: cache reset returned %d (errno %d)\n", + avc_prefix, rc, errno); + return rc; + } + selinux_flush_class_cache(); + rc = selinux_netlink_policyload(msg->seqno); if (rc < 0) return rc; break; @@ -303,17 +284,6 @@ void avc_netlink_loop(void) int avc_netlink_acquire_fd(void) { - if (fd < 0) { - int rc = 0; - rc = avc_netlink_open(0); - if (rc < 0) { - avc_log(SELINUX_ERROR, - "%s: could not open netlink socket: %d (%m)\n", - avc_prefix, errno); - return rc; - } - } - avc_app_main_loop = 1; return fd; diff --git a/libselinux/src/avc_internal.h b/libselinux/src/avc_internal.h index a9a4aa0b..f8516590 100644 --- a/libselinux/src/avc_internal.h +++ b/libselinux/src/avc_internal.h @@ -14,27 +14,24 @@ #include #include #include "callbacks.h" +#include "dso.h" /* callback pointers */ -extern void *(*avc_func_malloc) (size_t) ; -extern void (*avc_func_free) (void *); +extern void *(*avc_func_malloc) (size_t) hidden; +extern void (*avc_func_free) (void *)hidden; -extern void (*avc_func_log) (const char *, ...) __attribute__((__format__(printf,1,2))) ; -extern void (*avc_func_audit) (void *, security_class_t, char *, size_t); +extern void (*avc_func_log) (const char *, ...) __attribute__((__format__(printf,1,2))) hidden; +extern void (*avc_func_audit) (void *, security_class_t, char *, size_t)hidden; -extern int avc_using_threads ; -extern int avc_app_main_loop ; -extern void *(*avc_func_create_thread) (void (*)(void)); -extern void (*avc_func_stop_thread) (void *); +extern int avc_using_threads hidden; +extern int avc_app_main_loop hidden; +extern void *(*avc_func_create_thread) (void (*)(void))hidden; +extern void (*avc_func_stop_thread) (void *)hidden; -extern void *(*avc_func_alloc_lock) (void); -extern void (*avc_func_get_lock) (void *); -extern void (*avc_func_release_lock) (void *); -extern void (*avc_func_free_lock) (void *); - -/* selinux status processing for netlink and sestatus */ -extern int avc_process_setenforce(int enforcing); -extern int avc_process_policyload(uint32_t seqno); +extern void *(*avc_func_alloc_lock) (void)hidden; +extern void (*avc_func_get_lock) (void *)hidden; +extern void (*avc_func_release_lock) (void *)hidden; +extern void (*avc_func_free_lock) (void *)hidden; static inline void set_callbacks(const struct avc_memory_callback *mem_cb, const struct avc_log_callback *log_cb, @@ -64,10 +61,10 @@ static inline void set_callbacks(const struct avc_memory_callback *mem_cb, /* message prefix and enforcing mode*/ #define AVC_PREFIX_SIZE 16 -extern char avc_prefix[AVC_PREFIX_SIZE] ; -extern int avc_running ; -extern int avc_enforcing ; -extern int avc_setenforce ; +extern char avc_prefix[AVC_PREFIX_SIZE] hidden; +extern int avc_running hidden; +extern int avc_enforcing hidden; +extern int avc_setenforce hidden; /* user-supplied callback interface for avc */ static inline void *avc_malloc(size_t size) @@ -85,12 +82,10 @@ static inline void avc_free(void *ptr) /* this is a macro in order to use the variadic capability. */ #define avc_log(type, format...) \ - do { \ - if (avc_func_log) \ - avc_func_log(format); \ - else \ - selinux_log(type, format); \ - } while (0) + if (avc_func_log) \ + avc_func_log(format); \ + else \ + selinux_log(type, format); static inline void avc_suppl_audit(void *ptr, security_class_t class, char *buf, size_t len) @@ -139,18 +134,14 @@ static inline void avc_free_lock(void *lock) #ifdef AVC_CACHE_STATS #define avc_cache_stats_incr(field) \ - do { \ - cache_stats.field ++; \ - } while (0) + cache_stats.field ++; #define avc_cache_stats_add(field, num) \ - do { \ - cache_stats.field += num; \ - } while (0) + cache_stats.field += num; #else -#define avc_cache_stats_incr(field) do {} while (0) -#define avc_cache_stats_add(field, num) do {} while (0) +#define avc_cache_stats_incr(field) +#define avc_cache_stats_add(field, num) #endif @@ -164,23 +155,28 @@ static inline void avc_free_lock(void *lock) /* internal callbacks */ int avc_ss_grant(security_id_t ssid, security_id_t tsid, security_class_t tclass, access_vector_t perms, - uint32_t seqno) ; + uint32_t seqno) hidden; int avc_ss_try_revoke(security_id_t ssid, security_id_t tsid, security_class_t tclass, access_vector_t perms, uint32_t seqno, - access_vector_t * out_retained) ; + access_vector_t * out_retained) hidden; int avc_ss_revoke(security_id_t ssid, security_id_t tsid, security_class_t tclass, access_vector_t perms, - uint32_t seqno) ; -int avc_ss_reset(uint32_t seqno) ; + uint32_t seqno) hidden; +int avc_ss_reset(uint32_t seqno) hidden; int avc_ss_set_auditallow(security_id_t ssid, security_id_t tsid, security_class_t tclass, access_vector_t perms, - uint32_t seqno, uint32_t enable) ; + uint32_t seqno, uint32_t enable) hidden; int avc_ss_set_auditdeny(security_id_t ssid, security_id_t tsid, security_class_t tclass, access_vector_t perms, - uint32_t seqno, uint32_t enable) ; + uint32_t seqno, uint32_t enable) hidden; /* netlink kernel message code */ -extern int avc_netlink_trouble ; +extern int avc_netlink_trouble hidden; +hidden_proto(avc_av_stats) + hidden_proto(avc_cleanup) + hidden_proto(avc_reset) + hidden_proto(avc_audit) + hidden_proto(avc_has_perm_noaudit) #endif /* _SELINUX_AVC_INTERNAL_H_ */ diff --git a/libselinux/src/avc_sidtab.c b/libselinux/src/avc_sidtab.c index f179d855..9669264d 100644 --- a/libselinux/src/avc_sidtab.c +++ b/libselinux/src/avc_sidtab.c @@ -15,13 +15,14 @@ static inline unsigned sidtab_hash(const char * key) { - const char *p; + char *p, *keyp; unsigned int size; unsigned int val; val = 0; - size = strlen(key); - for (p = key; (unsigned int)(p - key) < size; p++) + keyp = (char *)key; + size = strlen(keyp); + for (p = keyp; (unsigned int)(p - keyp) < size; p++) val = (val << 4 | (val >> (8 * sizeof(unsigned int) - 4))) ^ (*p); return val & (SIDTAB_SIZE - 1); @@ -56,7 +57,7 @@ int sidtab_insert(struct sidtab *s, const char * ctx) rc = -1; goto out; } - newctx = strdup(ctx); + newctx = (char *) strdup(ctx); if (!newctx) { rc = -1; avc_free(newnode); @@ -100,7 +101,7 @@ sidtab_context_to_sid(struct sidtab *s, return rc; } -void sidtab_sid_stats(struct sidtab *s, char *buf, int buflen) +void sidtab_sid_stats(struct sidtab *h, char *buf, int buflen) { int i, chain_len, slots_used, max_chain_len; struct sidtab_node *cur; @@ -108,7 +109,7 @@ void sidtab_sid_stats(struct sidtab *s, char *buf, int buflen) slots_used = 0; max_chain_len = 0; for (i = 0; i < SIDTAB_SIZE; i++) { - cur = s->htable[i]; + cur = h->htable[i]; if (cur) { slots_used++; chain_len = 0; @@ -124,7 +125,7 @@ void sidtab_sid_stats(struct sidtab *s, char *buf, int buflen) snprintf(buf, buflen, "%s: %u SID entries and %d/%d buckets used, longest " - "chain length %d\n", avc_prefix, s->nel, slots_used, + "chain length %d\n", avc_prefix, h->nel, slots_used, SIDTAB_SIZE, max_chain_len); } diff --git a/libselinux/src/avc_sidtab.h b/libselinux/src/avc_sidtab.h index cc5abe35..bce9b877 100644 --- a/libselinux/src/avc_sidtab.h +++ b/libselinux/src/avc_sidtab.h @@ -7,6 +7,7 @@ #include #include +#include "dso.h" struct sidtab_node { struct security_id sid_s; @@ -23,13 +24,13 @@ struct sidtab { unsigned nel; }; -int sidtab_init(struct sidtab *s) ; -int sidtab_insert(struct sidtab *s, const char * ctx) ; +int sidtab_init(struct sidtab *s) hidden; +int sidtab_insert(struct sidtab *s, const char * ctx) hidden; int sidtab_context_to_sid(struct sidtab *s, - const char * ctx, security_id_t * sid) ; + const char * ctx, security_id_t * sid) hidden; -void sidtab_sid_stats(struct sidtab *s, char *buf, int buflen) ; -void sidtab_destroy(struct sidtab *s) ; +void sidtab_sid_stats(struct sidtab *s, char *buf, int buflen) hidden; +void sidtab_destroy(struct sidtab *s) hidden; #endif /* _SELINUX_AVC_SIDTAB_H_ */ diff --git a/libselinux/src/booleans.c b/libselinux/src/booleans.c index ef1f64a0..ffa8d26b 100644 --- a/libselinux/src/booleans.c +++ b/libselinux/src/booleans.c @@ -414,3 +414,8 @@ char *selinux_boolean_sub(const char *name __attribute__((unused))) } #endif +hidden_def(security_get_boolean_names) +hidden_def(selinux_boolean_sub) +hidden_def(security_get_boolean_active) +hidden_def(security_set_boolean) +hidden_def(security_commit_booleans) diff --git a/libselinux/src/callbacks.h b/libselinux/src/callbacks.h index 03d87f0c..2a572e08 100644 --- a/libselinux/src/callbacks.h +++ b/libselinux/src/callbacks.h @@ -9,21 +9,22 @@ #include #include #include +#include "dso.h" /* callback pointers */ extern int __attribute__ ((format(printf, 2, 3))) -(*selinux_log) (int type, const char *, ...) ; +(*selinux_log) (int type, const char *, ...) hidden; extern int -(*selinux_audit) (void *, security_class_t, char *, size_t) ; +(*selinux_audit) (void *, security_class_t, char *, size_t) hidden; extern int -(*selinux_validate)(char **ctx) ; +(*selinux_validate)(char **ctx) hidden; extern int -(*selinux_netlink_setenforce) (int enforcing) ; +(*selinux_netlink_setenforce) (int enforcing) hidden; extern int -(*selinux_netlink_policyload) (int seqno) ; +(*selinux_netlink_policyload) (int seqno) hidden; #endif /* _SELINUX_CALLBACKS_H_ */ diff --git a/libselinux/src/canonicalize_context.c b/libselinux/src/canonicalize_context.c index faab7305..ba4c9a2c 100644 --- a/libselinux/src/canonicalize_context.c +++ b/libselinux/src/canonicalize_context.c @@ -60,6 +60,7 @@ int security_canonicalize_context_raw(const char * con, return ret; } +hidden_def(security_canonicalize_context_raw) int security_canonicalize_context(const char * con, char ** canoncon) @@ -82,3 +83,4 @@ int security_canonicalize_context(const char * con, return ret; } +hidden_def(security_canonicalize_context) diff --git a/libselinux/src/checkAccess.c b/libselinux/src/checkAccess.c index 022cd6b5..7227ffe5 100644 --- a/libselinux/src/checkAccess.c +++ b/libselinux/src/checkAccess.c @@ -39,7 +39,7 @@ int selinux_check_access(const char *scon, const char *tcon, const char *class, if (rc < 0) return rc; - (void) selinux_status_updated(); + (void) avc_netlink_check_nb(); sclass = string_to_security_class(class); if (sclass == 0) { @@ -64,7 +64,7 @@ int selinux_check_access(const char *scon, const char *tcon, const char *class, return avc_has_perm (scon_id, tcon_id, sclass, av, NULL, aux); } -static int selinux_check_passwd_access_internal(access_vector_t requested) +int selinux_check_passwd_access(access_vector_t requested) { int status = -1; char *user_context; @@ -78,9 +78,7 @@ static int selinux_check_passwd_access_internal(access_vector_t requested) passwd_class = string_to_security_class("passwd"); if (passwd_class == 0) { freecon(user_context); - if (security_deny_unknown() == 0) - return 0; - return -1; + return 0; } retval = security_compute_av_raw(user_context, @@ -101,11 +99,9 @@ static int selinux_check_passwd_access_internal(access_vector_t requested) return status; } -int selinux_check_passwd_access(access_vector_t requested) { - return selinux_check_passwd_access_internal(requested); -} +hidden_def(selinux_check_passwd_access) int checkPasswdAccess(access_vector_t requested) { - return selinux_check_passwd_access_internal(requested); + return selinux_check_passwd_access(requested); } diff --git a/libselinux/src/check_context.c b/libselinux/src/check_context.c index 5096a2c4..8a7997f0 100644 --- a/libselinux/src/check_context.c +++ b/libselinux/src/check_context.c @@ -31,6 +31,7 @@ int security_check_context_raw(const char * con) return 0; } +hidden_def(security_check_context_raw) int security_check_context(const char * con) { @@ -47,3 +48,4 @@ int security_check_context(const char * con) return ret; } +hidden_def(security_check_context) diff --git a/libselinux/src/checkreqprot.c b/libselinux/src/checkreqprot.c index 3dc79d97..9b4b12d7 100644 --- a/libselinux/src/checkreqprot.c +++ b/libselinux/src/checkreqprot.c @@ -37,3 +37,4 @@ int security_get_checkreqprot(void) return checkreqprot; } +hidden_def(security_get_checkreqprot); diff --git a/libselinux/src/compute_av.c b/libselinux/src/compute_av.c index 9d17339d..a47cffe9 100644 --- a/libselinux/src/compute_av.c +++ b/libselinux/src/compute_av.c @@ -80,6 +80,7 @@ int security_compute_av_flags_raw(const char * scon, return ret; } +hidden_def(security_compute_av_flags_raw) int security_compute_av_raw(const char * scon, const char * tcon, @@ -106,6 +107,7 @@ int security_compute_av_raw(const char * scon, return ret; } +hidden_def(security_compute_av_raw) int security_compute_av_flags(const char * scon, const char * tcon, @@ -132,6 +134,7 @@ int security_compute_av_flags(const char * scon, return ret; } +hidden_def(security_compute_av_flags) int security_compute_av(const char * scon, const char * tcon, @@ -159,3 +162,4 @@ int security_compute_av(const char * scon, return ret; } +hidden_def(security_compute_av) diff --git a/libselinux/src/compute_create.c b/libselinux/src/compute_create.c index 1d75714d..0975aeac 100644 --- a/libselinux/src/compute_create.c +++ b/libselinux/src/compute_create.c @@ -105,6 +105,7 @@ int security_compute_create_name_raw(const char * scon, close(fd); return ret; } +hidden_def(security_compute_create_name_raw) int security_compute_create_raw(const char * scon, const char * tcon, @@ -114,6 +115,7 @@ int security_compute_create_raw(const char * scon, return security_compute_create_name_raw(scon, tcon, tclass, NULL, newcon); } +hidden_def(security_compute_create_raw) int security_compute_create_name(const char * scon, const char * tcon, @@ -144,6 +146,7 @@ int security_compute_create_name(const char * scon, return ret; } +hidden_def(security_compute_create_name) int security_compute_create(const char * scon, const char * tcon, @@ -152,3 +155,4 @@ int security_compute_create(const char * scon, { return security_compute_create_name(scon, tcon, tclass, NULL, newcon); } +hidden_def(security_compute_create) diff --git a/libselinux/src/compute_member.c b/libselinux/src/compute_member.c index 16234b79..4e2d221e 100644 --- a/libselinux/src/compute_member.c +++ b/libselinux/src/compute_member.c @@ -60,6 +60,7 @@ int security_compute_member_raw(const char * scon, return ret; } +hidden_def(security_compute_member_raw) int security_compute_member(const char * scon, const char * tcon, diff --git a/libselinux/src/compute_relabel.c b/libselinux/src/compute_relabel.c index dd20d652..49f77ef3 100644 --- a/libselinux/src/compute_relabel.c +++ b/libselinux/src/compute_relabel.c @@ -60,6 +60,7 @@ int security_compute_relabel_raw(const char * scon, return ret; } +hidden_def(security_compute_relabel_raw) int security_compute_relabel(const char * scon, const char * tcon, diff --git a/libselinux/src/compute_user.c b/libselinux/src/compute_user.c index ae5e7b4a..7b881215 100644 --- a/libselinux/src/compute_user.c +++ b/libselinux/src/compute_user.c @@ -8,7 +8,6 @@ #include "selinux_internal.h" #include "policy.h" #include -#include "callbacks.h" int security_compute_user_raw(const char * scon, const char *user, char *** con) @@ -25,8 +24,6 @@ int security_compute_user_raw(const char * scon, return -1; } - selinux_log(SELINUX_WARNING, "Direct use of security_compute_user() is deprecated, switch to get_ordered_context_list()\n"); - snprintf(path, sizeof path, "%s/user", selinux_mnt); fd = open(path, O_RDWR | O_CLOEXEC); if (fd < 0) @@ -80,6 +77,7 @@ int security_compute_user_raw(const char * scon, return ret; } +hidden_def(security_compute_user_raw) int security_compute_user(const char * scon, const char *user, char *** con) @@ -109,3 +107,4 @@ int security_compute_user(const char * scon, return ret; } +hidden_def(security_compute_user) diff --git a/libselinux/src/context.c b/libselinux/src/context.c index b2144c7c..b673733e 100644 --- a/libselinux/src/context.c +++ b/libselinux/src/context.c @@ -37,7 +37,7 @@ context_t context_new(const char *str) } n->current_str = n->component[0] = n->component[1] = n->component[2] = n->component[3] = 0; - for (count = 0, p = str; *p; p++) { + for (i = count = 0, p = str; *p; p++) { switch (*p) { case ':': count++; @@ -82,6 +82,7 @@ context_t context_new(const char *str) return 0; } +hidden_def(context_new) static void conditional_free(char **v) { @@ -112,6 +113,7 @@ void context_free(context_t context) } } +hidden_def(context_free) /* * Return a pointer to the string value of the context. @@ -142,6 +144,7 @@ char *context_str(context_t context) return n->current_str; } +hidden_def(context_str) /* Returns nonzero iff failed */ static int set_comp(context_private_t * n, int idx, const char *str) @@ -151,14 +154,14 @@ static int set_comp(context_private_t * n, int idx, const char *str) if (str) { t = (char *)malloc(strlen(str) + 1); if (!t) { - return -1; + return 1; } for (p = str; *p; p++) { if (*p == '\t' || *p == '\n' || *p == '\r' || ((*p == ':' || *p == ' ') && idx != COMP_RANGE)) { free(t); errno = EINVAL; - return -1; + return 1; } } strcpy(t, str); @@ -173,7 +176,8 @@ const char * context_ ## name ## _get(context_t context) \ { \ context_private_t *n = context->ptr; \ return n->component[tag]; \ -} +} \ +hidden_def(context_ ## name ## _get) def_get(type, COMP_TYPE) def_get(user, COMP_USER) @@ -183,7 +187,8 @@ def_get(type, COMP_TYPE) int context_ ## name ## _set(context_t context, const char* str) \ { \ return set_comp(context->ptr,tag,str);\ -} +} \ +hidden_def(context_ ## name ## _set) def_set(type, COMP_TYPE) def_set(role, COMP_ROLE) def_set(user, COMP_USER) diff --git a/libselinux/src/context_internal.h b/libselinux/src/context_internal.h index a7698106..3c71e802 100644 --- a/libselinux/src/context_internal.h +++ b/libselinux/src/context_internal.h @@ -1,2 +1,14 @@ #include +#include "dso.h" +hidden_proto(context_new) + hidden_proto(context_free) + hidden_proto(context_str) + hidden_proto(context_type_set) + hidden_proto(context_type_get) + hidden_proto(context_role_set) + hidden_proto(context_role_get) + hidden_proto(context_user_set) + hidden_proto(context_user_get) + hidden_proto(context_range_set) + hidden_proto(context_range_get) diff --git a/libselinux/src/deny_unknown.c b/libselinux/src/deny_unknown.c index fdd32b50..77d04e37 100644 --- a/libselinux/src/deny_unknown.c +++ b/libselinux/src/deny_unknown.c @@ -37,3 +37,4 @@ int security_deny_unknown(void) return deny_unknown; } +hidden_def(security_deny_unknown); diff --git a/libselinux/src/disable.c b/libselinux/src/disable.c index 1a5ae417..8d66262a 100644 --- a/libselinux/src/disable.c +++ b/libselinux/src/disable.c @@ -35,3 +35,4 @@ int security_disable(void) return 0; } +hidden_def(security_disable) diff --git a/libselinux/src/dso.h b/libselinux/src/dso.h new file mode 100644 index 00000000..12c3d116 --- /dev/null +++ b/libselinux/src/dso.h @@ -0,0 +1,23 @@ +#ifndef _SELINUX_DSO_H +#define _SELINUX_DSO_H 1 + +#ifdef SHARED +# define hidden __attribute__ ((visibility ("hidden"))) +# define hidden_proto(fct) __hidden_proto (fct, fct##_internal) +# define __hidden_proto(fct, internal) \ + extern __typeof (fct) internal; \ + extern __typeof (fct) fct __asm (#internal) hidden; +# if defined(__alpha__) || defined(__mips__) +# define hidden_def(fct) \ + asm (".globl " #fct "\n" #fct " = " #fct "_internal"); +# else +# define hidden_def(fct) \ + asm (".globl " #fct "\n.set " #fct ", " #fct "_internal"); +#endif +#else +# define hidden +# define hidden_proto(fct) +# define hidden_def(fct) +#endif + +#endif diff --git a/libselinux/src/enabled.c b/libselinux/src/enabled.c index fefb0bd9..dd628fba 100644 --- a/libselinux/src/enabled.c +++ b/libselinux/src/enabled.c @@ -20,6 +20,7 @@ int is_selinux_enabled(void) #endif } +hidden_def(is_selinux_enabled) /* * Function: is_selinux_mls_enabled() @@ -54,3 +55,4 @@ int is_selinux_mls_enabled(void) return enabled; } +hidden_def(is_selinux_mls_enabled) diff --git a/libselinux/src/exception.sh b/libselinux/src/exception.sh index 3b7f2450..33ceef80 100755 --- a/libselinux/src/exception.sh +++ b/libselinux/src/exception.sh @@ -1,5 +1,3 @@ -#!/bin/bash - function except() { case $1 in selinux_file_context_cmp) # ignore @@ -12,26 +10,15 @@ echo " PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } -}" +} +" ;; esac } - -# Make sure that selinux.h is included first in order not to depend on the order -# in which "#include " appears in other files. -FILE_LIST=( - ../include/selinux/selinux.h - ../include/selinux/avc.h - ../include/selinux/context.h - ../include/selinux/get_context_list.h - ../include/selinux/get_default_type.h - ../include/selinux/label.h - ../include/selinux/restorecon.h -) -if ! cat "${FILE_LIST[@]}" | ${CC:-gcc} -x c -c -I../include -o temp.o - -aux-info temp.aux +if ! ${CC:-gcc} -x c -c -I../include -o temp.o - -aux-info temp.aux < ../include/selinux/selinux.h then # clang does not support -aux-info so fall back to gcc - cat "${FILE_LIST[@]}" | gcc -x c -c -I../include -o temp.o - -aux-info temp.aux + gcc -x c -c -I../include -o temp.o - -aux-info temp.aux < ../include/selinux/selinux.h fi for i in `awk '/.*extern int/ { print $6 }' temp.aux`; do except $i ; done rm -f -- temp.aux temp.o diff --git a/libselinux/src/fgetfilecon.c b/libselinux/src/fgetfilecon.c index 8c748f8a..5522ac16 100644 --- a/libselinux/src/fgetfilecon.c +++ b/libselinux/src/fgetfilecon.c @@ -49,6 +49,7 @@ int fgetfilecon_raw(int fd, char ** context) return ret; } +hidden_def(fgetfilecon_raw) int fgetfilecon(int fd, char ** context) { diff --git a/libselinux/src/freecon.c b/libselinux/src/freecon.c index df2d7e28..5290dfa1 100644 --- a/libselinux/src/freecon.c +++ b/libselinux/src/freecon.c @@ -8,3 +8,4 @@ void freecon(char * con) free(con); } +hidden_def(freecon) diff --git a/libselinux/src/freeconary.c b/libselinux/src/freeconary.c index fd2dbaab..8d07718e 100644 --- a/libselinux/src/freeconary.c +++ b/libselinux/src/freeconary.c @@ -16,3 +16,4 @@ void freeconary(char ** con) free(con); } +hidden_def(freeconary) diff --git a/libselinux/src/fsetfilecon.c b/libselinux/src/fsetfilecon.c index 5cf34e3f..52707d05 100644 --- a/libselinux/src/fsetfilecon.c +++ b/libselinux/src/fsetfilecon.c @@ -25,6 +25,7 @@ int fsetfilecon_raw(int fd, const char * context) return rc; } +hidden_def(fsetfilecon_raw) int fsetfilecon(int fd, const char *context) { diff --git a/libselinux/src/get_context_list.c b/libselinux/src/get_context_list.c index cfe38e59..689e4658 100644 --- a/libselinux/src/get_context_list.c +++ b/libselinux/src/get_context_list.c @@ -2,7 +2,6 @@ #include #include #include -#include #include #include #include @@ -13,7 +12,7 @@ int get_default_context_with_role(const char *user, const char *role, - const char *fromcon, + char * fromcon, char ** newcon) { char **conary; @@ -52,28 +51,28 @@ int get_default_context_with_role(const char *user, return rc; } +hidden_def(get_default_context_with_role) int get_default_context_with_rolelevel(const char *user, const char *role, const char *level, - const char *fromcon, + char * fromcon, char ** newcon) { - int rc; - char *backup_fromcon = NULL; + int rc = 0; + int freefrom = 0; context_t con; - const char *newfromcon; - + char *newfromcon; if (!level) return get_default_context_with_role(user, role, fromcon, newcon); if (!fromcon) { - rc = getcon(&backup_fromcon); + rc = getcon(&fromcon); if (rc < 0) return rc; - fromcon = backup_fromcon; + freefrom = 1; } rc = -1; @@ -92,13 +91,14 @@ int get_default_context_with_rolelevel(const char *user, out: context_free(con); - freecon(backup_fromcon); + if (freefrom) + freecon(fromcon); return rc; } int get_default_context(const char *user, - const char *fromcon, char ** newcon) + char * fromcon, char ** newcon) { char **conary; int rc; @@ -114,41 +114,64 @@ int get_default_context(const char *user, return 0; } -static int is_in_reachable(char **reachable, const char *usercon_str) +static int find_partialcon(char ** list, + unsigned int nreach, char *part) { - if (!reachable) - return 0; + const char *conrole, *contype; + char *partrole, *parttype, *ptr; + context_t con; + unsigned int i; - for (; *reachable != NULL; reachable++) { - if (strcmp(*reachable, usercon_str) == 0) { - return 1; + partrole = part; + ptr = part; + while (*ptr && !isspace(*ptr) && *ptr != ':') + ptr++; + if (*ptr != ':') + return -1; + *ptr++ = 0; + parttype = ptr; + while (*ptr && !isspace(*ptr) && *ptr != ':') + ptr++; + *ptr = 0; + + for (i = 0; i < nreach; i++) { + con = context_new(list[i]); + if (!con) + return -1; + conrole = context_role_get(con); + contype = context_type_get(con); + if (!conrole || !contype) { + context_free(con); + return -1; } + if (!strcmp(conrole, partrole) && !strcmp(contype, parttype)) { + context_free(con); + return i; + } + context_free(con); } - return 0; + + return -1; } -static int get_context_user(FILE * fp, - const char * fromcon, - const char * user, - char ***reachable, - unsigned int *nreachable) +static int get_context_order(FILE * fp, + char * fromcon, + char ** reachable, + unsigned int nreach, + unsigned int *ordering, unsigned int *nordered) { char *start, *end = NULL; char *line = NULL; - size_t line_len = 0, usercon_len; - size_t user_len = strlen(user); + size_t line_len = 0; ssize_t len; int found = 0; - const char *fromrole, *fromtype, *fromlevel; + const char *fromrole, *fromtype; char *linerole, *linetype; - char **new_reachable = NULL; - char *usercon_str; + unsigned int i; context_t con; - context_t usercon; - int rc; - errno = EINVAL; + errno = -EINVAL; /* Extract the role and type of the fromcon for matching. User identity and MLS range can be variable. */ @@ -157,7 +180,6 @@ static int get_context_user(FILE * fp, return -1; fromrole = context_role_get(con); fromtype = context_type_get(con); - fromlevel = context_range_get(con); if (!fromrole || !fromtype) { context_free(con); return -1; @@ -221,75 +243,23 @@ static int get_context_user(FILE * fp, if (*end) *end++ = 0; - /* Check whether a new context is valid */ - if (SIZE_MAX - user_len < strlen(start) + 2) { - fprintf(stderr, "%s: one of partial contexts is too big\n", __FUNCTION__); - errno = EINVAL; - rc = -1; - goto out; - } - usercon_len = user_len + strlen(start) + 2; - usercon_str = malloc(usercon_len); - if (!usercon_str) { - rc = -1; - goto out; - } - - /* set range from fromcon in the new usercon */ - snprintf(usercon_str, usercon_len, "%s:%s", user, start); - usercon = context_new(usercon_str); - if (!usercon) { - if (errno != EINVAL) { - free(usercon_str); - rc = -1; - goto out; - } - fprintf(stderr, - "%s: can't create a context from %s, skipping\n", - __FUNCTION__, usercon_str); - free(usercon_str); + /* Check for a match in the reachable list. */ + rc = find_partialcon(reachable, nreach, start); + if (rc < 0) { + /* No match, skip it. */ start = end; continue; } - free(usercon_str); - if (context_range_set(usercon, fromlevel) != 0) { - context_free(usercon); - rc = -1; - goto out; - } - usercon_str = context_str(usercon); - if (!usercon_str) { - context_free(usercon); - rc = -1; - goto out; - } - /* check whether usercon is already in reachable */ - if (is_in_reachable(*reachable, usercon_str)) { - context_free(usercon); - start = end; - continue; - } - if (security_check_context(usercon_str) == 0) { - new_reachable = realloc(*reachable, (*nreachable + 2) * sizeof(char *)); - if (!new_reachable) { - context_free(usercon); - rc = -1; - goto out; - } - *reachable = new_reachable; - new_reachable[*nreachable] = strdup(usercon_str); - if (new_reachable[*nreachable] == NULL) { - context_free(usercon); - rc = -1; - goto out; - } - new_reachable[*nreachable + 1] = 0; - *nreachable += 1; - } - context_free(usercon); + /* If a match is found and the entry is not already ordered + (e.g. due to prior match in prior config file), then set + the ordering for it. */ + i = rc; + if (ordering[i] == nreach) + ordering[i] = (*nordered)++; start = end; } + rc = 0; out: @@ -343,24 +313,39 @@ static int get_failsafe_context(const char *user, char ** newcon) return 0; } +struct context_order { + char * con; + unsigned int order; +}; + +static int order_compare(const void *A, const void *B) +{ + const struct context_order *c1 = A, *c2 = B; + if (c1->order < c2->order) + return -1; + else if (c1->order > c2->order) + return 1; + return strcmp(c1->con, c2->con); +} + int get_ordered_context_list_with_level(const char *user, const char *level, - const char *fromcon, + char * fromcon, char *** list) { int rc; - char *backup_fromcon = NULL; + int freefrom = 0; context_t con; - const char *newfromcon; + char *newfromcon; if (!level) return get_ordered_context_list(user, fromcon, list); if (!fromcon) { - rc = getcon(&backup_fromcon); + rc = getcon(&fromcon); if (rc < 0) return rc; - fromcon = backup_fromcon; + freefrom = 1; } rc = -1; @@ -379,14 +364,16 @@ int get_ordered_context_list_with_level(const char *user, out: context_free(con); - freecon(backup_fromcon); + if (freefrom) + freecon(fromcon); return rc; } +hidden_def(get_ordered_context_list_with_level) int get_default_context_with_level(const char *user, const char *level, - const char *fromcon, + char * fromcon, char ** newcon) { char **conary; @@ -404,13 +391,15 @@ int get_default_context_with_level(const char *user, } int get_ordered_context_list(const char *user, - const char *fromcon, + char * fromcon, char *** list) { char **reachable = NULL; + unsigned int *ordering = NULL; + struct context_order *co = NULL; + char **ptr; int rc = 0; - unsigned nreachable = 0; - char *backup_fromcon = NULL; + unsigned int nreach = 0, nordered = 0, freefrom = 0, i; FILE *fp; char *fname = NULL; size_t fname_len; @@ -418,12 +407,29 @@ int get_ordered_context_list(const char *user, if (!fromcon) { /* Get the current context and use it for the starting context */ - rc = getcon(&backup_fromcon); + rc = getcon(&fromcon); if (rc < 0) return rc; - fromcon = backup_fromcon; + freefrom = 1; } + /* Determine the set of reachable contexts for the user. */ + rc = security_compute_user(fromcon, user, &reachable); + if (rc < 0) + goto failsafe; + nreach = 0; + for (ptr = reachable; *ptr; ptr++) + nreach++; + if (!nreach) + goto failsafe; + + /* Initialize ordering array. */ + ordering = malloc(nreach * sizeof(unsigned int)); + if (!ordering) + goto failsafe; + for (i = 0; i < nreach; i++) + ordering[i] = nreach; + /* Determine the ordering to apply from the optional per-user config and from the global config. */ fname_len = strlen(user_contexts_path) + strlen(user) + 2; @@ -434,8 +440,8 @@ int get_ordered_context_list(const char *user, fp = fopen(fname, "re"); if (fp) { __fsetlocking(fp, FSETLOCKING_BYCALLER); - rc = get_context_user(fp, fromcon, user, &reachable, &nreachable); - + rc = get_context_order(fp, fromcon, reachable, nreach, ordering, + &nordered); fclose(fp); if (rc < 0 && errno != ENOENT) { fprintf(stderr, @@ -448,7 +454,8 @@ int get_ordered_context_list(const char *user, fp = fopen(selinux_default_context_path(), "re"); if (fp) { __fsetlocking(fp, FSETLOCKING_BYCALLER); - rc = get_context_user(fp, fromcon, user, &reachable, &nreachable); + rc = get_context_order(fp, fromcon, reachable, nreach, ordering, + &nordered); fclose(fp); if (rc < 0 && errno != ENOENT) { fprintf(stderr, @@ -456,20 +463,42 @@ int get_ordered_context_list(const char *user, __FUNCTION__, selinux_default_context_path()); /* Fall through */ } + rc = 0; } - if (!nreachable) + if (!nordered) goto failsafe; - out: - if (nreachable > 0) { - *list = reachable; - rc = nreachable; + /* Apply the ordering. */ + co = malloc(nreach * sizeof(struct context_order)); + if (!co) + goto failsafe; + for (i = 0; i < nreach; i++) { + co[i].con = reachable[i]; + co[i].order = ordering[i]; } + qsort(co, nreach, sizeof(struct context_order), order_compare); + for (i = 0; i < nreach; i++) + reachable[i] = co[i].con; + free(co); + + /* Only report the ordered entries to the caller. */ + if (nordered <= nreach) { + for (i = nordered; i < nreach; i++) + free(reachable[i]); + reachable[nordered] = NULL; + rc = nordered; + } + + out: + if (rc > 0) + *list = reachable; else freeconary(reachable); - freecon(backup_fromcon); + free(ordering); + if (freefrom) + freecon(fromcon); return rc; @@ -490,7 +519,8 @@ int get_ordered_context_list(const char *user, reachable = NULL; goto out; } - nreachable = 1; /* one context in the list */ + rc = 1; /* one context in the list */ goto out; } +hidden_def(get_ordered_context_list) diff --git a/libselinux/src/get_context_list_internal.h b/libselinux/src/get_context_list_internal.h index a7c1d41b..c224834e 100644 --- a/libselinux/src/get_context_list_internal.h +++ b/libselinux/src/get_context_list_internal.h @@ -1,2 +1,6 @@ #include +#include "dso.h" +hidden_proto(get_ordered_context_list) + hidden_proto(get_ordered_context_list_with_level) + hidden_proto(get_default_context_with_role) diff --git a/libselinux/src/get_default_type_internal.h b/libselinux/src/get_default_type_internal.h index deb5d296..0da3c512 100644 --- a/libselinux/src/get_default_type_internal.h +++ b/libselinux/src/get_default_type_internal.h @@ -1,2 +1,4 @@ #include +#include "dso.h" +hidden_proto(selinux_default_type_path) diff --git a/libselinux/src/get_initial_context.c b/libselinux/src/get_initial_context.c index 97ae3dcf..5e919f47 100644 --- a/libselinux/src/get_initial_context.c +++ b/libselinux/src/get_initial_context.c @@ -53,6 +53,7 @@ int security_get_initial_context_raw(const char * name, char ** con) return ret; } +hidden_def(security_get_initial_context_raw) int security_get_initial_context(const char * name, char ** con) { @@ -68,3 +69,4 @@ int security_get_initial_context(const char * name, char ** con) return ret; } +hidden_def(security_get_initial_context) diff --git a/libselinux/src/getenforce.c b/libselinux/src/getenforce.c index 3f1e2002..d909dced 100644 --- a/libselinux/src/getenforce.c +++ b/libselinux/src/getenforce.c @@ -37,3 +37,4 @@ int security_getenforce(void) return !!enforce; } +hidden_def(security_getenforce) diff --git a/libselinux/src/getfilecon.c b/libselinux/src/getfilecon.c index 4bee3137..20bee8ab 100644 --- a/libselinux/src/getfilecon.c +++ b/libselinux/src/getfilecon.c @@ -49,6 +49,7 @@ int getfilecon_raw(const char *path, char ** context) return ret; } +hidden_def(getfilecon_raw) int getfilecon(const char *path, char ** context) { @@ -69,3 +70,4 @@ int getfilecon(const char *path, char ** context) return ret; } +hidden_def(getfilecon) diff --git a/libselinux/src/getpeercon.c b/libselinux/src/getpeercon.c index a9dca73e..3a77a2de 100644 --- a/libselinux/src/getpeercon.c +++ b/libselinux/src/getpeercon.c @@ -43,6 +43,7 @@ int getpeercon_raw(int fd, char ** context) return ret; } +hidden_def(getpeercon_raw) int getpeercon(int fd, char ** context) { diff --git a/libselinux/src/init.c b/libselinux/src/init.c index 542c979b..083638c4 100644 --- a/libselinux/src/init.c +++ b/libselinux/src/init.c @@ -12,6 +12,7 @@ #include #include +#include "dso.h" #include "policy.h" #include "selinux_internal.h" #include "setrans_internal.h" @@ -78,6 +79,7 @@ int selinuxfs_exists(void) fclose(fp); return exists; } +hidden_def(selinuxfs_exists) static void init_selinuxmnt(void) { @@ -136,12 +138,14 @@ void fini_selinuxmnt(void) selinux_mnt = NULL; } +hidden_def(fini_selinuxmnt) void set_selinuxmnt(const char *mnt) { selinux_mnt = strdup(mnt); } +hidden_def(set_selinuxmnt) static void init_lib(void) __attribute__ ((constructor)); static void init_lib(void) diff --git a/libselinux/src/is_customizable_type.c b/libselinux/src/is_customizable_type.c index 1b17860c..92876f4d 100644 --- a/libselinux/src/is_customizable_type.c +++ b/libselinux/src/is_customizable_type.c @@ -38,7 +38,7 @@ static int get_customizable_type_list(char *** retlist) while (fgets_unlocked(buf, selinux_page_size, fp) && i < ctr) { buf[strlen(buf) - 1] = 0; - list[i] = strdup(buf); + list[i] = (char *) strdup(buf); if (!list[i]) { unsigned int j; for (j = 0; j < i; j++) diff --git a/libselinux/src/label_backends_android.c b/libselinux/src/label_backends_android.c index b7b176a3..d81faabe 100644 --- a/libselinux/src/label_backends_android.c +++ b/libselinux/src/label_backends_android.c @@ -96,15 +96,9 @@ static int process_line(struct selabel_handle *rec, items = read_spec_entries(line_buf, &errbuf, 2, &prop, &context); if (items < 0) { items = errno; - if (errbuf) { - selinux_log(SELINUX_ERROR, - "%s: line %u error due to: %s\n", path, - lineno, errbuf); - } else { - selinux_log(SELINUX_ERROR, - "%s: line %u error due to: %m\n", path, - lineno); - } + selinux_log(SELINUX_ERROR, + "%s: line %u error due to: %s\n", path, + lineno, errbuf ?: strerror(errno)); errno = items; return -1; } diff --git a/libselinux/src/label_db.c b/libselinux/src/label_db.c index 94c05c6d..fba96c92 100644 --- a/libselinux/src/label_db.c +++ b/libselinux/src/label_db.c @@ -277,7 +277,7 @@ db_init(const struct selinux_opt *opts, unsigned nopts, if (!path) path = selinux_sepgsql_context_path(); - if ((filp = fopen(path, "re")) == NULL) { + if ((filp = fopen(path, "rb")) == NULL) { free(catalog); return NULL; } diff --git a/libselinux/src/label_file.c b/libselinux/src/label_file.c index 70ea86fa..08570aad 100644 --- a/libselinux/src/label_file.c +++ b/libselinux/src/label_file.c @@ -374,7 +374,7 @@ end_arch_check: if (stem_id < 0 || stem_id >= (int32_t)stem_map_len) spec->stem_id = -1; - else + else spec->stem_id = stem_map[stem_id]; /* retrieve the hasMetaChars bit */ @@ -898,7 +898,7 @@ static void closef(struct selabel_handle *rec) // Finds all the matches of |key| in the given context. Returns the result in // the allocated array and updates the match count. If match_count is NULL, // stops early once the 1st match is found. -static struct spec **lookup_all(struct selabel_handle *rec, +static const struct spec **lookup_all(struct selabel_handle *rec, const char *key, int type, bool partial, @@ -907,14 +907,13 @@ static struct spec **lookup_all(struct selabel_handle *rec, struct saved_data *data = (struct saved_data *)rec->data; struct spec *spec_arr = data->spec_arr; int i, rc, file_stem; - size_t len; mode_t mode = (mode_t)type; char *clean_key = NULL; const char *prev_slash, *next_slash; unsigned int sofar = 0; char *sub = NULL; - struct spec **result = NULL; + const struct spec **result = NULL; if (match_count) { *match_count = 0; result = calloc(data->nspec, sizeof(struct spec*)); @@ -948,27 +947,6 @@ static struct spec **lookup_all(struct selabel_handle *rec, key = clean_key; } - /* remove trailing slash */ - len = strlen(key); - if (len == 0) { - errno = EINVAL; - goto finish; - } - - if (len > 1 && key[len - 1] == '/') { - /* reuse clean_key from above if available */ - if (!clean_key) { - clean_key = (char *) malloc(len); - if (!clean_key) - goto finish; - - memcpy(clean_key, key, len - 1); - } - - clean_key[len - 1] = '\0'; - key = clean_key; - } - sub = selabel_sub_key(data, key); if (sub) key = sub; @@ -1023,8 +1001,6 @@ static struct spec **lookup_all(struct selabel_handle *rec, goto finish; } } - if (!result[0]) - errno = ENOENT; finish: free(clean_key); @@ -1040,11 +1016,11 @@ static struct spec *lookup_common(struct selabel_handle *rec, const char *key, int type, bool partial) { - struct spec **matches = lookup_all(rec, key, type, partial, NULL); + const struct spec **matches = lookup_all(rec, key, type, partial, NULL); if (!matches) { return NULL; } - struct spec *result = matches[0]; + struct spec *result = (struct spec*)matches[0]; free(matches); return result; } @@ -1107,7 +1083,7 @@ static bool hash_all_partial_matches(struct selabel_handle *rec, const char *key assert(digest); size_t total_matches; - struct spec **matches = lookup_all(rec, key, 0, true, &total_matches); + const struct spec **matches = lookup_all(rec, key, 0, true, &total_matches); if (!matches) { return false; } diff --git a/libselinux/src/label_file.h b/libselinux/src/label_file.h index 343ffc70..baed3341 100644 --- a/libselinux/src/label_file.h +++ b/libselinux/src/label_file.h @@ -286,6 +286,7 @@ static inline int store_stem(struct saved_data *data, char *buf, int stem_len) tmp_arr = realloc(data->stem_arr, sizeof(*tmp_arr) * alloc_stems); if (!tmp_arr) { + free(buf); return -1; } data->alloc_stems = alloc_stems; @@ -307,7 +308,6 @@ static inline int find_stem_from_spec(struct saved_data *data, const char *buf) int stem_len = get_stem_from_spec(buf); int stemid; char *stem; - int r; if (!stem_len) return -1; @@ -321,11 +321,7 @@ static inline int find_stem_from_spec(struct saved_data *data, const char *buf) if (!stem) return -1; - r = store_stem(data, stem, stem_len); - if (r < 0) - free(stem); - - return r; + return store_stem(data, stem, stem_len); } /* This will always check for buffer over-runs and either read the next entry @@ -445,15 +441,9 @@ static inline int process_line(struct selabel_handle *rec, items = read_spec_entries(line_buf, &errbuf, 3, ®ex, &type, &context); if (items < 0) { rc = errno; - if (errbuf) { - selinux_log(SELINUX_ERROR, - "%s: line %u error due to: %s\n", path, - lineno, errbuf); - } else { - selinux_log(SELINUX_ERROR, - "%s: line %u error due to: %m\n", path, - lineno); - } + selinux_log(SELINUX_ERROR, + "%s: line %u error due to: %s\n", path, + lineno, errbuf ?: strerror(errno)); errno = rc; return -1; } diff --git a/libselinux/src/label_internal.h b/libselinux/src/label_internal.h index d09847c8..95f9a14c 100644 --- a/libselinux/src/label_internal.h +++ b/libselinux/src/label_internal.h @@ -13,6 +13,7 @@ #include #include #include +#include "dso.h" #include "sha1.h" #if defined(ANDROID) || defined(__APPLE__) @@ -25,22 +26,22 @@ */ int selabel_file_init(struct selabel_handle *rec, const struct selinux_opt *opts, - unsigned nopts) ; + unsigned nopts) hidden; int selabel_media_init(struct selabel_handle *rec, const struct selinux_opt *opts, - unsigned nopts) ; + unsigned nopts) hidden; int selabel_x_init(struct selabel_handle *rec, const struct selinux_opt *opts, - unsigned nopts) ; + unsigned nopts) hidden; int selabel_db_init(struct selabel_handle *rec, const struct selinux_opt *opts, - unsigned nopts) ; + unsigned nopts) hidden; int selabel_property_init(struct selabel_handle *rec, const struct selinux_opt *opts, - unsigned nopts) ; + unsigned nopts) hidden; int selabel_exact_match_init(struct selabel_handle *rec, const struct selinux_opt *opts, - unsigned nopts) ; + unsigned nopts) hidden; /* * Labeling internal structures @@ -121,26 +122,24 @@ struct selabel_handle { */ extern int selabel_validate(struct selabel_handle *rec, - struct selabel_lookup_rec *contexts) ; + struct selabel_lookup_rec *contexts) hidden; /* * Compatibility support */ extern int myprintf_compat; extern void __attribute__ ((format(printf, 1, 2))) -(*myprintf) (const char *fmt, ...) ; +(*myprintf) (const char *fmt, ...) hidden; -#define COMPAT_LOG(type, fmt...) do { \ - if (myprintf_compat) \ - myprintf(fmt); \ - else \ - selinux_log(type, fmt); \ - } while (0) +#define COMPAT_LOG(type, fmt...) if (myprintf_compat) \ + myprintf(fmt); \ + else \ + selinux_log(type, fmt); extern int compat_validate(struct selabel_handle *rec, struct selabel_lookup_rec *contexts, - const char *path, unsigned lineno) ; + const char *path, unsigned lineno) hidden; /* * The read_spec_entries function may be used to diff --git a/libselinux/src/label_media.c b/libselinux/src/label_media.c index eb27deaf..d202e5d5 100644 --- a/libselinux/src/label_media.c +++ b/libselinux/src/label_media.c @@ -119,6 +119,7 @@ static int init(struct selabel_handle *rec, const struct selinux_opt *opts, if (process_line(path, line_buf, pass, ++lineno, rec)) goto finish; } + lineno = 0; if (pass == 0) { if (data->nspec == 0) { diff --git a/libselinux/src/label_support.c b/libselinux/src/label_support.c index 94ed6e42..26f9ef15 100644 --- a/libselinux/src/label_support.c +++ b/libselinux/src/label_support.c @@ -63,7 +63,7 @@ static inline int read_spec_entry(char **entry, char **ptr, int *len, const char * This function calls read_spec_entry() to do the actual string processing. * As such, can return anything from that function as well. */ -int read_spec_entries(char *line_buf, const char **errbuf, int num_args, ...) +int hidden read_spec_entries(char *line_buf, const char **errbuf, int num_args, ...) { char **spec_entry, *buf_p; int len, rc, items, entry_len = 0; @@ -113,7 +113,7 @@ int read_spec_entries(char *line_buf, const char **errbuf, int num_args, ...) } /* Once all the specfiles are in the hash_buf, generate the hash. */ -void digest_gen_hash(struct selabel_digest *digest) +void hidden digest_gen_hash(struct selabel_digest *digest) { Sha1Context context; @@ -141,7 +141,7 @@ void digest_gen_hash(struct selabel_digest *digest) * * Return %0 on success, -%1 with @errno set on failure. */ -int digest_add_specfile(struct selabel_digest *digest, FILE *fp, +int hidden digest_add_specfile(struct selabel_digest *digest, FILE *fp, char *from_addr, size_t buf_len, const char *path) { diff --git a/libselinux/src/label_x.c b/libselinux/src/label_x.c index e9fa063f..96745299 100644 --- a/libselinux/src/label_x.c +++ b/libselinux/src/label_x.c @@ -146,6 +146,7 @@ static int init(struct selabel_handle *rec, const struct selinux_opt *opts, if (process_line(path, line_buf, pass, ++lineno, rec)) goto finish; } + lineno = 0; if (pass == 0) { if (data->nspec == 0) { diff --git a/libselinux/src/lgetfilecon.c b/libselinux/src/lgetfilecon.c index d1fb821b..db67bc60 100644 --- a/libselinux/src/lgetfilecon.c +++ b/libselinux/src/lgetfilecon.c @@ -49,6 +49,7 @@ int lgetfilecon_raw(const char *path, char ** context) return ret; } +hidden_def(lgetfilecon_raw) int lgetfilecon(const char *path, char ** context) { diff --git a/libselinux/src/libselinux.map b/libselinux/src/libselinux.map deleted file mode 100644 index 2a368e93..00000000 --- a/libselinux/src/libselinux.map +++ /dev/null @@ -1,242 +0,0 @@ -LIBSELINUX_1.0 { - global: - avc_add_callback; - avc_audit; - avc_av_stats; - avc_cache_stats; - avc_cleanup; - avc_compute_create; - avc_compute_member; - avc_context_to_sid; - avc_context_to_sid_raw; - avc_destroy; - avc_get_initial_sid; - avc_has_perm; - avc_has_perm_noaudit; - avc_init; - avc_netlink_acquire_fd; - avc_netlink_check_nb; - avc_netlink_close; - avc_netlink_loop; - avc_netlink_open; - avc_netlink_release_fd; - avc_open; - avc_reset; - avc_sid_stats; - avc_sid_to_context; - avc_sid_to_context_raw; - checkPasswdAccess; - context_free; - context_new; - context_range_get; - context_range_set; - context_role_get; - context_role_set; - context_str; - context_type_get; - context_type_set; - context_user_get; - context_user_set; - fgetfilecon; - fgetfilecon_raw; - fini_selinuxmnt; - freecon; - freeconary; - fsetfilecon; - fsetfilecon_raw; - getcon; - getcon_raw; - get_default_context; - get_default_context_with_level; - get_default_context_with_role; - get_default_context_with_rolelevel; - get_default_type; - getexeccon; - getexeccon_raw; - getfilecon; - getfilecon_raw; - getfscreatecon; - getfscreatecon_raw; - getkeycreatecon; - getkeycreatecon_raw; - get_ordered_context_list; - get_ordered_context_list_with_level; - getpeercon; - getpeercon_raw; - getpidcon; - getpidcon_raw; - getprevcon; - getprevcon_raw; - getseuser; - getseuserbyname; - getsockcreatecon; - getsockcreatecon_raw; - is_context_customizable; - is_selinux_enabled; - is_selinux_mls_enabled; - lgetfilecon; - lgetfilecon_raw; - lsetfilecon; - lsetfilecon_raw; - manual_user_enter_context; - matchmediacon; - matchpathcon; - matchpathcon_checkmatches; - matchpathcon_filespec_add; - matchpathcon_filespec_destroy; - matchpathcon_filespec_eval; - matchpathcon_fini; - matchpathcon_index; - matchpathcon_init; - matchpathcon_init_prefix; - mode_to_security_class; - print_access_vector; - query_user_context; - realpath_not_final; - rpm_execcon; - security_av_perm_to_string; - security_av_string; - security_canonicalize_context; - security_canonicalize_context_raw; - security_check_context; - security_check_context_raw; - security_class_to_string; - security_commit_booleans; - security_compute_av; - security_compute_av_flags; - security_compute_av_flags_raw; - security_compute_av_raw; - security_compute_create; - security_compute_create_name; - security_compute_create_name_raw; - security_compute_create_raw; - security_compute_member; - security_compute_member_raw; - security_compute_relabel; - security_compute_relabel_raw; - security_compute_user; - security_compute_user_raw; - security_deny_unknown; - security_disable; - security_get_boolean_active; - security_get_boolean_names; - security_get_boolean_pending; - security_get_checkreqprot; - security_getenforce; - security_get_initial_context; - security_get_initial_context_raw; - security_load_booleans; - security_load_policy; - security_policyvers; - security_reject_unknown; - security_set_boolean; - security_set_boolean_list; - security_setenforce; - security_validatetrans; - security_validatetrans_raw; - selabel_close; - selabel_cmp; - selabel_digest; - selabel_get_digests_all_partial_matches; - selabel_hash_all_partial_matches; - selabel_lookup; - selabel_lookup_best_match; - selabel_lookup_best_match_raw; - selabel_lookup_raw; - selabel_open; - selabel_partial_match; - selabel_stats; - selinux_binary_policy_path; - selinux_booleans_path; - selinux_booleans_subs_path; - selinux_boolean_sub; - selinux_check_access; - selinux_check_passwd_access; - selinux_check_securetty_context; - selinux_colors_path; - selinux_contexts_path; - selinux_current_policy_path; - selinux_customizable_types_path; - selinux_default_context_path; - selinux_default_type_path; - selinux_failsafe_context_path; - selinux_file_context_cmp; - selinux_file_context_homedir_path; - selinux_file_context_local_path; - selinux_file_context_path; - selinux_file_context_subs_dist_path; - selinux_file_context_subs_path; - selinux_file_context_verify; - selinux_flush_class_cache; - selinuxfs_exists; - selinux_get_callback; - selinux_getenforcemode; - selinux_getpolicytype; - selinux_homedir_context_path; - selinux_init_load_policy; - selinux_lsetfilecon_default; - selinux_lxc_contexts_path; - selinux_media_context_path; - selinux_mkload_policy; - selinux_mnt; - selinux_netfilter_context_path; - selinux_openrc_contexts_path; - selinux_openssh_contexts_path; - selinux_path; - selinux_policy_root; - selinux_raw_context_to_color; - selinux_raw_to_trans_context; - selinux_removable_context_path; - selinux_reset_config; - selinux_restorecon; - selinux_restorecon_default_handle; - selinux_restorecon_set_alt_rootpath; - selinux_restorecon_set_exclude_list; - selinux_restorecon_set_sehandle; - selinux_restorecon_xattr; - selinux_securetty_types_path; - selinux_sepgsql_context_path; - selinux_set_callback; - selinux_set_mapping; - selinux_set_policy_root; - selinux_snapperd_contexts_path; - selinux_status_close; - selinux_status_deny_unknown; - selinux_status_getenforce; - selinux_status_open; - selinux_status_policyload; - selinux_status_updated; - selinux_systemd_contexts_path; - selinux_translations_path; - selinux_trans_to_raw_context; - selinux_user_contexts_path; - selinux_usersconf_path; - selinux_users_path; - selinux_virtual_domain_context_path; - selinux_virtual_image_context_path; - selinux_x_context_path; - setcon; - setcon_raw; - setexeccon; - setexeccon_raw; - setexecfilecon; - setfilecon; - setfilecon_raw; - setfscreatecon; - setfscreatecon_raw; - setkeycreatecon; - setkeycreatecon_raw; - set_matchpathcon_canoncon; - set_matchpathcon_flags; - set_matchpathcon_invalidcon; - set_matchpathcon_printf; - set_selinuxmnt; - setsockcreatecon; - setsockcreatecon_raw; - sidget; - sidput; - string_to_av_perm; - string_to_security_class; - local: - *; -}; diff --git a/libselinux/src/load_policy.c b/libselinux/src/load_policy.c index d8c715ed..9e75292d 100644 --- a/libselinux/src/load_policy.c +++ b/libselinux/src/load_policy.c @@ -45,6 +45,7 @@ int security_load_policy(void *data, size_t len) return 0; } +hidden_def(security_load_policy) #ifndef ANDROID #undef max @@ -76,11 +77,11 @@ int selinux_mkload_policy(int preservebools __attribute__((unused))) #ifdef SHARED char *errormsg = NULL; void *libsepolh = NULL; - libsepolh = dlopen("libsepol.so.2", RTLD_NOW); + libsepolh = dlopen("libsepol.so.1", RTLD_NOW); if (libsepolh) { usesepol = 1; dlerror(); -#define DLERR() do { if ((errormsg = dlerror())) goto dlclose; } while (0) +#define DLERR() if ((errormsg = dlerror())) goto dlclose; vers_max = dlsym(libsepolh, "sepol_policy_kern_vers_max"); DLERR(); vers_min = dlsym(libsepolh, "sepol_policy_kern_vers_min"); @@ -137,15 +138,15 @@ int selinux_mkload_policy(int preservebools __attribute__((unused))) } if (fd < 0) { fprintf(stderr, - "SELinux: Could not open policy file <= %s.%d: %m\n", - selinux_binary_policy_path(), maxvers); + "SELinux: Could not open policy file <= %s.%d: %s\n", + selinux_binary_policy_path(), maxvers, strerror(errno)); goto dlclose; } if (fstat(fd, &sb) < 0) { fprintf(stderr, - "SELinux: Could not stat policy file %s: %m\n", - path); + "SELinux: Could not stat policy file %s: %s\n", + path, strerror(errno)); goto close; } @@ -153,8 +154,8 @@ int selinux_mkload_policy(int preservebools __attribute__((unused))) data = map = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); if (map == MAP_FAILED) { fprintf(stderr, - "SELinux: Could not map policy file %s: %m\n", - path); + "SELinux: Could not map policy file %s: %s\n", + path, strerror(errno)); goto close; } @@ -193,8 +194,8 @@ int selinux_mkload_policy(int preservebools __attribute__((unused))) if (rc) fprintf(stderr, - "SELinux: Could not load policy file %s: %m\n", - path); + "SELinux: Could not load policy file %s: %s\n", + path, strerror(errno)); unmap: if (data != map) @@ -212,6 +213,7 @@ int selinux_mkload_policy(int preservebools __attribute__((unused))) return rc; } +hidden_def(selinux_mkload_policy) /* * Mount point for selinuxfs. @@ -279,8 +281,7 @@ int selinux_init_load_policy(int *enforce) const char *mntpoint = NULL; /* First make sure /sys is mounted */ if (mount("sysfs", "/sys", "sysfs", 0, 0) == 0 || errno == EBUSY) { - /* MS_NODEV can't be set because of /sys/fs/selinux/null device, used by Android */ - if (mount(SELINUXFS, SELINUXMNT, SELINUXFS, MS_NOEXEC | MS_NOSUID, 0) == 0 || errno == EBUSY) { + if (mount(SELINUXFS, SELINUXMNT, SELINUXFS, 0, 0) == 0 || errno == EBUSY) { mntpoint = SELINUXMNT; } else { /* check old mountpoint */ @@ -306,7 +307,7 @@ int selinux_init_load_policy(int *enforce) *enforce = 0; } else { /* Only emit this error if selinux was not disabled */ - fprintf(stderr, "Mount failed for selinuxfs on %s: %m\n", SELINUXMNT); + fprintf(stderr, "Mount failed for selinuxfs on %s: %s\n", SELINUXMNT, strerror(errno)); } if (rc == 0) @@ -352,7 +353,7 @@ int selinux_init_load_policy(int *enforce) if (orig_enforce != *enforce) { rc = security_setenforce(*enforce); if (rc < 0) { - fprintf(stderr, "SELinux: Unable to switch to %s mode: %m\n", (*enforce ? "enforcing" : "permissive")); + fprintf(stderr, "SELinux: Unable to switch to %s mode: %s\n", (*enforce ? "enforcing" : "permissive"), strerror(errno)); if (*enforce) goto noload; } diff --git a/libselinux/src/lsetfilecon.c b/libselinux/src/lsetfilecon.c index 213fb684..1d3b28a1 100644 --- a/libselinux/src/lsetfilecon.c +++ b/libselinux/src/lsetfilecon.c @@ -25,6 +25,7 @@ int lsetfilecon_raw(const char *path, const char * context) return rc; } +hidden_def(lsetfilecon_raw) int lsetfilecon(const char *path, const char *context) { diff --git a/libselinux/src/matchmediacon.c b/libselinux/src/matchmediacon.c index d3d95043..23d01af4 100644 --- a/libselinux/src/matchmediacon.c +++ b/libselinux/src/matchmediacon.c @@ -22,7 +22,6 @@ int matchmediacon(const char *media, char ** con) return -1; while (!feof_unlocked(infile)) { if (!fgets_unlocked(current_line, sizeof(current_line), infile)) { - fclose(infile); return -1; } if (current_line[strlen(current_line) - 1]) diff --git a/libselinux/src/matchpathcon.c b/libselinux/src/matchpathcon.c index 1e7f8890..05a5cfa4 100644 --- a/libselinux/src/matchpathcon.c +++ b/libselinux/src/matchpathcon.c @@ -78,30 +78,17 @@ static pthread_once_t once = PTHREAD_ONCE_INIT; static pthread_key_t destructor_key; static int destructor_key_initialized = 0; -static void free_array_elts(void) -{ - int i; - for (i = 0; i < con_array_used; i++) - free(con_array[i]); - free(con_array); - - con_array_size = con_array_used = 0; - con_array = NULL; -} - static int add_array_elt(char *con) { - char **tmp; if (con_array_size) { while (con_array_used >= con_array_size) { con_array_size *= 2; - tmp = (char **)realloc(con_array, sizeof(char*) * + con_array = (char **)realloc(con_array, sizeof(char*) * con_array_size); - if (!tmp) { - free_array_elts(); + if (!con_array) { + con_array_size = con_array_used = 0; return -1; } - con_array = tmp; } } else { con_array_size = 1000; @@ -118,6 +105,13 @@ static int add_array_elt(char *con) return con_array_used++; } +static void free_array_elts(void) +{ + con_array_size = con_array_used = 0; + free(con_array); + con_array = NULL; +} + void set_matchpathcon_invalidcon(int (*f) (const char *p, unsigned l, char *c)) { myinvalidcon = f; @@ -321,24 +315,14 @@ void matchpathcon_filespec_destroy(void) fl_head = NULL; } -static void matchpathcon_fini_internal(void) -{ - free_array_elts(); - - if (hnd) { - selabel_close(hnd); - hnd = NULL; - } -} - static void matchpathcon_thread_destructor(void __attribute__((unused)) *ptr) { - matchpathcon_fini_internal(); + matchpathcon_fini(); } void __attribute__((destructor)) matchpathcon_lib_destructor(void); -void __attribute__((destructor)) matchpathcon_lib_destructor(void) +void hidden __attribute__((destructor)) matchpathcon_lib_destructor(void) { if (destructor_key_initialized) __selinux_key_delete(destructor_key); @@ -367,6 +351,7 @@ int matchpathcon_init_prefix(const char *path, const char *subset) return hnd ? 0 : -1; } +hidden_def(matchpathcon_init_prefix) int matchpathcon_init(const char *path) { @@ -375,7 +360,12 @@ int matchpathcon_init(const char *path) void matchpathcon_fini(void) { - matchpathcon_fini_internal(); + free_array_elts(); + + if (hnd) { + selabel_close(hnd); + hnd = NULL; + } } /* @@ -393,8 +383,8 @@ int realpath_not_final(const char *name, char *resolved_path) tmp_path = strdup(name); if (!tmp_path) { - myprintf("symlink_realpath(%s) strdup() failed: %m\n", - name); + myprintf("symlink_realpath(%s) strdup() failed: %s\n", + name, strerror(errno)); rc = -1; goto out; } @@ -414,8 +404,8 @@ int realpath_not_final(const char *name, char *resolved_path) } if (!p) { - myprintf("symlink_realpath(%s) realpath() failed: %m\n", - name); + myprintf("symlink_realpath(%s) realpath() failed: %s\n", + name, strerror(errno)); rc = -1; goto out; } @@ -438,7 +428,7 @@ out: return rc; } -static int matchpathcon_internal(const char *path, mode_t mode, char ** con) +int matchpathcon(const char *path, mode_t mode, char ** con) { char stackpath[PATH_MAX + 1]; char *p = NULL; @@ -459,13 +449,9 @@ static int matchpathcon_internal(const char *path, mode_t mode, char ** con) selabel_lookup(hnd, con, path, mode); } -int matchpathcon(const char *path, mode_t mode, char ** con) { - return matchpathcon_internal(path, mode, con); -} - int matchpathcon_index(const char *name, mode_t mode, char ** con) { - int i = matchpathcon_internal(name, mode, con); + int i = matchpathcon(name, mode, con); if (i < 0) return -1; @@ -483,15 +469,15 @@ void matchpathcon_checkmatches(char *str __attribute__((unused))) int selinux_file_context_cmp(const char * a, const char * b) { - const char *rest_a, *rest_b; /* Rest of the context after the user */ + char *rest_a, *rest_b; /* Rest of the context after the user */ if (!a && !b) return 0; if (!a) return -1; if (!b) return 1; - rest_a = strchr(a, ':'); - rest_b = strchr(b, ':'); + rest_a = strchr((char *)a, ':'); + rest_b = strchr((char *)b, ':'); if (!rest_a && !rest_b) return 0; if (!rest_a) diff --git a/libselinux/src/policyvers.c b/libselinux/src/policyvers.c index e5aa2f3f..c97dd9df 100644 --- a/libselinux/src/policyvers.c +++ b/libselinux/src/policyvers.c @@ -7,6 +7,7 @@ #include "selinux_internal.h" #include #include "policy.h" +#include "dso.h" #include int security_policyvers(void) @@ -41,3 +42,4 @@ int security_policyvers(void) return vers; } +hidden_def(security_policyvers) diff --git a/libselinux/src/procattr.c b/libselinux/src/procattr.c index 6552ee01..c6799ef2 100644 --- a/libselinux/src/procattr.c +++ b/libselinux/src/procattr.c @@ -25,23 +25,21 @@ static __thread char destructor_initialized; /* Bionic and glibc >= 2.30 declare gettid() system call wrapper in unistd.h and * has a definition for it */ #ifdef __BIONIC__ - #define HAVE_GETTID 1 + #define OVERRIDE_GETTID 0 #elif !defined(__GLIBC_PREREQ) - #define HAVE_GETTID 0 + #define OVERRIDE_GETTID 1 #elif !__GLIBC_PREREQ(2,30) - #define HAVE_GETTID 0 + #define OVERRIDE_GETTID 1 #else - #define HAVE_GETTID 1 + #define OVERRIDE_GETTID 0 #endif -static pid_t selinux_gettid(void) +#if OVERRIDE_GETTID +static pid_t gettid(void) { -#if HAVE_GETTID - return gettid(); -#else return syscall(__NR_gettid); -#endif } +#endif static void procattr_thread_destructor(void __attribute__((unused)) *unused) { @@ -59,7 +57,7 @@ static void procattr_thread_destructor(void __attribute__((unused)) *unused) void __attribute__((destructor)) procattr_destructor(void); -void __attribute__((destructor)) procattr_destructor(void) +void hidden __attribute__((destructor)) procattr_destructor(void) { if (destructor_key_initialized) __selinux_key_delete(destructor_key); @@ -96,7 +94,7 @@ static int openattr(pid_t pid, const char *attr, int flags) if (fd >= 0 || errno != ENOENT) goto out; free(path); - tid = selinux_gettid(); + tid = gettid(); rc = asprintf(&path, "/proc/self/task/%d/attr/%s", tid, attr); } else { errno = EINVAL; @@ -146,7 +144,7 @@ static int getprocattrcon_raw(char ** context, default: errno = ENOENT; return -1; - } + }; if (prev_context && prev_context != UNSET) { *context = strdup(prev_context); @@ -240,7 +238,7 @@ static int setprocattrcon_raw(const char * context, default: errno = ENOENT; return -1; - } + }; if (!context && !*prev_context) return 0; @@ -347,3 +345,22 @@ all_selfattr_def(con, current) all_selfattr_def(sockcreatecon, sockcreate) all_selfattr_def(keycreatecon, keycreate) + hidden_def(getcon_raw) + hidden_def(getcon) + hidden_def(getexeccon_raw) + hidden_def(getfilecon_raw) + hidden_def(getfilecon) + hidden_def(getfscreatecon_raw) + hidden_def(getkeycreatecon_raw) + hidden_def(getpeercon_raw) + hidden_def(getpidcon_raw) + hidden_def(getprevcon_raw) + hidden_def(getprevcon) + hidden_def(getsockcreatecon_raw) + hidden_def(setcon_raw) + hidden_def(setexeccon_raw) + hidden_def(setexeccon) + hidden_def(setfilecon_raw) + hidden_def(setfscreatecon_raw) + hidden_def(setkeycreatecon_raw) + hidden_def(setsockcreatecon_raw) diff --git a/libselinux/src/regex.c b/libselinux/src/regex.c index 73987d9f..770bc3ea 100644 --- a/libselinux/src/regex.c +++ b/libselinux/src/regex.c @@ -319,7 +319,7 @@ char const *regex_version(void) } int regex_load_mmap(struct mmap_area *mmap_area, struct regex_data **regex, - int do_load_precompregex __attribute__((unused)), bool *regex_compiled) + int unused __attribute__((unused)), bool *regex_compiled) { int rc; uint32_t entry_len; @@ -387,7 +387,7 @@ static inline pcre_extra *get_pcre_extra(struct regex_data *regex) } int regex_writef(struct regex_data *regex, FILE *fp, - int do_write_precompregex __attribute__((unused))) + int unused __attribute__((unused))) { int rc; size_t len; diff --git a/libselinux/src/regex.h b/libselinux/src/regex.h index 2dfa2534..6732b349 100644 --- a/libselinux/src/regex.h +++ b/libselinux/src/regex.h @@ -10,6 +10,7 @@ #include #endif +#include "dso.h" enum { REGEX_MATCH, REGEX_MATCH_PARTIAL, @@ -41,10 +42,10 @@ struct mmap_area; * expressions are not portable across architectures that do not have a * matching arch-string. */ -char const *regex_arch_string(void) ; +char const *regex_arch_string(void) hidden; /** - * regex_version returns the version string of the underlying regular + * regex_verison returns the version string of the underlying regular * regular expressions library. In the case of PCRE it just returns the * result of pcre_version(). In the case of PCRE2, the very first time this * function is called it allocates a buffer large enough to hold the version @@ -54,12 +55,12 @@ char const *regex_arch_string(void) ; * * It may return NULL on error. */ -char const *regex_version(void) ; +char const *regex_version(void) hidden; /** * This constructor function allocates a buffer for a regex_data structure. * The buffer is being initialized with zeroes. */ -struct regex_data *regex_data_create(void) ; +struct regex_data *regex_data_create(void) hidden; /** * This complementary destructor function frees the a given regex_data buffer. * It also frees any non NULL member pointers with the appropriate pcreX_X_free @@ -67,7 +68,7 @@ struct regex_data *regex_data_create(void) ; * the pcre_extra data conditionally. Calling this function on a NULL pointer is * save. */ -void regex_data_free(struct regex_data *regex) ; +void regex_data_free(struct regex_data *regex) hidden; /** * This function compiles the regular expression. Additionally, it prepares * data structures required by the different underlying engines. For PCRE @@ -87,7 +88,7 @@ void regex_data_free(struct regex_data *regex) ; * @retval -1 on error */ int regex_prepare_data(struct regex_data **regex, char const *pattern_string, - struct regex_error_data *errordata) ; + struct regex_error_data *errordata) hidden; /** * This function loads a serialized precompiled pattern from a contiguous * data region given by map_area. @@ -108,7 +109,7 @@ int regex_prepare_data(struct regex_data **regex, char const *pattern_string, int regex_load_mmap(struct mmap_area *map_area, struct regex_data **regex, int do_load_precompregex, - bool *regex_compiled) ; + bool *regex_compiled) hidden; /** * This function stores a precompiled regular expression to a file. * In the case of PCRE, it just dumps the binary representation of the @@ -121,7 +122,7 @@ int regex_load_mmap(struct mmap_area *map_area, * the output file (ignored by PCRE1 back-end). */ int regex_writef(struct regex_data *regex, FILE *fp, - int do_write_precompregex) ; + int do_write_precompregex) hidden; /** * This function applies a precompiled pattern to a subject string and * returns whether or not a match was found. @@ -138,7 +139,7 @@ int regex_writef(struct regex_data *regex, FILE *fp, * regular expression */ int regex_match(struct regex_data *regex, char const *subject, - int partial) ; + int partial) hidden; /** * This function compares two compiled regular expressions (regex1 and regex2). * It compares the binary representations of the compiled patterns. It is a very @@ -149,7 +150,7 @@ int regex_match(struct regex_data *regex, char const *subject, * the same * @retval SELABEL_INCOMPARABLE otherwise */ -int regex_cmp(struct regex_data *regex1, struct regex_data *regex2) ; +int regex_cmp(struct regex_data *regex1, struct regex_data *regex2) hidden; /** * This function takes the error data returned by regex_prepare_data and turns * it in to a human readable error message. @@ -162,5 +163,5 @@ int regex_cmp(struct regex_data *regex1, struct regex_data *regex2) ; * @arg buf_size Total size of the given buffer in bytes. */ void regex_format_error(struct regex_error_data const *error_data, char *buffer, - size_t buf_size) ; + size_t buf_size) hidden; #endif /* SRC_REGEX_H_ */ diff --git a/libselinux/src/reject_unknown.c b/libselinux/src/reject_unknown.c index 96e60be3..5c1d3605 100644 --- a/libselinux/src/reject_unknown.c +++ b/libselinux/src/reject_unknown.c @@ -37,3 +37,4 @@ int security_reject_unknown(void) return reject_unknown; } +hidden_def(security_reject_unknown); diff --git a/libselinux/src/selinux_check_securetty_context.c b/libselinux/src/selinux_check_securetty_context.c index c5c557fd..55d4e039 100644 --- a/libselinux/src/selinux_check_securetty_context.c +++ b/libselinux/src/selinux_check_securetty_context.c @@ -50,3 +50,4 @@ int selinux_check_securetty_context(const char * tty_context) return found; } +hidden_def(selinux_check_securetty_context) diff --git a/libselinux/src/selinux_config.c b/libselinux/src/selinux_config.c index 97f81a8b..b16a3851 100644 --- a/libselinux/src/selinux_config.c +++ b/libselinux/src/selinux_config.c @@ -128,6 +128,7 @@ int selinux_getenforcemode(int *enforce) return ret; } +hidden_def(selinux_getenforcemode) static char *selinux_policytype; @@ -140,6 +141,7 @@ int selinux_getpolicytype(char **type) return *type ? 0 : -1; } +hidden_def(selinux_getpolicytype) static int setpolicytype(const char *type) { @@ -177,11 +179,8 @@ static void init_selinux_config(void) if (!strncasecmp(buf_p, SELINUXTYPETAG, sizeof(SELINUXTYPETAG) - 1)) { type = strdup(buf_p + sizeof(SELINUXTYPETAG) - 1); - if (!type) { - free(line_buf); - fclose(fp); + if (!type) return; - } end = type + strlen(type) - 1; while ((end > type) && (isspace(*end) || iscntrl(*end))) { @@ -190,8 +189,6 @@ static void init_selinux_config(void) } if (setpolicytype(type) != 0) { free(type); - free(line_buf); - fclose(fp); return; } free(type); @@ -252,6 +249,7 @@ void selinux_reset_config(void) init_selinux_config(); } +hidden_def(selinux_reset_config) static const char *get_path(int idx) { @@ -264,6 +262,7 @@ const char *selinux_default_type_path(void) return get_path(DEFAULT_TYPE); } +hidden_def(selinux_default_type_path) const char *selinux_policy_root(void) { @@ -306,36 +305,42 @@ const char *selinux_path(void) return selinux_rootpath; } +hidden_def(selinux_path) const char *selinux_default_context_path(void) { return get_path(DEFAULT_CONTEXTS); } +hidden_def(selinux_default_context_path) const char *selinux_securetty_types_path(void) { return get_path(SECURETTY_TYPES); } +hidden_def(selinux_securetty_types_path) const char *selinux_failsafe_context_path(void) { return get_path(FAILSAFE_CONTEXT); } +hidden_def(selinux_failsafe_context_path) const char *selinux_removable_context_path(void) { return get_path(REMOVABLE_CONTEXT); } +hidden_def(selinux_removable_context_path) const char *selinux_binary_policy_path(void) { return get_path(BINPOLICY); } +hidden_def(selinux_binary_policy_path) const char *selinux_current_policy_path(void) { @@ -360,30 +365,35 @@ const char *selinux_current_policy_path(void) return policy_path; } +hidden_def(selinux_current_policy_path) const char *selinux_file_context_path(void) { return get_path(FILE_CONTEXTS); } +hidden_def(selinux_file_context_path) const char *selinux_homedir_context_path(void) { return get_path(HOMEDIR_CONTEXTS); } +hidden_def(selinux_homedir_context_path) const char *selinux_media_context_path(void) { return get_path(MEDIA_CONTEXTS); } +hidden_def(selinux_media_context_path) const char *selinux_customizable_types_path(void) { return get_path(CUSTOMIZABLE_TYPES); } +hidden_def(selinux_customizable_types_path) const char *selinux_contexts_path(void) { @@ -395,6 +405,7 @@ const char *selinux_user_contexts_path(void) return get_path(USER_CONTEXTS); } +hidden_def(selinux_user_contexts_path) /* Deprecated as local policy booleans no longer supported. */ const char *selinux_booleans_path(void) @@ -402,6 +413,7 @@ const char *selinux_booleans_path(void) return get_path(BOOLEANS); } +hidden_def(selinux_booleans_path) /* Deprecated as no longer supported. */ const char *selinux_users_path(void) @@ -409,108 +421,127 @@ const char *selinux_users_path(void) return get_path(USERS_DIR); } +hidden_def(selinux_users_path) const char *selinux_usersconf_path(void) { return get_path(SEUSERS); } +hidden_def(selinux_usersconf_path) const char *selinux_translations_path(void) { return get_path(TRANSLATIONS); } +hidden_def(selinux_translations_path) const char *selinux_colors_path(void) { return get_path(COLORS); } +hidden_def(selinux_colors_path) const char *selinux_netfilter_context_path(void) { return get_path(NETFILTER_CONTEXTS); } +hidden_def(selinux_netfilter_context_path) const char *selinux_file_context_homedir_path(void) { return get_path(FILE_CONTEXTS_HOMEDIR); } +hidden_def(selinux_file_context_homedir_path) const char *selinux_file_context_local_path(void) { return get_path(FILE_CONTEXTS_LOCAL); } +hidden_def(selinux_file_context_local_path) const char *selinux_x_context_path(void) { return get_path(X_CONTEXTS); } +hidden_def(selinux_x_context_path) const char *selinux_virtual_domain_context_path(void) { return get_path(VIRTUAL_DOMAIN); } +hidden_def(selinux_virtual_domain_context_path) const char *selinux_virtual_image_context_path(void) { return get_path(VIRTUAL_IMAGE); } +hidden_def(selinux_virtual_image_context_path) const char *selinux_lxc_contexts_path(void) { return get_path(LXC_CONTEXTS); } +hidden_def(selinux_lxc_contexts_path) const char *selinux_openrc_contexts_path(void) { return get_path(OPENRC_CONTEXTS); } +hidden_def(selinux_openrc_contexts_path) const char *selinux_openssh_contexts_path(void) { return get_path(OPENSSH_CONTEXTS); } +hidden_def(selinux_openssh_contexts_path) const char *selinux_snapperd_contexts_path(void) { return get_path(SNAPPERD_CONTEXTS); } +hidden_def(selinux_snapperd_contexts_path) const char *selinux_systemd_contexts_path(void) { return get_path(SYSTEMD_CONTEXTS); } +hidden_def(selinux_systemd_contexts_path) const char * selinux_booleans_subs_path(void) { return get_path(BOOLEAN_SUBS); } +hidden_def(selinux_booleans_subs_path) const char * selinux_file_context_subs_path(void) { return get_path(FILE_CONTEXT_SUBS); } +hidden_def(selinux_file_context_subs_path) const char * selinux_file_context_subs_dist_path(void) { return get_path(FILE_CONTEXT_SUBS_DIST); } +hidden_def(selinux_file_context_subs_dist_path) const char *selinux_sepgsql_context_path(void) { return get_path(SEPGSQL_CONTEXTS); } +hidden_def(selinux_sepgsql_context_path) diff --git a/libselinux/src/selinux_internal.h b/libselinux/src/selinux_internal.h index 27e9ac53..61b78aaa 100644 --- a/libselinux/src/selinux_internal.h +++ b/libselinux/src/selinux_internal.h @@ -1,9 +1,116 @@ #include #include +#include "dso.h" +hidden_proto(selinux_mkload_policy) + hidden_proto(fini_selinuxmnt) + hidden_proto(set_selinuxmnt) + hidden_proto(selinuxfs_exists) + hidden_proto(security_disable) + hidden_proto(security_policyvers) + hidden_proto(security_load_policy) + hidden_proto(security_get_boolean_active) + hidden_proto(security_get_boolean_names) + hidden_proto(security_set_boolean) + hidden_proto(security_commit_booleans) + hidden_proto(security_check_context) + hidden_proto(security_check_context_raw) + hidden_proto(security_canonicalize_context) + hidden_proto(security_canonicalize_context_raw) + hidden_proto(security_compute_av) + hidden_proto(security_compute_av_raw) + hidden_proto(security_compute_av_flags) + hidden_proto(security_compute_av_flags_raw) + hidden_proto(security_compute_user) + hidden_proto(security_compute_user_raw) + hidden_proto(security_compute_create) + hidden_proto(security_compute_create_raw) + hidden_proto(security_compute_create_name) + hidden_proto(security_compute_create_name_raw) + hidden_proto(security_compute_member_raw) + hidden_proto(security_compute_relabel_raw) + hidden_proto(security_validatetrans) + hidden_proto(security_validatetrans_raw) + hidden_proto(is_selinux_enabled) + hidden_proto(is_selinux_mls_enabled) + hidden_proto(freecon) + hidden_proto(freeconary) + hidden_proto(getprevcon) + hidden_proto(getprevcon_raw) + hidden_proto(getcon) + hidden_proto(getcon_raw) + hidden_proto(setcon_raw) + hidden_proto(getpeercon_raw) + hidden_proto(getpidcon_raw) + hidden_proto(getexeccon_raw) + hidden_proto(getfilecon) + hidden_proto(getfilecon_raw) + hidden_proto(lgetfilecon_raw) + hidden_proto(fgetfilecon_raw) + hidden_proto(setfilecon_raw) + hidden_proto(lsetfilecon_raw) + hidden_proto(fsetfilecon_raw) + hidden_proto(setexeccon) + hidden_proto(setexeccon_raw) + hidden_proto(getfscreatecon_raw) + hidden_proto(getkeycreatecon_raw) + hidden_proto(getsockcreatecon_raw) + hidden_proto(setfscreatecon_raw) + hidden_proto(setkeycreatecon_raw) + hidden_proto(setsockcreatecon_raw) + hidden_proto(security_getenforce) + hidden_proto(security_setenforce) + hidden_proto(security_deny_unknown) + hidden_proto(security_reject_unknown) + hidden_proto(security_get_checkreqprot) + hidden_proto(selinux_boolean_sub) + hidden_proto(selinux_current_policy_path) + hidden_proto(selinux_binary_policy_path) + hidden_proto(selinux_booleans_subs_path) + hidden_proto(selinux_default_context_path) + hidden_proto(selinux_securetty_types_path) + hidden_proto(selinux_failsafe_context_path) + hidden_proto(selinux_removable_context_path) + hidden_proto(selinux_virtual_domain_context_path) + hidden_proto(selinux_virtual_image_context_path) + hidden_proto(selinux_lxc_contexts_path) + hidden_proto(selinux_file_context_path) + hidden_proto(selinux_file_context_homedir_path) + hidden_proto(selinux_file_context_local_path) + hidden_proto(selinux_file_context_subs_dist_path) + hidden_proto(selinux_file_context_subs_path) + hidden_proto(selinux_netfilter_context_path) + hidden_proto(selinux_homedir_context_path) + hidden_proto(selinux_user_contexts_path) + hidden_proto(selinux_booleans_path) + hidden_proto(selinux_customizable_types_path) + hidden_proto(selinux_media_context_path) + hidden_proto(selinux_x_context_path) + hidden_proto(selinux_sepgsql_context_path) + hidden_proto(selinux_openrc_contexts_path) + hidden_proto(selinux_openssh_contexts_path) + hidden_proto(selinux_snapperd_contexts_path) + hidden_proto(selinux_systemd_contexts_path) + hidden_proto(selinux_path) + hidden_proto(selinux_check_passwd_access) + hidden_proto(selinux_check_securetty_context) + hidden_proto(matchpathcon_init_prefix) + hidden_proto(selinux_users_path) + hidden_proto(selinux_usersconf_path); +hidden_proto(selinux_translations_path); +hidden_proto(selinux_colors_path); +hidden_proto(selinux_getenforcemode); +hidden_proto(selinux_getpolicytype); +hidden_proto(selinux_raw_to_trans_context); +hidden_proto(selinux_trans_to_raw_context); + hidden_proto(selinux_raw_context_to_color); +hidden_proto(security_get_initial_context); +hidden_proto(security_get_initial_context_raw); +hidden_proto(selinux_reset_config); +hidden_proto(selinux_flush_class_cache); -extern int require_seusers ; -extern int selinux_page_size ; +extern int require_seusers hidden; +extern int selinux_page_size hidden; /* Make pthread_once optional */ #pragma weak pthread_once @@ -73,4 +180,4 @@ extern int selinux_page_size ; #define SELINUXDIR "/etc/selinux/" #define SELINUXCONFIG SELINUXDIR "config" -extern int has_selinux_config ; +extern int has_selinux_config hidden; diff --git a/libselinux/src/selinux_restorecon.c b/libselinux/src/selinux_restorecon.c index 04d95650..028d8924 100644 --- a/libselinux/src/selinux_restorecon.c +++ b/libselinux/src/selinux_restorecon.c @@ -62,7 +62,7 @@ static uint64_t fc_count = 0; /* Number of files processed so far */ static uint64_t efile_count; /* Estimated total number of files */ /* Store information on directories with xattr's. */ -static struct dir_xattr *dir_xattr_list; +struct dir_xattr *dir_xattr_list; static struct dir_xattr *dir_xattr_last; /* restorecon_flags for passing to restorecon_sb() */ @@ -81,7 +81,6 @@ struct rest_flags { bool log_matches; bool ignore_noent; bool warnonnomatch; - bool conflicterror; }; static void restorecon_init(void) @@ -230,6 +229,7 @@ static int exclude_non_seclabel_mounts(void) struct utsname uts; FILE *fp; size_t len; + ssize_t num; int index = 0, found = 0, nfile = 0; char *mount_info[4]; char *buf = NULL, *item; @@ -244,7 +244,7 @@ static int exclude_non_seclabel_mounts(void) if (!fp) return 0; - while (getline(&buf, &len, fp) != -1) { + while ((num = getline(&buf, &len, fp)) != -1) { found = 0; index = 0; item = strtok(buf, " "); @@ -296,7 +296,6 @@ static int add_xattr_entry(const char *directory, bool delete_nonmatch, char *sha1_buf = NULL; size_t i, digest_len = 0; int rc, digest_result; - bool match; struct dir_xattr *new_entry; uint8_t *xattr_digest = NULL; uint8_t *calculated_digest = NULL; @@ -306,9 +305,9 @@ static int add_xattr_entry(const char *directory, bool delete_nonmatch, return -1; } - match = selabel_get_digests_all_partial_matches(fc_sehandle, directory, - &calculated_digest, &xattr_digest, - &digest_len); + selabel_get_digests_all_partial_matches(fc_sehandle, directory, + &calculated_digest, + &xattr_digest, &digest_len); if (!xattr_digest || !digest_len) { free(calculated_digest); @@ -326,14 +325,16 @@ static int add_xattr_entry(const char *directory, bool delete_nonmatch, for (i = 0; i < digest_len; i++) sprintf((&sha1_buf[i * 2]), "%02x", xattr_digest[i]); - digest_result = match ? MATCH : NOMATCH; + rc = memcmp(calculated_digest, xattr_digest, digest_len); + digest_result = rc ? NOMATCH : MATCH; - if ((delete_nonmatch && !match) || delete_all) { - digest_result = match ? DELETED_MATCH : DELETED_NOMATCH; + if ((delete_nonmatch && rc != 0) || delete_all) { + digest_result = rc ? DELETED_NOMATCH : DELETED_MATCH; rc = removexattr(directory, RESTORECON_PARTIAL_MATCH_DIGEST); if (rc) { selinux_log(SELINUX_ERROR, - "Error: %m removing xattr \"%s\" from: %s\n", + "Error: %s removing xattr \"%s\" from: %s\n", + strerror(errno), RESTORECON_PARTIAL_MATCH_DIGEST, directory); digest_result = ERROR; } @@ -417,8 +418,7 @@ static file_spec_t *fl_head; * different context that matched the inode, then use the first context * that matched. */ -static int filespec_add(ino_t ino, const char *con, const char *file, - struct rest_flags *flags) +static int filespec_add(ino_t ino, const char *con, const char *file) { file_spec_t *prevfl, *fl; int h, ret; @@ -458,11 +458,6 @@ static int filespec_add(ino_t ino, const char *con, const char *file, fl->file = strdup(file); if (!fl->file) goto oom; - if (flags->conflicterror) { - selinux_log(SELINUX_ERROR, - "treating conflicting specifications as an error.\n"); - return -1; - } return 1; } @@ -650,7 +645,7 @@ static int restorecon_sb(const char *pathname, const struct stat *sb, } if (flags->add_assoc) { - rc = filespec_add(sb->st_ino, newcon, pathname, flags); + rc = filespec_add(sb->st_ino, newcon, pathname); if (rc < 0) { selinux_log(SELINUX_ERROR, @@ -733,8 +728,8 @@ out1: return rc; err: selinux_log(SELINUX_ERROR, - "Could not set context for %s: %m\n", - pathname); + "Could not set context for %s: %s\n", + pathname, strerror(errno)); rc = -1; goto out1; } @@ -838,8 +833,6 @@ int selinux_restorecon(const char *pathname_orig, flags.ignore_noent = (restorecon_flags & SELINUX_RESTORECON_IGNORE_NOENTRY) ? true : false; flags.warnonnomatch = true; - flags.conflicterror = (restorecon_flags & - SELINUX_RESTORECON_CONFLICT_ERROR) ? true : false; ignore_mounts = (restorecon_flags & SELINUX_RESTORECON_IGNORE_MOUNTS) ? true : false; bool ignore_digest = (restorecon_flags & @@ -856,7 +849,6 @@ int selinux_restorecon(const char *pathname_orig, dev_t dev_num = 0; struct dir_hash_node *current = NULL; struct dir_hash_node *head = NULL; - int errno_tmp; if (flags.verbose && flags.progress) flags.verbose = false; @@ -929,15 +921,15 @@ int selinux_restorecon(const char *pathname_orig, return 0; } else { selinux_log(SELINUX_ERROR, - "lstat(%s) failed: %m\n", - pathname); + "lstat(%s) failed: %s\n", + pathname, strerror(errno)); error = -1; goto cleanup; } } /* Skip digest if not a directory */ - if (!S_ISDIR(sb.st_mode)) + if ((sb.st_mode & S_IFDIR) != S_IFDIR) setrestorecondigest = false; if (!flags.recurse) { @@ -951,11 +943,10 @@ int selinux_restorecon(const char *pathname_orig, } /* Obtain fs type */ - memset(&sfsb, 0, sizeof sfsb); - if (!S_ISLNK(sb.st_mode) && statfs(pathname, &sfsb) < 0) { + if (statfs(pathname, &sfsb) < 0) { selinux_log(SELINUX_ERROR, - "statfs(%s) failed: %m\n", - pathname); + "statfs(%s) failed: %s\n", + pathname, strerror(errno)); error = -1; goto cleanup; } @@ -1006,30 +997,24 @@ int selinux_restorecon(const char *pathname_orig, case FTS_DP: continue; case FTS_DNR: - errno_tmp = errno; - errno = ftsent->fts_errno; selinux_log(SELINUX_ERROR, - "Could not read %s: %m.\n", - ftsent->fts_path); - errno = errno_tmp; + "Could not read %s: %s.\n", + ftsent->fts_path, + strerror(ftsent->fts_errno)); fts_set(fts, ftsent, FTS_SKIP); continue; case FTS_NS: - errno_tmp = errno; - errno = ftsent->fts_errno; selinux_log(SELINUX_ERROR, - "Could not stat %s: %m.\n", - ftsent->fts_path); - errno = errno_tmp; + "Could not stat %s: %s.\n", + ftsent->fts_path, + strerror(ftsent->fts_errno)); fts_set(fts, ftsent, FTS_SKIP); continue; case FTS_ERR: - errno_tmp = errno; - errno = ftsent->fts_errno; selinux_log(SELINUX_ERROR, - "Error on %s: %m.\n", - ftsent->fts_path); - errno = errno_tmp; + "Error on %s: %s.\n", + ftsent->fts_path, + strerror(ftsent->fts_errno)); fts_set(fts, ftsent, FTS_SKIP); continue; case FTS_D: @@ -1093,8 +1078,9 @@ int selinux_restorecon(const char *pathname_orig, current->digest, SHA1_HASH_SIZE, 0) < 0) { selinux_log(SELINUX_ERROR, - "setxattr failed: %s: %m\n", - current->path); + "setxattr failed: %s: %s\n", + current->path, + strerror(errno)); } current = current->next; } @@ -1136,16 +1122,16 @@ oom: realpatherr: sverrno = errno; selinux_log(SELINUX_ERROR, - "SELinux: Could not get canonical path for %s restorecon: %m.\n", - pathname_orig); + "SELinux: Could not get canonical path for %s restorecon: %s.\n", + pathname_orig, strerror(errno)); errno = sverrno; error = -1; goto cleanup; fts_err: selinux_log(SELINUX_ERROR, - "fts error while labeling %s: %m\n", - paths[0]); + "fts error while labeling %s: %s\n", + paths[0], strerror(errno)); error = -1; goto cleanup; } @@ -1157,9 +1143,7 @@ void selinux_restorecon_set_sehandle(struct selabel_handle *hndl) unsigned char *fc_digest; size_t num_specfiles, fc_digest_len; - fc_sehandle = hndl; - if (!fc_sehandle) - return; + fc_sehandle = (struct selabel_handle *) hndl; /* Check if digest requested in selabel_open(3), if so use it. */ if (selabel_digest(fc_sehandle, &fc_digest, &fc_digest_len, @@ -1186,7 +1170,8 @@ struct selabel_handle *selinux_restorecon_default_handle(void) if (!sehandle) { selinux_log(SELINUX_ERROR, - "Error obtaining file context handle: %m\n"); + "Error obtaining file context handle: %s\n", + strerror(errno)); return NULL; } @@ -1206,8 +1191,8 @@ void selinux_restorecon_set_exclude_list(const char **exclude_list) for (i = 0; exclude_list[i]; i++) { if (lstat(exclude_list[i], &sb) < 0 && errno != EACCES) { selinux_log(SELINUX_ERROR, - "lstat error on exclude path \"%s\", %m - ignoring.\n", - exclude_list[i]); + "lstat error on exclude path \"%s\", %s - ignoring.\n", + exclude_list[i], strerror(errno)); break; } if (add_exclude(exclude_list[i], CALLER_EXCLUDED) && @@ -1273,8 +1258,8 @@ int selinux_restorecon_xattr(const char *pathname, unsigned int xattr_flags, return 0; selinux_log(SELINUX_ERROR, - "lstat(%s) failed: %m\n", - pathname); + "lstat(%s) failed: %s\n", + pathname, strerror(errno)); return -1; } @@ -1304,8 +1289,8 @@ int selinux_restorecon_xattr(const char *pathname, unsigned int xattr_flags, fts = fts_open(paths, fts_flags, NULL); if (!fts) { selinux_log(SELINUX_ERROR, - "fts error on %s: %m\n", - paths[0]); + "fts error on %s: %s\n", + paths[0], strerror(errno)); return -1; } diff --git a/libselinux/src/selinuxswig_python_exception.i b/libselinux/src/selinuxswig_python_exception.i index 237ea69a..cf658259 100644 --- a/libselinux/src/selinuxswig_python_exception.i +++ b/libselinux/src/selinuxswig_python_exception.i @@ -7,6 +7,7 @@ } } + %exception is_selinux_mls_enabled { $action if (result < 0) { @@ -15,6 +16,7 @@ } } + %exception getcon { $action if (result < 0) { @@ -23,6 +25,7 @@ } } + %exception getcon_raw { $action if (result < 0) { @@ -31,6 +34,7 @@ } } + %exception setcon { $action if (result < 0) { @@ -39,6 +43,7 @@ } } + %exception setcon_raw { $action if (result < 0) { @@ -47,6 +52,7 @@ } } + %exception getpidcon { $action if (result < 0) { @@ -55,6 +61,7 @@ } } + %exception getpidcon_raw { $action if (result < 0) { @@ -63,6 +70,7 @@ } } + %exception getprevcon { $action if (result < 0) { @@ -71,6 +79,7 @@ } } + %exception getprevcon_raw { $action if (result < 0) { @@ -79,6 +88,7 @@ } } + %exception getexeccon { $action if (result < 0) { @@ -87,6 +97,7 @@ } } + %exception getexeccon_raw { $action if (result < 0) { @@ -95,6 +106,7 @@ } } + %exception setexeccon { $action if (result < 0) { @@ -103,6 +115,7 @@ } } + %exception setexeccon_raw { $action if (result < 0) { @@ -111,6 +124,7 @@ } } + %exception getfscreatecon { $action if (result < 0) { @@ -119,6 +133,7 @@ } } + %exception getfscreatecon_raw { $action if (result < 0) { @@ -127,6 +142,7 @@ } } + %exception setfscreatecon { $action if (result < 0) { @@ -135,6 +151,7 @@ } } + %exception setfscreatecon_raw { $action if (result < 0) { @@ -143,6 +160,7 @@ } } + %exception getkeycreatecon { $action if (result < 0) { @@ -151,6 +169,7 @@ } } + %exception getkeycreatecon_raw { $action if (result < 0) { @@ -159,6 +178,7 @@ } } + %exception setkeycreatecon { $action if (result < 0) { @@ -167,6 +187,7 @@ } } + %exception setkeycreatecon_raw { $action if (result < 0) { @@ -175,6 +196,7 @@ } } + %exception getsockcreatecon { $action if (result < 0) { @@ -183,6 +205,7 @@ } } + %exception getsockcreatecon_raw { $action if (result < 0) { @@ -191,6 +214,7 @@ } } + %exception setsockcreatecon { $action if (result < 0) { @@ -199,6 +223,7 @@ } } + %exception setsockcreatecon_raw { $action if (result < 0) { @@ -207,6 +232,7 @@ } } + %exception getfilecon { $action if (result < 0) { @@ -215,6 +241,7 @@ } } + %exception getfilecon_raw { $action if (result < 0) { @@ -223,6 +250,7 @@ } } + %exception lgetfilecon { $action if (result < 0) { @@ -231,6 +259,7 @@ } } + %exception lgetfilecon_raw { $action if (result < 0) { @@ -239,6 +268,7 @@ } } + %exception fgetfilecon { $action if (result < 0) { @@ -247,6 +277,7 @@ } } + %exception fgetfilecon_raw { $action if (result < 0) { @@ -255,6 +286,7 @@ } } + %exception setfilecon { $action if (result < 0) { @@ -263,6 +295,7 @@ } } + %exception setfilecon_raw { $action if (result < 0) { @@ -271,6 +304,7 @@ } } + %exception lsetfilecon { $action if (result < 0) { @@ -279,6 +313,7 @@ } } + %exception lsetfilecon_raw { $action if (result < 0) { @@ -287,6 +322,7 @@ } } + %exception fsetfilecon { $action if (result < 0) { @@ -295,6 +331,7 @@ } } + %exception fsetfilecon_raw { $action if (result < 0) { @@ -303,6 +340,7 @@ } } + %exception getpeercon { $action if (result < 0) { @@ -311,6 +349,7 @@ } } + %exception getpeercon_raw { $action if (result < 0) { @@ -319,6 +358,7 @@ } } + %exception security_compute_av { $action if (result < 0) { @@ -327,6 +367,7 @@ } } + %exception security_compute_av_raw { $action if (result < 0) { @@ -335,6 +376,7 @@ } } + %exception security_compute_av_flags { $action if (result < 0) { @@ -343,6 +385,7 @@ } } + %exception security_compute_av_flags_raw { $action if (result < 0) { @@ -351,6 +394,7 @@ } } + %exception security_compute_create { $action if (result < 0) { @@ -359,6 +403,7 @@ } } + %exception security_compute_create_raw { $action if (result < 0) { @@ -367,6 +412,7 @@ } } + %exception security_compute_create_name { $action if (result < 0) { @@ -375,6 +421,7 @@ } } + %exception security_compute_create_name_raw { $action if (result < 0) { @@ -383,6 +430,7 @@ } } + %exception security_compute_relabel { $action if (result < 0) { @@ -391,6 +439,7 @@ } } + %exception security_compute_relabel_raw { $action if (result < 0) { @@ -399,6 +448,7 @@ } } + %exception security_compute_member { $action if (result < 0) { @@ -407,6 +457,7 @@ } } + %exception security_compute_member_raw { $action if (result < 0) { @@ -415,6 +466,7 @@ } } + %exception security_compute_user { $action if (result < 0) { @@ -423,6 +475,7 @@ } } + %exception security_compute_user_raw { $action if (result < 0) { @@ -431,6 +484,7 @@ } } + %exception security_validatetrans { $action if (result < 0) { @@ -439,6 +493,7 @@ } } + %exception security_validatetrans_raw { $action if (result < 0) { @@ -447,6 +502,7 @@ } } + %exception security_load_policy { $action if (result < 0) { @@ -455,6 +511,7 @@ } } + %exception security_get_initial_context { $action if (result < 0) { @@ -463,6 +520,7 @@ } } + %exception security_get_initial_context_raw { $action if (result < 0) { @@ -471,6 +529,7 @@ } } + %exception selinux_mkload_policy { $action if (result < 0) { @@ -479,6 +538,7 @@ } } + %exception selinux_init_load_policy { $action if (result < 0) { @@ -487,6 +547,7 @@ } } + %exception security_set_boolean_list { $action if (result < 0) { @@ -495,6 +556,7 @@ } } + %exception security_load_booleans { $action if (result < 0) { @@ -503,6 +565,7 @@ } } + %exception security_check_context { $action if (result < 0) { @@ -511,6 +574,7 @@ } } + %exception security_check_context_raw { $action if (result < 0) { @@ -519,6 +583,7 @@ } } + %exception security_canonicalize_context { $action if (result < 0) { @@ -527,6 +592,7 @@ } } + %exception security_canonicalize_context_raw { $action if (result < 0) { @@ -535,6 +601,7 @@ } } + %exception security_getenforce { $action if (result < 0) { @@ -543,6 +610,7 @@ } } + %exception security_setenforce { $action if (result < 0) { @@ -551,6 +619,7 @@ } } + %exception security_reject_unknown { $action if (result < 0) { @@ -559,6 +628,7 @@ } } + %exception security_deny_unknown { $action if (result < 0) { @@ -567,6 +637,7 @@ } } + %exception security_get_checkreqprot { $action if (result < 0) { @@ -575,6 +646,7 @@ } } + %exception security_disable { $action if (result < 0) { @@ -583,6 +655,7 @@ } } + %exception security_policyvers { $action if (result < 0) { @@ -591,6 +664,7 @@ } } + %exception security_get_boolean_names { $action if (result < 0) { @@ -599,6 +673,7 @@ } } + %exception security_get_boolean_pending { $action if (result < 0) { @@ -607,6 +682,7 @@ } } + %exception security_get_boolean_active { $action if (result < 0) { @@ -615,6 +691,7 @@ } } + %exception security_set_boolean { $action if (result < 0) { @@ -623,6 +700,7 @@ } } + %exception security_commit_booleans { $action if (result < 0) { @@ -631,6 +709,7 @@ } } + %exception selinux_set_mapping { $action if (result < 0) { @@ -639,6 +718,7 @@ } } + %exception security_av_string { $action if (result < 0) { @@ -647,6 +727,7 @@ } } + %exception matchpathcon_init { $action if (result < 0) { @@ -655,6 +736,7 @@ } } + %exception matchpathcon_init_prefix { $action if (result < 0) { @@ -663,6 +745,7 @@ } } + %exception realpath_not_final { $action if (result < 0) { @@ -671,6 +754,7 @@ } } + %exception matchpathcon { $action if (result < 0) { @@ -679,6 +763,7 @@ } } + %exception matchpathcon_index { $action if (result < 0) { @@ -687,6 +772,7 @@ } } + %exception matchpathcon_filespec_add { $action if (result < 0) { @@ -695,6 +781,7 @@ } } + %exception matchmediacon { $action if (result < 0) { @@ -703,6 +790,7 @@ } } + %exception selinux_getenforcemode { $action if (result < 0) { @@ -711,6 +799,7 @@ } } + %exception selinux_getpolicytype { $action if (result < 0) { @@ -719,6 +808,7 @@ } } + %exception selinux_set_policy_root { $action if (result < 0) { @@ -727,6 +817,7 @@ } } + %exception selinux_check_access { $action if (result < 0) { @@ -735,6 +826,7 @@ } } + %exception selinux_check_passwd_access { $action if (result < 0) { @@ -743,6 +835,7 @@ } } + %exception checkPasswdAccess { $action if (result < 0) { @@ -751,6 +844,7 @@ } } + %exception selinux_check_securetty_context { $action if (result < 0) { @@ -759,6 +853,7 @@ } } + %exception selinuxfs_exists { $action if (result < 0) { @@ -767,6 +862,7 @@ } } + %exception setexecfilecon { $action if (result < 0) { @@ -775,6 +871,7 @@ } } + %exception rpm_execcon { $action if (result < 0) { @@ -783,6 +880,7 @@ } } + %exception is_context_customizable { $action if (result < 0) { @@ -791,6 +889,7 @@ } } + %exception selinux_trans_to_raw_context { $action if (result < 0) { @@ -799,6 +898,7 @@ } } + %exception selinux_raw_to_trans_context { $action if (result < 0) { @@ -807,6 +907,7 @@ } } + %exception selinux_raw_context_to_color { $action if (result < 0) { @@ -815,6 +916,7 @@ } } + %exception getseuserbyname { $action if (result < 0) { @@ -823,6 +925,7 @@ } } + %exception getseuser { $action if (result < 0) { @@ -831,6 +934,7 @@ } } + %exception selinux_file_context_verify { $action if (result < 0) { @@ -839,6 +943,7 @@ } } + %exception selinux_lsetfilecon_default { $action if (result < 0) { @@ -847,354 +952,3 @@ } } -%exception avc_sid_to_context { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception avc_sid_to_context_raw { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception avc_context_to_sid { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception avc_context_to_sid_raw { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception sidget { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception sidput { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception avc_get_initial_sid { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception avc_init { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception avc_open { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception avc_reset { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception avc_has_perm_noaudit { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception avc_has_perm { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception avc_compute_create { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception avc_compute_member { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception avc_add_callback { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception avc_netlink_open { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception avc_netlink_acquire_fd { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception avc_netlink_check_nb { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception selinux_status_open { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception selinux_status_updated { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception selinux_status_getenforce { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception selinux_status_policyload { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception selinux_status_deny_unknown { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception context_type_set { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception context_range_set { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception context_role_set { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception context_user_set { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception get_ordered_context_list { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception get_ordered_context_list_with_level { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception get_default_context { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception get_default_context_with_level { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception get_default_context_with_role { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception get_default_context_with_rolelevel { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception query_user_context { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception manual_user_enter_context { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception get_default_type { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception selabel_lookup { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception selabel_lookup_raw { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception selabel_lookup_best_match { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception selabel_lookup_best_match_raw { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception selabel_digest { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception selinux_restorecon { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception selinux_restorecon_set_alt_rootpath { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} - -%exception selinux_restorecon_xattr { - $action - if (result < 0) { - PyErr_SetFromErrno(PyExc_OSError); - SWIG_fail; - } -} diff --git a/libselinux/src/sestatus.c b/libselinux/src/sestatus.c index 89c1f621..ede5a289 100644 --- a/libselinux/src/sestatus.c +++ b/libselinux/src/sestatus.c @@ -37,15 +37,13 @@ struct selinux_status_t * Valid Pointer : opened and mapped correctly */ static struct selinux_status_t *selinux_status = NULL; +static int selinux_status_fd; static uint32_t last_seqno; -static uint32_t last_policyload; static uint32_t fallback_sequence; static int fallback_enforcing; static int fallback_policyload; -static void *fallback_netlink_thread = NULL; - /* * read_sequence * @@ -90,9 +88,7 @@ static inline uint32_t read_sequence(struct selinux_status_t *status) int selinux_status_updated(void) { uint32_t curr_seqno; - uint32_t tmp_seqno; - uint32_t enforcing; - uint32_t policyload; + int result = 0; if (selinux_status == NULL) { errno = EINVAL; @@ -118,29 +114,12 @@ int selinux_status_updated(void) if (last_seqno & 0x0001) last_seqno = curr_seqno; - if (last_seqno == curr_seqno) - return 0; - - /* sequence must not be changed during references */ - do { - enforcing = selinux_status->enforcing; - policyload = selinux_status->policyload; - tmp_seqno = curr_seqno; - curr_seqno = read_sequence(selinux_status); - } while (tmp_seqno != curr_seqno); - - if (avc_enforcing != (int) enforcing) { - if (avc_process_setenforce(enforcing) < 0) - return -1; + if (last_seqno != curr_seqno) + { + last_seqno = curr_seqno; + result = 1; } - if (last_policyload != policyload) { - if (avc_process_policyload(policyload) < 0) - return -1; - last_policyload = policyload; - } - last_seqno = curr_seqno; - - return 1; + return result; } /* @@ -271,20 +250,13 @@ static int fallback_cb_policyload(int policyload) * Since Linux 2.6.37 or later supports this feature, we may run * fallback routine using a netlink socket on older kernels, if * the supplied `fallback' is not zero. - * It returns 0 on success, -1 on error or 1 when we are ready to - * use these interfaces, but netlink socket was opened as fallback - * instead of the kernel status page. + * It returns 0 on success, or -1 on error. */ int selinux_status_open(int fallback) { - int fd; - char path[PATH_MAX]; - long pagesize; - uint32_t seqno; - - if (selinux_status != NULL) { - return (selinux_status == MAP_FAILED) ? 1 : 0; - } + int fd; + char path[PATH_MAX]; + long pagesize; if (!selinux_mnt) { errno = ENOENT; @@ -301,23 +273,13 @@ int selinux_status_open(int fallback) goto error; selinux_status = mmap(NULL, pagesize, PROT_READ, MAP_SHARED, fd, 0); - close(fd); if (selinux_status == MAP_FAILED) { + close(fd); goto error; } + selinux_status_fd = fd; last_seqno = (uint32_t)(-1); - /* sequence must not be changed during references */ - do { - seqno = read_sequence(selinux_status); - - last_policyload = selinux_status->policyload; - - } while (seqno != read_sequence(selinux_status)); - - /* No need to use avc threads if the kernel status page is available */ - avc_using_threads = 0; - return 0; error: @@ -338,14 +300,9 @@ error: /* mark as fallback mode */ selinux_status = MAP_FAILED; + selinux_status_fd = avc_netlink_acquire_fd(); last_seqno = (uint32_t)(-1); - if (avc_using_threads) - { - fallback_netlink_thread = avc_create_thread(&avc_netlink_loop); - avc_netlink_trouble = 0; - } - fallback_sequence = 0; fallback_enforcing = security_getenforce(); fallback_policyload = 0; @@ -374,9 +331,6 @@ void selinux_status_close(void) /* fallback-mode */ if (selinux_status == MAP_FAILED) { - if (avc_using_threads) - avc_stop_thread(fallback_netlink_thread); - avc_netlink_release_fd(); avc_netlink_close(); selinux_status = NULL; @@ -389,5 +343,7 @@ void selinux_status_close(void) munmap(selinux_status, pagesize); selinux_status = NULL; + close(selinux_status_fd); + selinux_status_fd = -1; last_seqno = (uint32_t)(-1); } diff --git a/libselinux/src/setenforce.c b/libselinux/src/setenforce.c index a87ff2d0..09cad3ce 100644 --- a/libselinux/src/setenforce.c +++ b/libselinux/src/setenforce.c @@ -34,3 +34,4 @@ int security_setenforce(int value) return 0; } +hidden_def(security_setenforce) diff --git a/libselinux/src/setexecfilecon.c b/libselinux/src/setexecfilecon.c index 2c6505a9..e72ba0d9 100644 --- a/libselinux/src/setexecfilecon.c +++ b/libselinux/src/setexecfilecon.c @@ -37,6 +37,7 @@ int setexecfilecon(const char *filename, const char *fallback_type) newcon = strdup(context_str(con)); if (!newcon) goto out; + rc = 0; } rc = setexeccon(newcon); diff --git a/libselinux/src/setfilecon.c b/libselinux/src/setfilecon.c index bd45f12c..d05969c6 100644 --- a/libselinux/src/setfilecon.c +++ b/libselinux/src/setfilecon.c @@ -25,6 +25,7 @@ int setfilecon_raw(const char *path, const char * context) return rc; } +hidden_def(setfilecon_raw) int setfilecon(const char *path, const char *context) { diff --git a/libselinux/src/setrans_client.c b/libselinux/src/setrans_client.c index 52a8ba78..fa188a82 100644 --- a/libselinux/src/setrans_client.c +++ b/libselinux/src/setrans_client.c @@ -19,6 +19,7 @@ #include #include #include +#include "dso.h" #include "selinux_internal.h" #include "setrans_internal.h" @@ -259,7 +260,7 @@ static void setrans_thread_destructor(void __attribute__((unused)) *unused) void __attribute__((destructor)) setrans_lib_destructor(void); -void __attribute__((destructor)) setrans_lib_destructor(void) +void hidden __attribute__((destructor)) setrans_lib_destructor(void) { if (!has_setrans) return; @@ -326,6 +327,7 @@ int selinux_trans_to_raw_context(const char * trans, return *rawp ? 0 : -1; } +hidden_def(selinux_trans_to_raw_context) int selinux_raw_to_trans_context(const char * raw, char ** transp) @@ -367,6 +369,7 @@ int selinux_raw_to_trans_context(const char * raw, return *transp ? 0 : -1; } +hidden_def(selinux_raw_to_trans_context) int selinux_raw_context_to_color(const char * raw, char **transp) { @@ -407,6 +410,7 @@ int selinux_raw_context_to_color(const char * raw, char **transp) return *transp ? 0 : -1; } +hidden_def(selinux_raw_context_to_color) #else /*DISABLE_SETRANS*/ int selinux_trans_to_raw_context(const char * trans, @@ -422,6 +426,7 @@ int selinux_trans_to_raw_context(const char * trans, return *rawp ? 0 : -1; } +hidden_def(selinux_trans_to_raw_context) int selinux_raw_to_trans_context(const char * raw, char ** transp) @@ -435,4 +440,5 @@ int selinux_raw_to_trans_context(const char * raw, return *transp ? 0 : -1; } +hidden_def(selinux_raw_to_trans_context) #endif /*DISABLE_SETRANS*/ diff --git a/libselinux/src/setup.py b/libselinux/src/setup.py index 958687a0..c8270bdc 100644 --- a/libselinux/src/setup.py +++ b/libselinux/src/setup.py @@ -4,7 +4,7 @@ from distutils.core import Extension, setup setup( name="selinux", - version="3.3-rc1", + version="3.0", description="SELinux python 3 bindings", author="SELinux Project", author_email="selinux@vger.kernel.org", diff --git a/libselinux/src/seusers.c b/libselinux/src/seusers.c index fff80c1a..7ec7d12c 100644 --- a/libselinux/src/seusers.c +++ b/libselinux/src/seusers.c @@ -88,7 +88,7 @@ static int process_seusers(const char *buffer, return -2; /* error */ } -int require_seusers = 0; +int require_seusers hidden = 0; #include #include diff --git a/libselinux/src/sha1.c b/libselinux/src/sha1.c index a8484677..004fcd3b 100644 --- a/libselinux/src/sha1.c +++ b/libselinux/src/sha1.c @@ -16,7 +16,6 @@ // sha1.c:73:33: error: cast from 'uint8_t *' (aka 'unsigned char *') to 'CHAR64LONG16 *' increases required alignment from 1 to 4 [-Werror,-Wcast-align] // CHAR64LONG16* block = (CHAR64LONG16*) workspace; // William Roberts -// - Silence clang's -Wextra-semi-stmt warning - July 2021, Nicolas Iooss /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -24,6 +23,7 @@ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include "sha1.h" +#include "dso.h" #include /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -50,11 +50,11 @@ typedef union ^block->l[(i+2)&15]^block->l[i&15],1)) // (R0+R1), R2, R3, R4 are the different operations used in SHA1 -#define R0(v,w,x,y,z,i) do { z += ((w&(x^y))^y) + blk0(i)+ 0x5A827999 + rol(v,5); w=rol(w,30); } while (0) -#define R1(v,w,x,y,z,i) do { z += ((w&(x^y))^y) + blk(i) + 0x5A827999 + rol(v,5); w=rol(w,30); } while (0) -#define R2(v,w,x,y,z,i) do { z += (w^x^y) + blk(i) + 0x6ED9EBA1 + rol(v,5); w=rol(w,30); } while (0) -#define R3(v,w,x,y,z,i) do { z += (((w|x)&y)|(w&x)) + blk(i) + 0x8F1BBCDC + rol(v,5); w=rol(w,30); } while (0) -#define R4(v,w,x,y,z,i) do { z += (w^x^y) + blk(i) + 0xCA62C1D6 + rol(v,5); w=rol(w,30); } while (0) +#define R0(v,w,x,y,z,i) z += ((w&(x^y))^y) + blk0(i)+ 0x5A827999 + rol(v,5); w=rol(w,30); +#define R1(v,w,x,y,z,i) z += ((w&(x^y))^y) + blk(i) + 0x5A827999 + rol(v,5); w=rol(w,30); +#define R2(v,w,x,y,z,i) z += (w^x^y) + blk(i) + 0x6ED9EBA1 + rol(v,5); w=rol(w,30); +#define R3(v,w,x,y,z,i) z += (((w|x)&y)|(w&x)) + blk(i) + 0x8F1BBCDC + rol(v,5); w=rol(w,30); +#define R4(v,w,x,y,z,i) z += (w^x^y) + blk(i) + 0xCA62C1D6 + rol(v,5); w=rol(w,30); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -126,7 +126,7 @@ void // // Initialises an SHA1 Context. Use this to initialise/reset a context. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void +void hidden Sha1Initialise ( Sha1Context* Context @@ -148,11 +148,11 @@ void // Adds data to the SHA1 context. This will process the data and update the internal state of the context. Keep on // calling this function until all the data has been added. Then call Sha1Finalise to calculate the hash. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void +void hidden Sha1Update ( Sha1Context* Context, - const void* Buffer, + void* Buffer, uint32_t BufferSize ) { @@ -173,7 +173,7 @@ void TransformFunction(Context->State, Context->Buffer); for (; i + 63 < BufferSize; i += 64) { - TransformFunction(Context->State, (const uint8_t*)Buffer + i); + TransformFunction(Context->State, (uint8_t*)Buffer + i); } j = 0; } @@ -182,7 +182,7 @@ void i = 0; } - memcpy(&Context->Buffer[j], &((const uint8_t*)Buffer)[i], BufferSize - i); + memcpy(&Context->Buffer[j], &((uint8_t*)Buffer)[i], BufferSize - i); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -191,7 +191,7 @@ void // Performs the final calculation of the hash and returns the digest (20 byte buffer containing 160bit hash). After // calling this, Sha1Initialised must be used to reuse the context. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void +void hidden Sha1Finalise ( Sha1Context* Context, @@ -206,10 +206,10 @@ void finalcount[i] = (unsigned char)((Context->Count[(i >= 4 ? 0 : 1)] >> ((3-(i & 3)) * 8) ) & 255); // Endian independent } - Sha1Update(Context, (const uint8_t*)"\x80", 1); + Sha1Update(Context, (uint8_t*)"\x80", 1); while ((Context->Count[0] & 504) != 448) { - Sha1Update(Context, (const uint8_t*)"\0", 1); + Sha1Update(Context, (uint8_t*)"\0", 1); } Sha1Update(Context, finalcount, 8); // Should cause a Sha1TransformFunction() diff --git a/libselinux/src/sha1.h b/libselinux/src/sha1.h index f83a6e7e..eac3c195 100644 --- a/libselinux/src/sha1.h +++ b/libselinux/src/sha1.h @@ -64,7 +64,7 @@ void Sha1Update ( Sha1Context* Context, - const void* Buffer, + void* Buffer, uint32_t BufferSize ); diff --git a/libselinux/src/stringrep.c b/libselinux/src/stringrep.c index 012a740a..29757b75 100644 --- a/libselinux/src/stringrep.c +++ b/libselinux/src/stringrep.c @@ -180,6 +180,7 @@ void selinux_flush_class_cache(void) discover_class_cache = NULL; } +hidden_def(selinux_flush_class_cache) security_class_t string_to_security_class(const char *s) { diff --git a/libselinux/src/validatetrans.c b/libselinux/src/validatetrans.c index 66ac7405..2aa300cf 100644 --- a/libselinux/src/validatetrans.c +++ b/libselinux/src/validatetrans.c @@ -57,6 +57,7 @@ out: return ret; } +hidden_def(security_validatetrans_raw) int security_validatetrans(const char *scon, const char *tcon, @@ -90,3 +91,4 @@ out: return ret; } +hidden_def(security_validatetrans) diff --git a/libselinux/utils/Makefile b/libselinux/utils/Makefile index b018a08a..36150638 100644 --- a/libselinux/utils/Makefile +++ b/libselinux/utils/Makefile @@ -36,6 +36,8 @@ CFLAGS ?= -O -Wall -W -Wundef -Wformat-y2k -Wformat-security -Winit-self -Wmissi -Werror -Wno-aggregate-return -Wno-redundant-decls -Wstrict-overflow=5 \ $(EXTRA_CFLAGS) +LD_SONAME_FLAGS=-soname,$(LIBSO),-z,defs,-z,relro + ifeq ($(OS), Darwin) override CFLAGS += -I/opt/local/include -I../../libsepol/include override LDFLAGS += -L../../libsepol/src -undefined dynamic_lookup @@ -43,7 +45,7 @@ endif override CFLAGS += -I../include -D_GNU_SOURCE $(DISABLE_FLAGS) $(PCRE_CFLAGS) override LDFLAGS += -L../src -override LDLIBS += -lselinux $(FTS_LDLIBS) +override LDLIBS += -lselinux PCRE_LDLIBS ?= -lpcre ifeq ($(ANDROID_HOST),y) diff --git a/libselinux/utils/avcstat.c b/libselinux/utils/avcstat.c index cc9a48dd..da239287 100644 --- a/libselinux/utils/avcstat.c +++ b/libselinux/utils/avcstat.c @@ -205,7 +205,7 @@ int main(int argc, char **argv) die("unable to parse \'%s\': no data", avcstatfile); if (cumulative || !i) - printf("%10llu %10llu %10llu %10llu %10llu %10llu\n", + printf("%10Lu %10Lu %10Lu %10Lu %10Lu %10Lu\n", tot.lookups, tot.hits, tot.misses, tot.allocations, tot.reclaims, tot.frees); else { @@ -215,7 +215,7 @@ int main(int argc, char **argv) rel.allocations = tot.allocations - last.allocations; rel.reclaims = tot.reclaims - last.reclaims; rel.frees = tot.frees - last.frees; - printf("%10llu %10llu %10llu %10llu %10llu %10llu\n", + printf("%10Lu %10Lu %10Lu %10Lu %10Lu %10Lu\n", rel.lookups, rel.hits, rel.misses, rel.allocations, rel.reclaims, rel.frees); } diff --git a/libselinux/utils/compute_user.c b/libselinux/utils/compute_user.c new file mode 100644 index 00000000..86d00a6e --- /dev/null +++ b/libselinux/utils/compute_user.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + char **buf, **ptr; + int ret; + + if (argc != 3) { + fprintf(stderr, "usage: %s context user\n", argv[0]); + exit(1); + } + + ret = security_compute_user(argv[1], argv[2], &buf); + if (ret < 0) { + fprintf(stderr, "%s: security_compute_user(%s,%s) failed\n", + argv[0], argv[1], argv[2]); + exit(2); + } + + if (!buf[0]) { + printf("none\n"); + exit(EXIT_SUCCESS); + } + + for (ptr = buf; *ptr; ptr++) { + printf("%s\n", *ptr); + } + freeconary(buf); + exit(EXIT_SUCCESS); +} diff --git a/libselinux/utils/getconlist.c b/libselinux/utils/getconlist.c index 0bb28469..29c16640 100644 --- a/libselinux/utils/getconlist.c +++ b/libselinux/utils/getconlist.c @@ -26,7 +26,6 @@ int main(int argc, char **argv) while ((opt = getopt(argc, argv, "l:")) > 0) { switch (opt) { case 'l': - free(level); level = strdup(optarg); if (!level) { fprintf(stderr, "memory allocation failure: %d(%s)\n", @@ -59,14 +58,8 @@ int main(int argc, char **argv) free(level); return 2; } - } else { + } else cur_context = argv[optind + 1]; - if (security_check_context(cur_context) != 0) { - fprintf(stderr, "Given context '%s' is invalid.\n", cur_context); - free(level); - return 3; - } - } /* Get the list and print it */ if (level) @@ -79,11 +72,6 @@ int main(int argc, char **argv) for (i = 0; list[i]; i++) puts(list[i]); freeconary(list); - } else { - fprintf(stderr, "get_ordered_context_list%s failure: %d(%s)\n", - level ? "_with_level" : "", errno, strerror(errno)); - free(level); - return 4; } free(level); diff --git a/libselinux/utils/getdefaultcon.c b/libselinux/utils/getdefaultcon.c index 957c1cb2..96a5a8c2 100644 --- a/libselinux/utils/getdefaultcon.c +++ b/libselinux/utils/getdefaultcon.c @@ -28,15 +28,12 @@ int main(int argc, char **argv) while ((opt = getopt(argc, argv, "l:r:s:v")) > 0) { switch (opt) { case 'l': - free(level); level = strdup(optarg); break; case 'r': - free(role); role = strdup(optarg); break; case 's': - free(service); service = strdup(optarg); break; case 'v': diff --git a/libselinux/utils/getseuser.c b/libselinux/utils/getseuser.c index 34f2e887..9193fe0a 100644 --- a/libselinux/utils/getseuser.c +++ b/libselinux/utils/getseuser.c @@ -13,47 +13,28 @@ int main(int argc, char **argv) if (argc != 3) { fprintf(stderr, "usage: %s linuxuser fromcon\n", argv[0]); - return 1; - } - - if (!is_selinux_enabled()) { - fprintf(stderr, "%s may be used only on a SELinux enabled kernel.\n", argv[0]); - return 4; + exit(1); } rc = getseuserbyname(argv[1], &seuser, &level); if (rc) { - fprintf(stderr, "getseuserbyname failed: %s\n", strerror(errno)); - return 2; + fprintf(stderr, "getseuserbyname failed: %s\n", + strerror(errno)); + exit(2); } printf("seuser: %s, level %s\n", seuser, level); - - rc = security_check_context(argv[2]); - if (rc) { - fprintf(stderr, "context '%s' is invalid\n", argv[2]); - free(seuser); - free(level); - return 5; + n = get_ordered_context_list_with_level(seuser, level, argv[2], + &contextlist); + if (n <= 0) { + fprintf(stderr, + "get_ordered_context_list_with_level failed: %s\n", + strerror(errno)); + exit(3); } - - n = get_ordered_context_list_with_level(seuser, level, argv[2], &contextlist); - if (n < 0) { - fprintf(stderr, "get_ordered_context_list_with_level failed: %s\n", strerror(errno)); - free(seuser); - free(level); - return 3; - } - free(seuser); free(level); - - if (n == 0) - printf("no valid context found\n"); - for (i = 0; i < n; i++) printf("Context %d\t%s\n", i, contextlist[i]); - freeconary(contextlist); - - return EXIT_SUCCESS; + exit(EXIT_SUCCESS); } diff --git a/libselinux/utils/matchpathcon.c b/libselinux/utils/matchpathcon.c index 1d713c01..eb39a188 100644 --- a/libselinux/utils/matchpathcon.c +++ b/libselinux/utils/matchpathcon.c @@ -1,14 +1,15 @@ -#include -#include -#include -#include -#include +#include #include #include +#include +#include #include -#include +#include #include -#include +#include +#include +#include +#include static __attribute__ ((__noreturn__)) void usage(const char *progname) { @@ -18,21 +19,15 @@ static __attribute__ ((__noreturn__)) void usage(const char *progname) exit(1); } -static int printmatchpathcon(struct selabel_handle *hnd, const char *path, int header, int mode, int notrans) +static int printmatchpathcon(const char *path, int header, int mode) { - char *buf = NULL; - int rc; - - if (notrans) { - rc = selabel_lookup_raw(hnd, &buf, path, mode); - } else { - rc = selabel_lookup(hnd, &buf, path, mode); - } + char *buf; + int rc = matchpathcon(path, mode, &buf); if (rc < 0) { if (errno == ENOENT) { buf = strdup("<>"); } else { - fprintf(stderr, "selabel_lookup(%s) failed: %s\n", path, + fprintf(stderr, "matchpathcon(%s) failed: %s\n", path, strerror(errno)); return 1; } @@ -65,20 +60,18 @@ static mode_t string_to_mode(char *s) return S_IFREG; default: return -1; - } + }; return -1; } int main(int argc, char **argv) { - int i, force_mode = 0; + int i, init = 0, force_mode = 0; int header = 1, opt; int verify = 0; int notrans = 0; int error = 0; int quiet = 0; - struct selabel_handle *hnd; - struct selinux_opt options[SELABEL_NOPT] = {}; if (argc < 2) usage(argv[0]); @@ -100,10 +93,23 @@ int main(int argc, char **argv) break; case 'N': notrans = 1; + set_matchpathcon_flags(MATCHPATHCON_NOTRANS); break; case 'f': - options[SELABEL_OPT_PATH].type = SELABEL_OPT_PATH; - options[SELABEL_OPT_PATH].value = optarg; + if (init) { + fprintf(stderr, + "%s: -f and -p are exclusive\n", + argv[0]); + exit(1); + } + init = 1; + if (matchpathcon_init(optarg)) { + fprintf(stderr, + "Error while processing %s: %s\n", + optarg, + errno ? strerror(errno) : "invalid"); + exit(1); + } break; case 'P': if (selinux_set_policy_root(optarg) < 0 ) { @@ -115,11 +121,20 @@ int main(int argc, char **argv) } break; case 'p': - // This option has been deprecated since libselinux 2.5 (2016): - // https://github.com/SELinuxProject/selinux/commit/26e05da0fc2d0a4bd274320968a88f8acbb3b6a6 - fprintf(stderr, "Warning: using %s -p is deprecated\n", argv[0]); - options[SELABEL_OPT_SUBSET].type = SELABEL_OPT_SUBSET; - options[SELABEL_OPT_SUBSET].value = optarg; + if (init) { + fprintf(stderr, + "%s: -f and -p are exclusive\n", + argv[0]); + exit(1); + } + init = 1; + if (matchpathcon_init_prefix(NULL, optarg)) { + fprintf(stderr, + "Error while processing %s: %s\n", + optarg, + errno ? strerror(errno) : "invalid"); + exit(1); + } break; case 'q': quiet = 1; @@ -128,13 +143,6 @@ int main(int argc, char **argv) usage(argv[0]); } } - hnd = selabel_open(SELABEL_CTX_FILE, options, SELABEL_NOPT); - if (!hnd) { - fprintf(stderr, - "Error while opening file contexts database: %s\n", - strerror(errno)); - return -1; - } for (i = optind; i < argc; i++) { int rc, mode = 0; struct stat buf; @@ -174,19 +182,19 @@ int main(int argc, char **argv) if (rc >= 0) { printf("%s has context %s, should be ", path, con); - printmatchpathcon(hnd, path, 0, mode, notrans); + printmatchpathcon(path, 0, mode); freecon(con); } else { printf ("actual context unknown: %s, should be ", strerror(errno)); - printmatchpathcon(hnd, path, 0, mode, notrans); + printmatchpathcon(path, 0, mode); } } } else { - error |= printmatchpathcon(hnd, path, header, mode, notrans); + error |= printmatchpathcon(path, header, mode); } } - selabel_close(hnd); + matchpathcon_fini(); return error; } diff --git a/libselinux/utils/sefcontext_compile.c b/libselinux/utils/sefcontext_compile.c index 6c32172d..dcb0085a 100644 --- a/libselinux/utils/sefcontext_compile.c +++ b/libselinux/utils/sefcontext_compile.c @@ -14,7 +14,7 @@ #include "../src/label_file.h" #include "../src/regex.h" -static const char *policy_file; +const char *policy_file; static int ctx_err; static int validate_context(char **ctxp) diff --git a/libselinux/utils/selabel_get_digests_all_partial_matches.c b/libselinux/utils/selabel_get_digests_all_partial_matches.c index e28833d2..0c2edc67 100644 --- a/libselinux/utils/selabel_get_digests_all_partial_matches.c +++ b/libselinux/utils/selabel_get_digests_all_partial_matches.c @@ -128,7 +128,7 @@ int main(int argc, char **argv) printf("No SHA1 digest available for: %s\n", ftsent->fts_path); printf("as file_context entry is \"<>\"\n"); - goto cleanup; + break; } printf("The file_context entries for: %s\n", @@ -149,11 +149,11 @@ int main(int argc, char **argv) xattr_digest[i]); printf("%s\n", sha1_buf); } + + free(xattr_digest); + free(calculated_digest); + free(sha1_buf); } - cleanup: - free(xattr_digest); - free(calculated_digest); - free(sha1_buf); break; } default: diff --git a/libselinux/utils/selabel_lookup_best_match.c b/libselinux/utils/selabel_lookup_best_match.c index 2cddc6cd..6a717423 100644 --- a/libselinux/utils/selabel_lookup_best_match.c +++ b/libselinux/utils/selabel_lookup_best_match.c @@ -47,7 +47,7 @@ static mode_t string_to_mode(char *s) return S_IFSOCK; case 'f': return S_IFREG; - } + }; return 0; } diff --git a/libsemanage/VERSION b/libsemanage/VERSION index e6852d8a..9f55b2cc 100644 --- a/libsemanage/VERSION +++ b/libsemanage/VERSION @@ -1 +1 @@ -3.3-rc1 +3.0 diff --git a/libsemanage/include/semanage/modules.h b/libsemanage/include/semanage/modules.h index b51f61f0..ac403931 100644 --- a/libsemanage/include/semanage/modules.h +++ b/libsemanage/include/semanage/modules.h @@ -33,7 +33,7 @@ typedef struct semanage_module_key semanage_module_key_t; */ extern int semanage_module_install(semanage_handle_t *, - char *module_data, size_t data_len, const char *name, const char *ext_lang); + char *module_data, size_t data_len, char *name, char *ext_lang); extern int semanage_module_install_file(semanage_handle_t *, const char *module_name); extern int semanage_module_remove(semanage_handle_t *, char *module_name); diff --git a/libsemanage/man/man5/semanage.conf.5 b/libsemanage/man/man5/semanage.conf.5 index 7d6f2fef..8efc7dd5 100644 --- a/libsemanage/man/man5/semanage.conf.5 +++ b/libsemanage/man/man5/semanage.conf.5 @@ -95,8 +95,8 @@ to this option set to "false"). .TP .B handle-unknown -This option overrides the kernel behavior for handling permissions defined in the kernel but missing from the actual policy. -It can be set to "deny", "reject" or "allow". By default the setting from the policy is taken. +This option controls the kernel behavior for handling permissions defined in the kernel but missing from the actual policy. +It can be set to "deny", "reject" or "allow". .TP .B bzip-blocksize diff --git a/libsemanage/src/Makefile b/libsemanage/src/Makefile index ab6cae51..f6780dc6 100644 --- a/libsemanage/src/Makefile +++ b/libsemanage/src/Makefile @@ -14,7 +14,7 @@ INCLUDEDIR ?= $(PREFIX)/include PYINC ?= $(shell $(PKG_CONFIG) --cflags $(PYPREFIX)) PYLIBS ?= $(shell $(PKG_CONFIG) --libs $(PYPREFIX)) PYTHONLIBDIR ?= $(shell $(PYTHON) -c "from distutils.sysconfig import *; print(get_python_lib(plat_specific=1, prefix='$(PREFIX)'))") -PYCEXT ?= $(shell $(PYTHON) -c 'import importlib.machinery;print(importlib.machinery.EXTENSION_SUFFIXES[0])') +PYCEXT ?= $(shell $(PYTHON) -c 'import imp;print([s for s,m,t in imp.get_suffixes() if t == imp.C_EXTENSION][0])') RUBYINC ?= $(shell $(RUBY) -e 'puts "-I" + RbConfig::CONFIG["rubyarchhdrdir"] + " -I" + RbConfig::CONFIG["rubyhdrdir"]') RUBYLIBS ?= $(shell $(RUBY) -e 'puts "-L" + RbConfig::CONFIG["libdir"] + " -L" + RbConfig::CONFIG["archlibdir"] + " " + RbConfig::CONFIG["LIBRUBYARG_SHARED"]') RUBYINSTALL ?= $(shell $(RUBY) -e 'puts RbConfig::CONFIG["vendorarchdir"]') @@ -32,7 +32,7 @@ YACC = bison YFLAGS = -d VERSION = $(shell cat ../VERSION) -LIBVERSION = 2 +LIBVERSION = 1 LIBA=libsemanage.a TARGET=libsemanage.so @@ -53,8 +53,7 @@ SRCS= $(filter-out $(GENERATED),$(sort $(wildcard *.c))) OBJS= $(patsubst %.c,%.o,$(SRCS)) conf-scan.o conf-parse.o LOBJS= $(patsubst %.c,%.lo,$(SRCS)) conf-scan.lo conf-parse.lo -CFLAGS ?= -Werror -Wall -W -Wundef -Wshadow -Wmissing-noreturn -Wmissing-format-attribute \ - -fno-semantic-interposition +CFLAGS ?= -Werror -Wall -W -Wundef -Wshadow -Wmissing-noreturn -Wmissing-format-attribute SWIG_CFLAGS += -Wno-error -Wno-unused-but-set-variable -Wno-unused-variable -Wno-shadow \ -Wno-unused-parameter diff --git a/libsemanage/src/boolean_internal.h b/libsemanage/src/boolean_internal.h index 8d1c20dc..dc23c273 100644 --- a/libsemanage/src/boolean_internal.h +++ b/libsemanage/src/boolean_internal.h @@ -7,6 +7,19 @@ #include #include "database.h" #include "handle.h" +#include "dso.h" + +hidden_proto(semanage_bool_clone) + hidden_proto(semanage_bool_compare) + hidden_proto(semanage_bool_compare2) + hidden_proto(semanage_bool_create) + hidden_proto(semanage_bool_free) + hidden_proto(semanage_bool_get_name) + hidden_proto(semanage_bool_get_value) + hidden_proto(semanage_bool_key_extract) + hidden_proto(semanage_bool_key_free) + hidden_proto(semanage_bool_set_name) + hidden_proto(semanage_bool_set_value) /* BOOL RECORD: method table */ extern record_table_t SEMANAGE_BOOL_RTABLE; diff --git a/libsemanage/src/boolean_record.c b/libsemanage/src/boolean_record.c index 95f3a862..c234094e 100644 --- a/libsemanage/src/boolean_record.c +++ b/libsemanage/src/boolean_record.c @@ -8,6 +8,7 @@ #include #include +#include "handle_internal.h" typedef sepol_bool_t semanage_bool_t; typedef sepol_bool_key_t semanage_bool_key_t; @@ -39,12 +40,14 @@ int semanage_bool_key_extract(semanage_handle_t * handle, return sepol_bool_key_extract(handle->sepolh, boolean, key); } +hidden_def(semanage_bool_key_extract) void semanage_bool_key_free(semanage_bool_key_t * key) { sepol_bool_key_free(key); } +hidden_def(semanage_bool_key_free) int semanage_bool_compare(const semanage_bool_t * boolean, const semanage_bool_key_t * key) @@ -53,6 +56,7 @@ int semanage_bool_compare(const semanage_bool_t * boolean, return sepol_bool_compare(boolean, key); } +hidden_def(semanage_bool_compare) int semanage_bool_compare2(const semanage_bool_t * boolean, const semanage_bool_t * boolean2) @@ -61,6 +65,7 @@ int semanage_bool_compare2(const semanage_bool_t * boolean, return sepol_bool_compare2(boolean, boolean2); } +hidden_def(semanage_bool_compare2) static int semanage_bool_compare2_qsort(const semanage_bool_t ** boolean, const semanage_bool_t ** boolean2) @@ -76,6 +81,7 @@ const char *semanage_bool_get_name(const semanage_bool_t * boolean) return sepol_bool_get_name(boolean); } +hidden_def(semanage_bool_get_name) int semanage_bool_set_name(semanage_handle_t * handle, semanage_bool_t * boolean, const char *name) @@ -135,6 +141,7 @@ out: return rc; } +hidden_def(semanage_bool_set_name) /* Value */ int semanage_bool_get_value(const semanage_bool_t * boolean) @@ -143,6 +150,7 @@ int semanage_bool_get_value(const semanage_bool_t * boolean) return sepol_bool_get_value(boolean); } +hidden_def(semanage_bool_get_value) void semanage_bool_set_value(semanage_bool_t * boolean, int value) { @@ -150,6 +158,7 @@ void semanage_bool_set_value(semanage_bool_t * boolean, int value) sepol_bool_set_value(boolean, value); } +hidden_def(semanage_bool_set_value) /* Create/Clone/Destroy */ int semanage_bool_create(semanage_handle_t * handle, @@ -159,6 +168,7 @@ int semanage_bool_create(semanage_handle_t * handle, return sepol_bool_create(handle->sepolh, bool_ptr); } +hidden_def(semanage_bool_create) int semanage_bool_clone(semanage_handle_t * handle, const semanage_bool_t * boolean, @@ -168,6 +178,7 @@ int semanage_bool_clone(semanage_handle_t * handle, return sepol_bool_clone(handle->sepolh, boolean, bool_ptr); } +hidden_def(semanage_bool_clone) void semanage_bool_free(semanage_bool_t * boolean) { @@ -175,6 +186,7 @@ void semanage_bool_free(semanage_bool_t * boolean) sepol_bool_free(boolean); } +hidden_def(semanage_bool_free) /* Record base functions */ record_table_t SEMANAGE_BOOL_RTABLE = { diff --git a/libsemanage/src/conf-parse.y b/libsemanage/src/conf-parse.y index eac91344..9bf9364a 100644 --- a/libsemanage/src/conf-parse.y +++ b/libsemanage/src/conf-parse.y @@ -516,12 +516,12 @@ static int parse_module_store(char *arg) char *s; current_conf->store_type = SEMANAGE_CON_POLSERV_REMOTE; if ((s = strchr(arg, ':')) == NULL) { - current_conf->store_path = strdup(arg); + current_conf->store_path = arg; current_conf->server_port = 4242; } else { char *endptr; *s = '\0'; - current_conf->store_path = strdup(arg); + current_conf->store_path = arg; current_conf->server_port = strtol(s + 1, &endptr, 10); if (*(s + 1) == '\0' || *endptr != '\0') { return -2; diff --git a/libsemanage/src/context_internal.h b/libsemanage/src/context_internal.h new file mode 100644 index 00000000..729bfc84 --- /dev/null +++ b/libsemanage/src/context_internal.h @@ -0,0 +1,11 @@ +#ifndef _SEMANAGE_CONTEXT_INTERNAL_H_ +#define _SEMANAGE_CONTEXT_INTERNAL_H_ + +#include +#include "dso.h" + +hidden_proto(semanage_context_clone) + hidden_proto(semanage_context_free) + hidden_proto(semanage_context_from_string) + hidden_proto(semanage_context_to_string) +#endif diff --git a/libsemanage/src/context_record.c b/libsemanage/src/context_record.c index 16ba518e..a228565e 100644 --- a/libsemanage/src/context_record.c +++ b/libsemanage/src/context_record.c @@ -6,6 +6,7 @@ typedef sepol_context_t semanage_context_t; #define _SEMANAGE_CONTEXT_DEFINED_ +#include "context_internal.h" /* User */ const char *semanage_context_get_user(const semanage_context_t * con) @@ -79,6 +80,7 @@ int semanage_context_clone(semanage_handle_t * handle, return sepol_context_clone(handle->sepolh, con, con_ptr); } +hidden_def(semanage_context_clone) void semanage_context_free(semanage_context_t * con) { @@ -86,6 +88,7 @@ void semanage_context_free(semanage_context_t * con) sepol_context_free(con); } +hidden_def(semanage_context_free) /* Parse to/from string */ int semanage_context_from_string(semanage_handle_t * handle, @@ -95,6 +98,7 @@ int semanage_context_from_string(semanage_handle_t * handle, return sepol_context_from_string(handle->sepolh, str, con); } +hidden_def(semanage_context_from_string) int semanage_context_to_string(semanage_handle_t * handle, const semanage_context_t * con, char **str_ptr) @@ -103,3 +107,4 @@ int semanage_context_to_string(semanage_handle_t * handle, return sepol_context_to_string(handle->sepolh, con, str_ptr); } +hidden_def(semanage_context_to_string) diff --git a/libsemanage/src/database_llist.c b/libsemanage/src/database_llist.c index 240b2557..c8f4ff0b 100644 --- a/libsemanage/src/database_llist.c +++ b/libsemanage/src/database_llist.c @@ -218,7 +218,7 @@ int dbase_llist_modify(semanage_handle_t * handle, return STATUS_ERR; } - int dbase_llist_count(semanage_handle_t * handle __attribute__ ((unused)), +hidden int dbase_llist_count(semanage_handle_t * handle __attribute__ ((unused)), dbase_llist_t * dbase, unsigned int *response) { diff --git a/libsemanage/src/debug.c b/libsemanage/src/debug.c index 3c345462..08a9e026 100644 --- a/libsemanage/src/debug.c +++ b/libsemanage/src/debug.c @@ -33,22 +33,25 @@ int semanage_msg_get_level(semanage_handle_t * handle) return handle->msg_level; } +hidden_def(semanage_msg_get_level) const char *semanage_msg_get_channel(semanage_handle_t * handle) { return handle->msg_channel; } +hidden_def(semanage_msg_get_channel) const char *semanage_msg_get_fname(semanage_handle_t * handle) { return handle->msg_fname; } +hidden_def(semanage_msg_get_fname) #ifdef __GNUC__ __attribute__ ((format(printf, 3, 4))) #endif -void semanage_msg_default_handler(void *varg __attribute__ ((unused)), +void hidden semanage_msg_default_handler(void *varg __attribute__ ((unused)), semanage_handle_t * handle, const char *fmt, ...) { @@ -88,7 +91,7 @@ void semanage_msg_default_handler(void *varg __attribute__ ((unused)), #ifdef __GNUC__ __attribute__ ((format(printf, 3, 4))) #endif -void semanage_msg_relay_handler(void *varg, +void hidden semanage_msg_relay_handler(void *varg, sepol_handle_t * sepolh, const char *fmt, ...) { diff --git a/libsemanage/src/debug.h b/libsemanage/src/debug.h index a18a95be..92bfcf5f 100644 --- a/libsemanage/src/debug.h +++ b/libsemanage/src/debug.h @@ -27,6 +27,7 @@ #include #include #include "handle.h" +#include "dso.h" #define STATUS_SUCCESS 0 #define STATUS_ERR -1 @@ -61,15 +62,18 @@ #ifdef __GNUC__ __attribute__ ((format(printf, 3, 4))) #endif -extern void semanage_msg_default_handler(void *varg, +extern void hidden semanage_msg_default_handler(void *varg, semanage_handle_t * handle, const char *fmt, ...); #ifdef __GNUC__ __attribute__ ((format(printf, 3, 4))) #endif -extern void semanage_msg_relay_handler(void *varg, +extern void hidden semanage_msg_relay_handler(void *varg, sepol_handle_t * handle, const char *fmt, ...); +hidden_proto(semanage_msg_get_channel) + hidden_proto(semanage_msg_get_fname) + hidden_proto(semanage_msg_get_level) #endif diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c index f0e2300a..1088a0ac 100644 --- a/libsemanage/src/direct_api.c +++ b/libsemanage/src/direct_api.c @@ -1022,7 +1022,6 @@ static int semanage_direct_write_langext(semanage_handle_t *sh, if (fclose(fp) != 0) { ERR(sh, "Unable to close %s module ext file.", modinfo->name); - fp = NULL; ret = -1; goto cleanup; } @@ -1189,7 +1188,7 @@ cleanup: * overwrite it. If source doesn't exist then return success. * Returns 0 on success, -1 on error. */ static int copy_file_if_exists(const char *src, const char *dst, mode_t mode){ - int rc = semanage_copy_file(src, dst, mode, false); + int rc = semanage_copy_file(src, dst, mode); return (rc < 0 && errno != ENOENT) ? rc : 0; } @@ -1489,7 +1488,7 @@ rebuild: retval = semanage_copy_file(path, semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS), - 0, false); + 0); if (retval < 0) goto cleanup; pseusers->dtable->drop_cache(pseusers->dbase); @@ -1507,7 +1506,7 @@ rebuild: retval = semanage_copy_file(path, semanage_path(SEMANAGE_TMP, SEMANAGE_USERS_EXTRA), - 0, false); + 0); if (retval < 0) goto cleanup; pusers_extra->dtable->drop_cache(pusers_extra->dbase); @@ -1596,7 +1595,7 @@ rebuild: retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL), semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_KERNEL), - sh->conf->file_mode, false); + sh->conf->file_mode); if (retval < 0) { goto cleanup; } @@ -1635,7 +1634,7 @@ rebuild: retval = semanage_copy_file( semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_HOMEDIRS), semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_HOMEDIRS), - sh->conf->file_mode, false); + sh->conf->file_mode); if (retval < 0) { goto cleanup; } @@ -1952,7 +1951,6 @@ static int semanage_direct_remove(semanage_handle_t * sh, char *module_name) status = semanage_direct_remove_key(sh, &modkey); cleanup: - semanage_module_key_destroy(sh, &modkey); return status; } diff --git a/libsemanage/src/dso.h b/libsemanage/src/dso.h new file mode 100644 index 00000000..8c9a0140 --- /dev/null +++ b/libsemanage/src/dso.h @@ -0,0 +1,23 @@ +#ifndef _SEMANAGE_DSO_H +#define _SEMANAGE_DSO_H 1 + +#ifdef SHARED +# define hidden __attribute__ ((visibility ("hidden"))) +# define hidden_proto(fct) __hidden_proto (fct, fct##_internal) +# define __hidden_proto(fct, internal) \ + extern __typeof (fct) internal; \ + extern __typeof (fct) fct __asm (#internal) hidden; +# if defined(__alpha__) || defined(__mips__) +# define hidden_def(fct) \ + asm (".globl " #fct "\n" #fct " = " #fct "_internal"); +# else +# define hidden_def(fct) \ + asm (".globl " #fct "\n.set " #fct ", " #fct "_internal"); +#endif +#else +# define hidden +# define hidden_proto(fct) +# define hidden_def(fct) +#endif + +#endif diff --git a/libsemanage/src/exception.sh b/libsemanage/src/exception.sh index e1d01b59..fc1d4035 100644 --- a/libsemanage/src/exception.sh +++ b/libsemanage/src/exception.sh @@ -6,7 +6,8 @@ echo " PyErr_SetFromErrno(PyExc_OSError); SWIG_fail; } -}" +} +" } if ! ${CC:-gcc} -x c -c -I../include -o temp.o - -aux-info temp.aux < ../include/semanage/semanage.h then diff --git a/libsemanage/src/fcontext_internal.h b/libsemanage/src/fcontext_internal.h index 7ae20f12..c7767d07 100644 --- a/libsemanage/src/fcontext_internal.h +++ b/libsemanage/src/fcontext_internal.h @@ -7,6 +7,24 @@ #include #include "database.h" #include "handle.h" +#include "dso.h" + +hidden_proto(semanage_fcontext_key_create) + hidden_proto(semanage_fcontext_key_extract) + hidden_proto(semanage_fcontext_key_free) + hidden_proto(semanage_fcontext_compare) + hidden_proto(semanage_fcontext_compare2) + hidden_proto(semanage_fcontext_create) + hidden_proto(semanage_fcontext_get_expr) + hidden_proto(semanage_fcontext_set_expr) + hidden_proto(semanage_fcontext_get_type) + hidden_proto(semanage_fcontext_get_type_str) + hidden_proto(semanage_fcontext_set_type) + hidden_proto(semanage_fcontext_get_con) + hidden_proto(semanage_fcontext_set_con) + hidden_proto(semanage_fcontext_clone) + hidden_proto(semanage_fcontext_free) + hidden_proto(semanage_fcontext_iterate_local) /* FCONTEXT RECORD: method table */ extern record_table_t SEMANAGE_FCONTEXT_RTABLE; @@ -18,7 +36,7 @@ extern int fcontext_file_dbase_init(semanage_handle_t * handle, extern void fcontext_file_dbase_release(dbase_config_t * dconfig); -extern int semanage_fcontext_validate_local(semanage_handle_t * handle, +extern int hidden semanage_fcontext_validate_local(semanage_handle_t * handle, const sepol_policydb_t * policydb); diff --git a/libsemanage/src/fcontext_record.c b/libsemanage/src/fcontext_record.c index ae1b0324..f39efa19 100644 --- a/libsemanage/src/fcontext_record.c +++ b/libsemanage/src/fcontext_record.c @@ -7,6 +7,7 @@ typedef struct semanage_fcontext_key record_key_t; #include #include #include "fcontext_internal.h" +#include "context_internal.h" #include "debug.h" struct semanage_fcontext { @@ -56,6 +57,7 @@ int semanage_fcontext_key_create(semanage_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(semanage_fcontext_key_create) int semanage_fcontext_key_extract(semanage_handle_t * handle, const semanage_fcontext_t * fcontext, @@ -73,6 +75,7 @@ int semanage_fcontext_key_extract(semanage_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(semanage_fcontext_key_extract) void semanage_fcontext_key_free(semanage_fcontext_key_t * key) { @@ -80,6 +83,7 @@ void semanage_fcontext_key_free(semanage_fcontext_key_t * key) free(key); } +hidden_def(semanage_fcontext_key_free) int semanage_fcontext_compare(const semanage_fcontext_t * fcontext, const semanage_fcontext_key_t * key) @@ -100,6 +104,7 @@ int semanage_fcontext_compare(const semanage_fcontext_t * fcontext, } } +hidden_def(semanage_fcontext_compare) int semanage_fcontext_compare2(const semanage_fcontext_t * fcontext, const semanage_fcontext_t * fcontext2) @@ -120,6 +125,7 @@ int semanage_fcontext_compare2(const semanage_fcontext_t * fcontext, } } +hidden_def(semanage_fcontext_compare2) static int semanage_fcontext_compare2_qsort(const semanage_fcontext_t ** fcontext, @@ -152,6 +158,7 @@ int semanage_fcontext_create(semanage_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(semanage_fcontext_create) /* Regexp */ const char *semanage_fcontext_get_expr(const semanage_fcontext_t * fcontext) @@ -160,6 +167,7 @@ const char *semanage_fcontext_get_expr(const semanage_fcontext_t * fcontext) return fcontext->expr; } +hidden_def(semanage_fcontext_get_expr) int semanage_fcontext_set_expr(semanage_handle_t * handle, semanage_fcontext_t * fcontext, const char *expr) @@ -175,6 +183,7 @@ int semanage_fcontext_set_expr(semanage_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(semanage_fcontext_set_expr) /* Type */ int semanage_fcontext_get_type(const semanage_fcontext_t * fcontext) @@ -183,6 +192,7 @@ int semanage_fcontext_get_type(const semanage_fcontext_t * fcontext) return fcontext->type; } +hidden_def(semanage_fcontext_get_type) const char *semanage_fcontext_get_type_str(int type) { @@ -209,6 +219,7 @@ const char *semanage_fcontext_get_type_str(int type) } } +hidden_def(semanage_fcontext_get_type_str) void semanage_fcontext_set_type(semanage_fcontext_t * fcontext, int type) { @@ -216,6 +227,7 @@ void semanage_fcontext_set_type(semanage_fcontext_t * fcontext, int type) fcontext->type = type; } +hidden_def(semanage_fcontext_set_type) /* Context */ semanage_context_t *semanage_fcontext_get_con(const semanage_fcontext_t * @@ -225,6 +237,7 @@ semanage_context_t *semanage_fcontext_get_con(const semanage_fcontext_t * return fcontext->con; } +hidden_def(semanage_fcontext_get_con) int semanage_fcontext_set_con(semanage_handle_t * handle, semanage_fcontext_t * fcontext, @@ -243,6 +256,7 @@ int semanage_fcontext_set_con(semanage_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(semanage_fcontext_set_con) /* Deep copy clone */ int semanage_fcontext_clone(semanage_handle_t * handle, @@ -274,6 +288,7 @@ int semanage_fcontext_clone(semanage_handle_t * handle, return STATUS_ERR; } +hidden_def(semanage_fcontext_clone) /* Destroy */ void semanage_fcontext_free(semanage_fcontext_t * fcontext) @@ -287,6 +302,7 @@ void semanage_fcontext_free(semanage_fcontext_t * fcontext) free(fcontext); } +hidden_def(semanage_fcontext_free) /* Record base functions */ record_table_t SEMANAGE_FCONTEXT_RTABLE = { diff --git a/libsemanage/src/fcontexts_file.c b/libsemanage/src/fcontexts_file.c index 04cd365a..1e596519 100644 --- a/libsemanage/src/fcontexts_file.c +++ b/libsemanage/src/fcontexts_file.c @@ -15,6 +15,7 @@ typedef struct dbase_file dbase_t; #include #include #include "fcontext_internal.h" +#include "context_internal.h" #include "database_file.h" #include "parse_utils.h" #include "debug.h" diff --git a/libsemanage/src/fcontexts_local.c b/libsemanage/src/fcontexts_local.c index ea994d8c..b0da236b 100644 --- a/libsemanage/src/fcontexts_local.c +++ b/libsemanage/src/fcontexts_local.c @@ -10,6 +10,7 @@ typedef struct semanage_fcontext record_t; #include #include #include "fcontext_internal.h" +#include "context_internal.h" #include "debug.h" #include "handle.h" #include "database.h" @@ -67,6 +68,7 @@ int semanage_fcontext_iterate_local(semanage_handle_t * handle, return dbase_iterate(handle, dconfig, handler, handler_arg); } +hidden_def(semanage_fcontext_iterate_local) int semanage_fcontext_list_local(semanage_handle_t * handle, semanage_fcontext_t *** records, @@ -116,7 +118,7 @@ static int validate_handler(const semanage_fcontext_t * fcon, void *varg) return -1; } -int semanage_fcontext_validate_local(semanage_handle_t * handle, +int hidden semanage_fcontext_validate_local(semanage_handle_t * handle, const sepol_policydb_t * policydb) { diff --git a/libsemanage/src/genhomedircon.c b/libsemanage/src/genhomedircon.c index 7ca9afc3..d08c88de 100644 --- a/libsemanage/src/genhomedircon.c +++ b/libsemanage/src/genhomedircon.c @@ -740,7 +740,7 @@ static int write_user_context(genhomedircon_settings_t * s, FILE * out, static int seuser_sort_func(const void *arg1, const void *arg2) { const semanage_seuser_t **u1 = (const semanage_seuser_t **) arg1; - const semanage_seuser_t **u2 = (const semanage_seuser_t **) arg2; + const semanage_seuser_t **u2 = (const semanage_seuser_t **) arg2;; const char *name1 = semanage_seuser_get_name(*u1); const char *name2 = semanage_seuser_get_name(*u2); diff --git a/libsemanage/src/handle.c b/libsemanage/src/handle.c index bb1e6140..5e59aef7 100644 --- a/libsemanage/src/handle.c +++ b/libsemanage/src/handle.c @@ -48,6 +48,7 @@ int semanage_set_root(const char *root) return 0; } +hidden_def(semanage_set_root); const char * semanage_root(void) { @@ -57,6 +58,7 @@ const char * semanage_root(void) return private_semanage_root; } +hidden_def(semanage_root); semanage_handle_t *semanage_handle_create(void) { @@ -362,6 +364,7 @@ int semanage_access_check(semanage_handle_t * sh) return -1; /* unreachable */ } +hidden_def(semanage_access_check) int semanage_disconnect(semanage_handle_t * sh) { @@ -391,6 +394,7 @@ void semanage_handle_destroy(semanage_handle_t * sh) free(sh); } +hidden_def(semanage_handle_destroy) /********************* public transaction functions *********************/ int semanage_begin_transaction(semanage_handle_t * sh) @@ -412,6 +416,7 @@ int semanage_begin_transaction(semanage_handle_t * sh) return 0; } +hidden_def(semanage_begin_transaction) int semanage_commit(semanage_handle_t * sh) { diff --git a/libsemanage/src/handle.h b/libsemanage/src/handle.h index e1ce83ba..a91907b0 100644 --- a/libsemanage/src/handle.h +++ b/libsemanage/src/handle.h @@ -25,6 +25,7 @@ #include #include +#include "handle_internal.h" #include #include "modules.h" #include "semanage_conf.h" diff --git a/libsemanage/src/handle_internal.h b/libsemanage/src/handle_internal.h new file mode 100644 index 00000000..d4b4d9c7 --- /dev/null +++ b/libsemanage/src/handle_internal.h @@ -0,0 +1,13 @@ +#ifndef _SEMANAGE_HANDLE_INTERNAL_H_ +#define _SEMANAGE_HANDLE_INTERNAL_H_ + +#include +#include "dso.h" + +hidden_proto(semanage_begin_transaction) +hidden_proto(semanage_handle_destroy) +hidden_proto(semanage_reload_policy) +hidden_proto(semanage_access_check) +hidden_proto(semanage_set_root) +hidden_proto(semanage_root) +#endif diff --git a/libsemanage/src/ibendport_internal.h b/libsemanage/src/ibendport_internal.h index eada2d4b..970fbdb2 100644 --- a/libsemanage/src/ibendport_internal.h +++ b/libsemanage/src/ibendport_internal.h @@ -6,6 +6,22 @@ #include #include "database.h" #include "handle.h" +#include "dso.h" + +hidden_proto(semanage_ibendport_create) +hidden_proto(semanage_ibendport_compare) +hidden_proto(semanage_ibendport_compare2) +hidden_proto(semanage_ibendport_clone) +hidden_proto(semanage_ibendport_free) +hidden_proto(semanage_ibendport_key_extract) +hidden_proto(semanage_ibendport_key_free) +hidden_proto(semanage_ibendport_get_port) +hidden_proto(semanage_ibendport_set_port) +hidden_proto(semanage_ibendport_get_con) +hidden_proto(semanage_ibendport_set_con) +hidden_proto(semanage_ibendport_list_local) +hidden_proto(semanage_ibendport_get_ibdev_name) +hidden_proto(semanage_ibendport_set_ibdev_name) /* IBENDPORT RECORD: method table */ extern record_table_t SEMANAGE_IBENDPORT_RTABLE; @@ -22,11 +38,11 @@ extern int ibendport_policydb_dbase_init(semanage_handle_t *handle, extern void ibendport_policydb_dbase_release(dbase_config_t *dconfig); -extern int semanage_ibendport_validate_local(semanage_handle_t *handle); +extern int hidden semanage_ibendport_validate_local(semanage_handle_t *handle); /* ==== Internal (to ibendports) API === */ - int semanage_ibendport_compare2_qsort(const semanage_ibendport_t **ibendport, +hidden int semanage_ibendport_compare2_qsort(const semanage_ibendport_t **ibendport, const semanage_ibendport_t **ibendport2); #endif diff --git a/libsemanage/src/ibendport_record.c b/libsemanage/src/ibendport_record.c index a8cb125d..955067ea 100644 --- a/libsemanage/src/ibendport_record.c +++ b/libsemanage/src/ibendport_record.c @@ -29,6 +29,7 @@ int semanage_ibendport_compare(const semanage_ibendport_t *ibendport, return sepol_ibendport_compare(ibendport, key); } +hidden_def(semanage_ibendport_compare) int semanage_ibendport_compare2(const semanage_ibendport_t *ibendport, const semanage_ibendport_t *ibendport2) @@ -36,8 +37,9 @@ int semanage_ibendport_compare2(const semanage_ibendport_t *ibendport, return sepol_ibendport_compare2(ibendport, ibendport2); } +hidden_def(semanage_ibendport_compare2) - int semanage_ibendport_compare2_qsort(const semanage_ibendport_t **ibendport, +hidden int semanage_ibendport_compare2_qsort(const semanage_ibendport_t **ibendport, const semanage_ibendport_t **ibendport2) { return sepol_ibendport_compare2(*ibendport, *ibendport2); @@ -58,12 +60,14 @@ int semanage_ibendport_key_extract(semanage_handle_t *handle, return sepol_ibendport_key_extract(handle->sepolh, ibendport, key_ptr); } +hidden_def(semanage_ibendport_key_extract) void semanage_ibendport_key_free(semanage_ibendport_key_t *key) { sepol_ibendport_key_free(key); } +hidden_def(semanage_ibendport_key_free) int semanage_ibendport_get_ibdev_name(semanage_handle_t *handle, const semanage_ibendport_t *ibendport, @@ -72,6 +76,7 @@ int semanage_ibendport_get_ibdev_name(semanage_handle_t *handle, return sepol_ibendport_get_ibdev_name(handle->sepolh, ibendport, ibdev_name_ptr); } +hidden_def(semanage_ibendport_get_ibdev_name) int semanage_ibendport_set_ibdev_name(semanage_handle_t *handle, semanage_ibendport_t *ibendport, @@ -80,24 +85,28 @@ int semanage_ibendport_set_ibdev_name(semanage_handle_t *handle, return sepol_ibendport_set_ibdev_name(handle->sepolh, ibendport, ibdev_name); } +hidden_def(semanage_ibendport_set_ibdev_name) int semanage_ibendport_get_port(const semanage_ibendport_t *ibendport) { return sepol_ibendport_get_port(ibendport); } +hidden_def(semanage_ibendport_get_port) void semanage_ibendport_set_port(semanage_ibendport_t *ibendport, int port) { sepol_ibendport_set_port(ibendport, port); } +hidden_def(semanage_ibendport_set_port) semanage_context_t *semanage_ibendport_get_con(const semanage_ibendport_t *ibendport) { return sepol_ibendport_get_con(ibendport); } +hidden_def(semanage_ibendport_get_con) int semanage_ibendport_set_con(semanage_handle_t *handle, semanage_ibendport_t *ibendport, @@ -106,6 +115,7 @@ int semanage_ibendport_set_con(semanage_handle_t *handle, return sepol_ibendport_set_con(handle->sepolh, ibendport, con); } +hidden_def(semanage_ibendport_set_con) int semanage_ibendport_create(semanage_handle_t *handle, semanage_ibendport_t **ibendport_ptr) @@ -113,6 +123,7 @@ int semanage_ibendport_create(semanage_handle_t *handle, return sepol_ibendport_create(handle->sepolh, ibendport_ptr); } +hidden_def(semanage_ibendport_create) int semanage_ibendport_clone(semanage_handle_t *handle, const semanage_ibendport_t *ibendport, @@ -121,12 +132,14 @@ int semanage_ibendport_clone(semanage_handle_t *handle, return sepol_ibendport_clone(handle->sepolh, ibendport, ibendport_ptr); } +hidden_def(semanage_ibendport_clone) void semanage_ibendport_free(semanage_ibendport_t *ibendport) { sepol_ibendport_free(ibendport); } +hidden_def(semanage_ibendport_free) /*key base functions */ record_table_t SEMANAGE_IBENDPORT_RTABLE = { diff --git a/libsemanage/src/ibendports_file.c b/libsemanage/src/ibendports_file.c index bafa8c1d..402c7a5e 100644 --- a/libsemanage/src/ibendports_file.c +++ b/libsemanage/src/ibendports_file.c @@ -15,6 +15,7 @@ typedef struct dbase_file dbase_t; #include #include #include "ibendport_internal.h" +#include "context_internal.h" #include "database_file.h" #include "parse_utils.h" #include "debug.h" diff --git a/libsemanage/src/ibendports_local.c b/libsemanage/src/ibendports_local.c index e696fdca..8b5567d8 100644 --- a/libsemanage/src/ibendports_local.c +++ b/libsemanage/src/ibendports_local.c @@ -74,8 +74,9 @@ int semanage_ibendport_list_local(semanage_handle_t *handle, return dbase_list(handle, dconfig, records, count); } +hidden_def(semanage_ibendport_list_local) -int semanage_ibendport_validate_local(semanage_handle_t *handle) +int hidden semanage_ibendport_validate_local(semanage_handle_t *handle) { semanage_ibendport_t **ibendports = NULL; unsigned int nibendports = 0; diff --git a/libsemanage/src/ibpkey_internal.h b/libsemanage/src/ibpkey_internal.h index 1e206b62..9465bb8d 100644 --- a/libsemanage/src/ibpkey_internal.h +++ b/libsemanage/src/ibpkey_internal.h @@ -6,6 +6,26 @@ #include #include "database.h" #include "handle.h" +#include "dso.h" + +hidden_proto(semanage_ibpkey_create) +hidden_proto(semanage_ibpkey_compare) +hidden_proto(semanage_ibpkey_compare2) +hidden_proto(semanage_ibpkey_clone) +hidden_proto(semanage_ibpkey_free) +hidden_proto(semanage_ibpkey_key_extract) +hidden_proto(semanage_ibpkey_key_free) +hidden_proto(semanage_ibpkey_get_high) +hidden_proto(semanage_ibpkey_get_low) +hidden_proto(semanage_ibpkey_set_pkey) +hidden_proto(semanage_ibpkey_set_range) +hidden_proto(semanage_ibpkey_get_con) +hidden_proto(semanage_ibpkey_set_con) +hidden_proto(semanage_ibpkey_list_local) +hidden_proto(semanage_ibpkey_get_subnet_prefix) +hidden_proto(semanage_ibpkey_get_subnet_prefix_bytes) +hidden_proto(semanage_ibpkey_set_subnet_prefix) +hidden_proto(semanage_ibpkey_set_subnet_prefix_bytes) /* PKEY RECORD: method table */ extern record_table_t SEMANAGE_IBPKEY_RTABLE; @@ -22,11 +42,11 @@ extern int ibpkey_policydb_dbase_init(semanage_handle_t *handle, extern void ibpkey_policydb_dbase_release(dbase_config_t *dconfig); -extern int semanage_ibpkey_validate_local(semanage_handle_t *handle); +extern int hidden semanage_ibpkey_validate_local(semanage_handle_t *handle); /* ==== Internal (to ibpkeys) API === */ - int semanage_ibpkey_compare2_qsort(const semanage_ibpkey_t **ibpkey, +hidden int semanage_ibpkey_compare2_qsort(const semanage_ibpkey_t **ibpkey, const semanage_ibpkey_t **ibpkey2); #endif diff --git a/libsemanage/src/ibpkey_record.c b/libsemanage/src/ibpkey_record.c index bb7fa6ea..ca5bc76d 100644 --- a/libsemanage/src/ibpkey_record.c +++ b/libsemanage/src/ibpkey_record.c @@ -29,6 +29,7 @@ int semanage_ibpkey_compare(const semanage_ibpkey_t *ibpkey, return sepol_ibpkey_compare(ibpkey, key); } +hidden_def(semanage_ibpkey_compare) int semanage_ibpkey_compare2(const semanage_ibpkey_t *ibpkey, const semanage_ibpkey_t *ibpkey2) @@ -36,8 +37,9 @@ int semanage_ibpkey_compare2(const semanage_ibpkey_t *ibpkey, return sepol_ibpkey_compare2(ibpkey, ibpkey2); } +hidden_def(semanage_ibpkey_compare2) - int semanage_ibpkey_compare2_qsort(const semanage_ibpkey_t **ibpkey, +hidden int semanage_ibpkey_compare2_qsort(const semanage_ibpkey_t **ibpkey, const semanage_ibpkey_t **ibpkey2) { return sepol_ibpkey_compare2(*ibpkey, *ibpkey2); @@ -58,12 +60,14 @@ int semanage_ibpkey_key_extract(semanage_handle_t *handle, return sepol_ibpkey_key_extract(handle->sepolh, ibpkey, key_ptr); } +hidden_def(semanage_ibpkey_key_extract) void semanage_ibpkey_key_free(semanage_ibpkey_key_t *key) { sepol_ibpkey_key_free(key); } +hidden_def(semanage_ibpkey_key_free) int semanage_ibpkey_get_subnet_prefix(semanage_handle_t *handle, const semanage_ibpkey_t *ibpkey, @@ -72,12 +76,14 @@ int semanage_ibpkey_get_subnet_prefix(semanage_handle_t *handle, return sepol_ibpkey_get_subnet_prefix(handle->sepolh, ibpkey, subnet_prefix_ptr); } +hidden_def(semanage_ibpkey_get_subnet_prefix) uint64_t semanage_ibpkey_get_subnet_prefix_bytes(const semanage_ibpkey_t *ibpkey) { return sepol_ibpkey_get_subnet_prefix_bytes(ibpkey); } +hidden_def(semanage_ibpkey_get_subnet_prefix_bytes) int semanage_ibpkey_set_subnet_prefix(semanage_handle_t *handle, semanage_ibpkey_t *ibpkey, @@ -86,6 +92,7 @@ int semanage_ibpkey_set_subnet_prefix(semanage_handle_t *handle, return sepol_ibpkey_set_subnet_prefix(handle->sepolh, ibpkey, subnet_prefix); } +hidden_def(semanage_ibpkey_set_subnet_prefix) void semanage_ibpkey_set_subnet_prefix_bytes(semanage_ibpkey_t *ibpkey, uint64_t subnet_prefix) @@ -93,36 +100,42 @@ void semanage_ibpkey_set_subnet_prefix_bytes(semanage_ibpkey_t *ibpkey, return sepol_ibpkey_set_subnet_prefix_bytes(ibpkey, subnet_prefix); } +hidden_def(semanage_ibpkey_set_subnet_prefix_bytes) int semanage_ibpkey_get_low(const semanage_ibpkey_t *ibpkey) { return sepol_ibpkey_get_low(ibpkey); } +hidden_def(semanage_ibpkey_get_low) int semanage_ibpkey_get_high(const semanage_ibpkey_t *ibpkey) { return sepol_ibpkey_get_high(ibpkey); } +hidden_def(semanage_ibpkey_get_high) void semanage_ibpkey_set_pkey(semanage_ibpkey_t *ibpkey, int ibpkey_num) { sepol_ibpkey_set_pkey(ibpkey, ibpkey_num); } +hidden_def(semanage_ibpkey_set_pkey) void semanage_ibpkey_set_range(semanage_ibpkey_t *ibpkey, int low, int high) { sepol_ibpkey_set_range(ibpkey, low, high); } +hidden_def(semanage_ibpkey_set_range) semanage_context_t *semanage_ibpkey_get_con(const semanage_ibpkey_t *ibpkey) { return sepol_ibpkey_get_con(ibpkey); } +hidden_def(semanage_ibpkey_get_con) int semanage_ibpkey_set_con(semanage_handle_t *handle, semanage_ibpkey_t *ibpkey, semanage_context_t *con) @@ -130,6 +143,7 @@ int semanage_ibpkey_set_con(semanage_handle_t *handle, return sepol_ibpkey_set_con(handle->sepolh, ibpkey, con); } +hidden_def(semanage_ibpkey_set_con) int semanage_ibpkey_create(semanage_handle_t *handle, semanage_ibpkey_t **ibpkey_ptr) @@ -137,6 +151,7 @@ int semanage_ibpkey_create(semanage_handle_t *handle, return sepol_ibpkey_create(handle->sepolh, ibpkey_ptr); } +hidden_def(semanage_ibpkey_create) int semanage_ibpkey_clone(semanage_handle_t *handle, const semanage_ibpkey_t *ibpkey, @@ -145,12 +160,14 @@ int semanage_ibpkey_clone(semanage_handle_t *handle, return sepol_ibpkey_clone(handle->sepolh, ibpkey, ibpkey_ptr); } +hidden_def(semanage_ibpkey_clone) void semanage_ibpkey_free(semanage_ibpkey_t *ibpkey) { sepol_ibpkey_free(ibpkey); } +hidden_def(semanage_ibpkey_free) /* key base functions */ record_table_t SEMANAGE_IBPKEY_RTABLE = { diff --git a/libsemanage/src/ibpkeys_file.c b/libsemanage/src/ibpkeys_file.c index 929bc31e..ceaea7ad 100644 --- a/libsemanage/src/ibpkeys_file.c +++ b/libsemanage/src/ibpkeys_file.c @@ -15,6 +15,7 @@ typedef struct dbase_file dbase_t; #include #include #include "ibpkey_internal.h" +#include "context_internal.h" #include "database_file.h" #include "parse_utils.h" #include "debug.h" diff --git a/libsemanage/src/ibpkeys_local.c b/libsemanage/src/ibpkeys_local.c index 6d05d125..e194ee01 100644 --- a/libsemanage/src/ibpkeys_local.c +++ b/libsemanage/src/ibpkeys_local.c @@ -74,8 +74,9 @@ int semanage_ibpkey_list_local(semanage_handle_t *handle, return dbase_list(handle, dconfig, records, count); } +hidden_def(semanage_ibpkey_list_local) -int semanage_ibpkey_validate_local(semanage_handle_t *handle) +int hidden semanage_ibpkey_validate_local(semanage_handle_t *handle) { semanage_ibpkey_t **ibpkeys = NULL; unsigned int nibpkeys = 0; diff --git a/libsemanage/src/iface_internal.h b/libsemanage/src/iface_internal.h index df38fb0f..5cb77789 100644 --- a/libsemanage/src/iface_internal.h +++ b/libsemanage/src/iface_internal.h @@ -6,6 +6,21 @@ #include #include "database.h" #include "handle.h" +#include "dso.h" + +hidden_proto(semanage_iface_create) + hidden_proto(semanage_iface_compare) + hidden_proto(semanage_iface_compare2) + hidden_proto(semanage_iface_clone) + hidden_proto(semanage_iface_free) + hidden_proto(semanage_iface_get_ifcon) + hidden_proto(semanage_iface_get_msgcon) + hidden_proto(semanage_iface_get_name) + hidden_proto(semanage_iface_key_extract) + hidden_proto(semanage_iface_key_free) + hidden_proto(semanage_iface_set_ifcon) + hidden_proto(semanage_iface_set_msgcon) + hidden_proto(semanage_iface_set_name) /* IFACE RECORD: method table */ extern record_table_t SEMANAGE_IFACE_RTABLE; diff --git a/libsemanage/src/iface_record.c b/libsemanage/src/iface_record.c index e54cdd2d..e7d72d75 100644 --- a/libsemanage/src/iface_record.c +++ b/libsemanage/src/iface_record.c @@ -31,6 +31,7 @@ int semanage_iface_compare(const semanage_iface_t * iface, return sepol_iface_compare(iface, key); } +hidden_def(semanage_iface_compare) int semanage_iface_compare2(const semanage_iface_t * iface, const semanage_iface_t * iface2) @@ -39,6 +40,7 @@ int semanage_iface_compare2(const semanage_iface_t * iface, return sepol_iface_compare2(iface, iface2); } +hidden_def(semanage_iface_compare2) static int semanage_iface_compare2_qsort(const semanage_iface_t ** iface, const semanage_iface_t ** iface2) @@ -62,6 +64,7 @@ int semanage_iface_key_extract(semanage_handle_t * handle, return sepol_iface_key_extract(handle->sepolh, iface, key_ptr); } +hidden_def(semanage_iface_key_extract) void semanage_iface_key_free(semanage_iface_key_t * key) { @@ -69,6 +72,7 @@ void semanage_iface_key_free(semanage_iface_key_t * key) sepol_iface_key_free(key); } +hidden_def(semanage_iface_key_free) /* Name */ const char *semanage_iface_get_name(const semanage_iface_t * iface) @@ -77,6 +81,7 @@ const char *semanage_iface_get_name(const semanage_iface_t * iface) return sepol_iface_get_name(iface); } +hidden_def(semanage_iface_get_name) int semanage_iface_set_name(semanage_handle_t * handle, semanage_iface_t * iface, const char *name) @@ -85,6 +90,7 @@ int semanage_iface_set_name(semanage_handle_t * handle, return sepol_iface_set_name(handle->sepolh, iface, name); } +hidden_def(semanage_iface_set_name) /* Context */ semanage_context_t *semanage_iface_get_ifcon(const semanage_iface_t * iface) @@ -93,6 +99,7 @@ semanage_context_t *semanage_iface_get_ifcon(const semanage_iface_t * iface) return sepol_iface_get_ifcon(iface); } +hidden_def(semanage_iface_get_ifcon) int semanage_iface_set_ifcon(semanage_handle_t * handle, semanage_iface_t * iface, semanage_context_t * con) @@ -101,6 +108,7 @@ int semanage_iface_set_ifcon(semanage_handle_t * handle, return sepol_iface_set_ifcon(handle->sepolh, iface, con); } +hidden_def(semanage_iface_set_ifcon) semanage_context_t *semanage_iface_get_msgcon(const semanage_iface_t * iface) { @@ -108,6 +116,7 @@ semanage_context_t *semanage_iface_get_msgcon(const semanage_iface_t * iface) return sepol_iface_get_msgcon(iface); } +hidden_def(semanage_iface_get_msgcon) int semanage_iface_set_msgcon(semanage_handle_t * handle, semanage_iface_t * iface, @@ -117,6 +126,7 @@ int semanage_iface_set_msgcon(semanage_handle_t * handle, return sepol_iface_set_msgcon(handle->sepolh, iface, con); } +hidden_def(semanage_iface_set_msgcon) /* Create/Clone/Destroy */ int semanage_iface_create(semanage_handle_t * handle, @@ -126,6 +136,7 @@ int semanage_iface_create(semanage_handle_t * handle, return sepol_iface_create(handle->sepolh, iface_ptr); } +hidden_def(semanage_iface_create) int semanage_iface_clone(semanage_handle_t * handle, const semanage_iface_t * iface, @@ -135,6 +146,7 @@ int semanage_iface_clone(semanage_handle_t * handle, return sepol_iface_clone(handle->sepolh, iface, iface_ptr); } +hidden_def(semanage_iface_clone) void semanage_iface_free(semanage_iface_t * iface) { @@ -142,6 +154,7 @@ void semanage_iface_free(semanage_iface_t * iface) sepol_iface_free(iface); } +hidden_def(semanage_iface_free) /* Record base functions */ record_table_t SEMANAGE_IFACE_RTABLE = { diff --git a/libsemanage/src/interfaces_file.c b/libsemanage/src/interfaces_file.c index c19c8f94..1478af97 100644 --- a/libsemanage/src/interfaces_file.c +++ b/libsemanage/src/interfaces_file.c @@ -14,6 +14,7 @@ typedef struct dbase_file dbase_t; #include #include #include "iface_internal.h" +#include "context_internal.h" #include "database_file.h" #include "parse_utils.h" #include "debug.h" diff --git a/libsemanage/src/libsemanage.map b/libsemanage/src/libsemanage.map index 3ea7b60f..02036696 100644 --- a/libsemanage/src/libsemanage.map +++ b/libsemanage/src/libsemanage.map @@ -1,347 +1,65 @@ LIBSEMANAGE_1.0 { - global: - semanage_access_check; - semanage_begin_transaction; - semanage_bool_clone; - semanage_bool_compare; - semanage_bool_compare2; - semanage_bool_count; - semanage_bool_count_active; - semanage_bool_count_local; - semanage_bool_create; - semanage_bool_del_local; - semanage_bool_exists; - semanage_bool_exists_active; - semanage_bool_exists_local; - semanage_bool_free; - semanage_bool_get_name; - semanage_bool_get_value; - semanage_bool_iterate; - semanage_bool_iterate_active; - semanage_bool_iterate_local; - semanage_bool_key_create; - semanage_bool_key_extract; - semanage_bool_key_free; - semanage_bool_list; - semanage_bool_list_active; - semanage_bool_list_local; - semanage_bool_modify_local; - semanage_bool_query; - semanage_bool_query_active; - semanage_bool_query_local; - semanage_bool_set_active; - semanage_bool_set_name; - semanage_bool_set_value; - semanage_commit; - semanage_connect; - semanage_context_clone; - semanage_context_create; - semanage_context_free; - semanage_context_from_string; - semanage_context_get_mls; - semanage_context_get_role; - semanage_context_get_type; - semanage_context_get_user; - semanage_context_set_mls; - semanage_context_set_role; - semanage_context_set_type; - semanage_context_set_user; - semanage_context_to_string; - semanage_disconnect; - semanage_fcontext_clone; - semanage_fcontext_compare; - semanage_fcontext_compare2; - semanage_fcontext_count; - semanage_fcontext_count_local; - semanage_fcontext_create; - semanage_fcontext_del_local; - semanage_fcontext_exists; - semanage_fcontext_exists_local; - semanage_fcontext_free; - semanage_fcontext_get_con; - semanage_fcontext_get_expr; - semanage_fcontext_get_type; - semanage_fcontext_get_type_str; - semanage_fcontext_iterate; - semanage_fcontext_iterate_local; - semanage_fcontext_key_create; - semanage_fcontext_key_extract; - semanage_fcontext_key_free; - semanage_fcontext_list; - semanage_fcontext_list_homedirs; - semanage_fcontext_list_local; - semanage_fcontext_modify_local; - semanage_fcontext_query; - semanage_fcontext_query_local; - semanage_fcontext_set_con; - semanage_fcontext_set_expr; - semanage_fcontext_set_type; - semanage_get_disable_dontaudit; - semanage_get_preserve_tunables; - semanage_handle_create; - semanage_handle_destroy; - semanage_ibendport_clone; - semanage_ibendport_compare; - semanage_ibendport_compare2; - semanage_ibendport_count; - semanage_ibendport_count_local; - semanage_ibendport_create; - semanage_ibendport_del_local; - semanage_ibendport_exists; - semanage_ibendport_exists_local; - semanage_ibendport_free; - semanage_ibendport_get_con; - semanage_ibendport_get_ibdev_name; - semanage_ibendport_get_port; - semanage_ibendport_iterate; - semanage_ibendport_iterate_local; - semanage_ibendport_key_create; - semanage_ibendport_key_extract; - semanage_ibendport_key_free; - semanage_ibendport_list; - semanage_ibendport_list_local; - semanage_ibendport_modify_local; - semanage_ibendport_query; - semanage_ibendport_query_local; - semanage_ibendport_set_con; - semanage_ibendport_set_ibdev_name; - semanage_ibendport_set_port; - semanage_ibpkey_clone; - semanage_ibpkey_compare; - semanage_ibpkey_compare2; - semanage_ibpkey_count; - semanage_ibpkey_count_local; - semanage_ibpkey_create; - semanage_ibpkey_del_local; - semanage_ibpkey_exists; - semanage_ibpkey_exists_local; - semanage_ibpkey_free; - semanage_ibpkey_get_con; - semanage_ibpkey_get_high; - semanage_ibpkey_get_low; - semanage_ibpkey_get_subnet_prefix; - semanage_ibpkey_get_subnet_prefix_bytes; - semanage_ibpkey_iterate; - semanage_ibpkey_iterate_local; - semanage_ibpkey_key_create; - semanage_ibpkey_key_extract; - semanage_ibpkey_key_free; - semanage_ibpkey_list; - semanage_ibpkey_list_local; - semanage_ibpkey_modify_local; - semanage_ibpkey_query; - semanage_ibpkey_query_local; - semanage_ibpkey_set_con; - semanage_ibpkey_set_pkey; - semanage_ibpkey_set_range; - semanage_ibpkey_set_subnet_prefix; - semanage_ibpkey_set_subnet_prefix_bytes; - semanage_iface_clone; - semanage_iface_compare; - semanage_iface_compare2; - semanage_iface_count; - semanage_iface_count_local; - semanage_iface_create; - semanage_iface_del_local; - semanage_iface_exists; - semanage_iface_exists_local; - semanage_iface_free; - semanage_iface_get_ifcon; - semanage_iface_get_msgcon; - semanage_iface_get_name; - semanage_iface_iterate; - semanage_iface_iterate_local; - semanage_iface_key_create; - semanage_iface_key_extract; - semanage_iface_key_free; - semanage_iface_list; - semanage_iface_list_local; - semanage_iface_modify_local; - semanage_iface_query; - semanage_iface_query_local; - semanage_iface_set_ifcon; - semanage_iface_set_msgcon; - semanage_iface_set_name; - semanage_is_connected; - semanage_is_managed; - semanage_mls_enabled; - semanage_module_get_name; - semanage_module_get_version; - semanage_module_info_datum_destroy; - semanage_module_install_file; - semanage_module_list; - semanage_module_list_nth; - semanage_module_remove; - semanage_module_upgrade_file; - semanage_msg_get_channel; - semanage_msg_get_fname; - semanage_msg_get_level; - semanage_msg_set_callback; - semanage_node_clone; - semanage_node_compare; - semanage_node_compare2; - semanage_node_count; - semanage_node_count_local; - semanage_node_create; - semanage_node_del_local; - semanage_node_exists; - semanage_node_exists_local; - semanage_node_free; - semanage_node_get_addr; - semanage_node_get_addr_bytes; - semanage_node_get_con; - semanage_node_get_mask; - semanage_node_get_mask_bytes; - semanage_node_get_proto; - semanage_node_get_proto_str; - semanage_node_iterate; - semanage_node_iterate_local; - semanage_node_key_create; - semanage_node_key_extract; - semanage_node_key_free; - semanage_node_list; - semanage_node_list_local; - semanage_node_modify_local; - semanage_node_query; - semanage_node_query_local; - semanage_node_set_addr; - semanage_node_set_addr_bytes; - semanage_node_set_con; - semanage_node_set_mask; - semanage_node_set_mask_bytes; - semanage_node_set_proto; - semanage_port_clone; - semanage_port_compare; - semanage_port_compare2; - semanage_port_count; - semanage_port_count_local; - semanage_port_create; - semanage_port_del_local; - semanage_port_exists; - semanage_port_exists_local; - semanage_port_free; - semanage_port_get_con; - semanage_port_get_high; - semanage_port_get_low; - semanage_port_get_proto; - semanage_port_get_proto_str; - semanage_port_iterate; - semanage_port_iterate_local; - semanage_port_key_create; - semanage_port_key_extract; - semanage_port_key_free; - semanage_port_list; - semanage_port_list_local; - semanage_port_modify_local; - semanage_port_query; - semanage_port_query_local; - semanage_port_set_con; - semanage_port_set_port; - semanage_port_set_proto; - semanage_port_set_range; - semanage_reload_policy; - semanage_root; - semanage_select_store; - semanage_set_check_contexts; - semanage_set_create_store; - semanage_set_disable_dontaudit; - semanage_set_preserve_tunables; - semanage_set_rebuild; - semanage_set_reload; - semanage_set_root; - semanage_seuser_clone; - semanage_seuser_compare; - semanage_seuser_compare2; - semanage_seuser_count; - semanage_seuser_count_local; - semanage_seuser_create; - semanage_seuser_del_local; - semanage_seuser_exists; - semanage_seuser_exists_local; - semanage_seuser_free; - semanage_seuser_get_mlsrange; - semanage_seuser_get_name; - semanage_seuser_get_sename; - semanage_seuser_iterate; - semanage_seuser_iterate_local; - semanage_seuser_key_create; - semanage_seuser_key_extract; - semanage_seuser_key_free; - semanage_seuser_list; - semanage_seuser_list_local; - semanage_seuser_modify_local; - semanage_seuser_query; - semanage_seuser_query_local; - semanage_seuser_set_mlsrange; - semanage_seuser_set_name; - semanage_seuser_set_sename; - semanage_user_add_role; - semanage_user_clone; - semanage_user_compare; - semanage_user_compare2; - semanage_user_count; - semanage_user_count_local; - semanage_user_create; - semanage_user_del_local; - semanage_user_del_role; - semanage_user_exists; - semanage_user_exists_local; - semanage_user_free; - semanage_user_get_mlslevel; - semanage_user_get_mlsrange; - semanage_user_get_name; - semanage_user_get_num_roles; - semanage_user_get_prefix; - semanage_user_get_roles; - semanage_user_has_role; - semanage_user_iterate; - semanage_user_iterate_local; - semanage_user_key_create; - semanage_user_key_extract; - semanage_user_key_free; - semanage_user_list; - semanage_user_list_local; - semanage_user_modify_local; - semanage_user_query; - semanage_user_query_local; - semanage_user_set_mlslevel; - semanage_user_set_mlsrange; - semanage_user_set_name; - semanage_user_set_prefix; - semanage_user_set_roles; + global: semanage_handle_create; semanage_handle_destroy; + semanage_is_managed; semanage_connect; semanage_disconnect; + semanage_msg_*; + semanage_begin_transaction; semanage_commit; + semanage_module_install; semanage_module_install_file; + semanage_module_upgrade; semanage_module_upgrade_file; + semanage_module_install_base; semanage_module_install_base_file; + semanage_module_enable; + semanage_module_disable; + semanage_module_remove; + semanage_module_list; semanage_module_info_datum_destroy; + semanage_module_list_nth; semanage_module_get_name; + semanage_module_get_version; semanage_select_store; + semanage_module_get_enabled; + semanage_reload_policy; semanage_set_reload; semanage_set_rebuild; + semanage_set_root; + semanage_root; + semanage_user_*; semanage_bool_*; semanage_seuser_*; + semanage_iface_*; semanage_port_*; semanage_context_*; + semanage_ibpkey_*; + semanage_ibendport_*; + semanage_node_*; + semanage_fcontext_*; semanage_access_check; semanage_set_create_store; + semanage_is_connected; semanage_get_disable_dontaudit; semanage_set_disable_dontaudit; + semanage_mls_enabled; + semanage_set_check_contexts; + semanage_get_preserve_tunables; semanage_set_preserve_tunables; local: *; }; LIBSEMANAGE_1.1 { global: - semanage_module_install; - semanage_module_extract; - semanage_get_hll_compiler_path; - semanage_get_ignore_module_cache; - semanage_set_ignore_module_cache; - semanage_get_default_priority; - semanage_set_default_priority; - semanage_module_info_create; - semanage_module_info_destroy; - semanage_module_info_get_priority; - semanage_module_info_get_name; - semanage_module_info_get_lang_ext; - semanage_module_info_get_enabled; - semanage_module_info_set_priority; - semanage_module_info_set_name; - semanage_module_info_set_lang_ext; - semanage_module_info_set_enabled; - semanage_module_key_create; - semanage_module_key_destroy; - semanage_module_key_get_priority; - semanage_module_key_get_name; - semanage_module_key_set_priority; - semanage_module_key_set_name; - semanage_module_get_module_info; - semanage_module_list_all; - semanage_module_get_enabled; - semanage_module_set_enabled; - semanage_module_install_info; - semanage_module_remove_key; - semanage_set_store_root; + semanage_module_install; + semanage_module_extract; + semanage_get_hll_compiler_path; + semanage_get_ignore_module_cache; + semanage_set_ignore_module_cache; + semanage_get_default_priority; + semanage_set_default_priority; + semanage_module_info_create; + semanage_module_info_destroy; + semanage_module_info_get_priority; + semanage_module_info_get_name; + semanage_module_info_get_lang_ext; + semanage_module_info_get_enabled; + semanage_module_info_set_priority; + semanage_module_info_set_name; + semanage_module_info_set_lang_ext; + semanage_module_info_set_enabled; + semanage_module_key_create; + semanage_module_key_destroy; + semanage_module_key_get_priority; + semanage_module_key_get_name; + semanage_module_key_set_priority; + semanage_module_key_set_name; + semanage_module_get_module_info; + semanage_module_list_all; + semanage_module_get_enabled; + semanage_module_set_enabled; + semanage_module_install_info; + semanage_module_upgrade_info; + semanage_module_remove_key; + semanage_set_store_root; } LIBSEMANAGE_1.0; diff --git a/libsemanage/src/module_internal.h b/libsemanage/src/module_internal.h new file mode 100644 index 00000000..c99f6c28 --- /dev/null +++ b/libsemanage/src/module_internal.h @@ -0,0 +1,27 @@ +#ifndef _SEMANAGE_MODULE_INTERNAL_H_ +#define _SEMANAGE_MODULE_INTERNAL_H_ + +#include +#include "dso.h" + +hidden_proto(semanage_module_get_name) + hidden_proto(semanage_module_info_datum_destroy) + hidden_proto(semanage_module_list_nth) + hidden_proto(semanage_module_info_create) + hidden_proto(semanage_module_info_destroy) + hidden_proto(semanage_module_info_get_priority) + hidden_proto(semanage_module_info_get_name) + hidden_proto(semanage_module_info_get_lang_ext) + hidden_proto(semanage_module_info_get_enabled) + hidden_proto(semanage_module_info_set_priority) + hidden_proto(semanage_module_info_set_name) + hidden_proto(semanage_module_info_set_lang_ext) + hidden_proto(semanage_module_info_set_enabled) + hidden_proto(semanage_module_key_create) + hidden_proto(semanage_module_key_destroy) + hidden_proto(semanage_module_key_get_priority) + hidden_proto(semanage_module_key_get_name) + hidden_proto(semanage_module_key_set_priority) + hidden_proto(semanage_module_key_set_name) + hidden_proto(semanage_module_set_enabled) +#endif diff --git a/libsemanage/src/modules.c b/libsemanage/src/modules.c index b6dd456c..19043505 100644 --- a/libsemanage/src/modules.c +++ b/libsemanage/src/modules.c @@ -22,7 +22,6 @@ /* This file implements only the publicly-visible module functions to libsemanage. */ #include "direct_api.h" -#include "modules.h" #include "semanage_conf.h" #include "semanage_store.h" @@ -42,7 +41,70 @@ #include "modules.h" #include "debug.h" -int semanage_module_install(semanage_handle_t * sh, +asm(".symver semanage_module_get_enabled_1_1,semanage_module_get_enabled@@LIBSEMANAGE_1.1"); +asm(".symver semanage_module_get_enabled_1_0,semanage_module_get_enabled@LIBSEMANAGE_1.0"); +asm(".symver semanage_module_install_pp,semanage_module_install@LIBSEMANAGE_1.0"); +asm(".symver semanage_module_install_hll,semanage_module_install@@LIBSEMANAGE_1.1"); + +/* Takes a module stored in 'module_data' and parses its headers. + * Sets reference variables 'module_name' to module's name and + * 'version' to module's version. The caller is responsible for + * free()ing 'module_name' and 'version'; they will be + * set to NULL upon entering this function. Returns 0 on success, -1 + * if out of memory, or -2 if data did not represent a module. + */ +static int parse_module_headers(semanage_handle_t * sh, char *module_data, + size_t data_len, char **module_name, char **version) +{ + struct sepol_policy_file *pf; + int file_type; + *version = NULL; + + if (sepol_policy_file_create(&pf)) { + ERR(sh, "Out of memory!"); + return -1; + } + sepol_policy_file_set_mem(pf, module_data, data_len); + sepol_policy_file_set_handle(pf, sh->sepolh); + if (module_data == NULL || + data_len == 0 || + sepol_module_package_info(pf, &file_type, module_name, version) == -1) { + sepol_policy_file_free(pf); + ERR(sh, "Could not parse module data."); + return -2; + } + sepol_policy_file_free(pf); + if (file_type != SEPOL_POLICY_MOD) { + ERR(sh, "Data did not represent a pp module. Please upgrade to the latest version of libsemanage to support hll modules."); + return -2; + } + + return 0; +} + +/* This function is used to preserve ABI compatibility with + * versions of semodule using LIBSEMANAGE_1.0 + */ +int semanage_module_install_pp(semanage_handle_t * sh, + char *module_data, size_t data_len) +{ + char *name = NULL; + char *version = NULL; + int status; + + if ((status = parse_module_headers(sh, module_data, data_len, &name, &version)) != 0) { + goto cleanup; + } + + status = semanage_module_install_hll(sh, module_data, data_len, name, "pp"); + +cleanup: + free(name); + free(version); + return status; +} + +int semanage_module_install_hll(semanage_handle_t * sh, char *module_data, size_t data_len, const char *name, const char *ext_lang) { if (sh->funcs->install == NULL) { @@ -97,6 +159,16 @@ int semanage_module_extract(semanage_handle_t * sh, return sh->funcs->extract(sh, modkey, extract_cil, mapped_data, data_len, modinfo); } +/* Legacy function that remains to preserve ABI + * compatibility. Please use semanage_module_install instead. + */ +int semanage_module_upgrade(semanage_handle_t * sh, + char *module_data, size_t data_len) +{ + return semanage_module_install_pp(sh, module_data, data_len); + +} + /* Legacy function that remains to preserve ABI * compatibility. Please use semanage_module_install_file instead. */ @@ -106,6 +178,24 @@ int semanage_module_upgrade_file(semanage_handle_t * sh, return semanage_module_install_file(sh, module_name); } +/* Legacy function that remains to preserve ABI + * compatibility. Please use semanage_module_install instead. + */ +int semanage_module_install_base(semanage_handle_t * sh, + char *module_data, size_t data_len) +{ + return semanage_module_install_pp(sh, module_data, data_len); +} + +/* Legacy function that remains to preserve ABI + * compatibility. Please use semanage_module_install_file instead. + */ +int semanage_module_install_base_file(semanage_handle_t * sh, + const char *module_name) +{ + return semanage_module_install_file(sh, module_name); +} + int semanage_module_remove(semanage_handle_t * sh, char *module_name) { if (sh->funcs->remove == NULL) { @@ -151,6 +241,7 @@ void semanage_module_info_datum_destroy(semanage_module_info_t * modinfo) } } +hidden_def(semanage_module_info_datum_destroy) semanage_module_info_t *semanage_module_list_nth(semanage_module_info_t * list, int n) @@ -158,12 +249,14 @@ semanage_module_info_t *semanage_module_list_nth(semanage_module_info_t * list, return list + n; } +hidden_def(semanage_module_list_nth) const char *semanage_module_get_name(semanage_module_info_t * modinfo) { return modinfo->name; } +hidden_def(semanage_module_get_name) /* Legacy function that remains to preserve ABI * compatibility. @@ -186,6 +279,7 @@ int semanage_module_info_create(semanage_handle_t *sh, return semanage_module_info_init(sh, *modinfo); } +hidden_def(semanage_module_info_create) int semanage_module_info_destroy(semanage_handle_t *sh, semanage_module_info_t *modinfo) @@ -202,6 +296,7 @@ int semanage_module_info_destroy(semanage_handle_t *sh, return semanage_module_info_init(sh, modinfo); } +hidden_def(semanage_module_info_destroy) int semanage_module_info_init(semanage_handle_t *sh, semanage_module_info_t *modinfo) @@ -276,6 +371,7 @@ int semanage_module_info_get_priority(semanage_handle_t *sh, return 0; } +hidden_def(semanage_module_info_get_priority) int semanage_module_info_get_name(semanage_handle_t *sh, semanage_module_info_t *modinfo, @@ -290,6 +386,7 @@ int semanage_module_info_get_name(semanage_handle_t *sh, return 0; } +hidden_def(semanage_module_info_get_name) int semanage_module_info_get_lang_ext(semanage_handle_t *sh, semanage_module_info_t *modinfo, @@ -304,6 +401,7 @@ int semanage_module_info_get_lang_ext(semanage_handle_t *sh, return 0; } +hidden_def(semanage_module_info_get_lang_ext) int semanage_module_info_get_enabled(semanage_handle_t *sh, semanage_module_info_t *modinfo, @@ -318,6 +416,7 @@ int semanage_module_info_get_enabled(semanage_handle_t *sh, return 0; } +hidden_def(semanage_module_info_get_enabled) int semanage_module_info_set_priority(semanage_handle_t *sh, semanage_module_info_t *modinfo, @@ -338,6 +437,7 @@ int semanage_module_info_set_priority(semanage_handle_t *sh, return 0; } +hidden_def(semanage_module_info_set_priority) int semanage_module_info_set_name(semanage_handle_t *sh, semanage_module_info_t *modinfo, @@ -368,6 +468,7 @@ int semanage_module_info_set_name(semanage_handle_t *sh, return 0; } +hidden_def(semanage_module_info_set_name) int semanage_module_info_set_lang_ext(semanage_handle_t *sh, semanage_module_info_t *modinfo, @@ -398,6 +499,7 @@ int semanage_module_info_set_lang_ext(semanage_handle_t *sh, return 0; } +hidden_def(semanage_module_info_set_lang_ext) int semanage_module_info_set_enabled(semanage_handle_t *sh, semanage_module_info_t *modinfo, @@ -418,6 +520,7 @@ int semanage_module_info_set_enabled(semanage_handle_t *sh, return 0; } +hidden_def(semanage_module_info_set_enabled) int semanage_module_get_path(semanage_handle_t *sh, const semanage_module_info_t *modinfo, @@ -582,6 +685,7 @@ int semanage_module_key_create(semanage_handle_t *sh, return semanage_module_key_init(sh, *modkey); } +hidden_def(semanage_module_key_create) int semanage_module_key_destroy(semanage_handle_t *sh, semanage_module_key_t *modkey) @@ -597,6 +701,7 @@ int semanage_module_key_destroy(semanage_handle_t *sh, return semanage_module_key_init(sh, modkey); } +hidden_def(semanage_module_key_destroy) int semanage_module_key_init(semanage_handle_t *sh, semanage_module_key_t *modkey) @@ -623,6 +728,7 @@ int semanage_module_key_get_name(semanage_handle_t *sh, return 0; } +hidden_def(semanage_module_key_get_name) int semanage_module_key_get_priority(semanage_handle_t *sh, semanage_module_key_t *modkey, @@ -637,6 +743,7 @@ int semanage_module_key_get_priority(semanage_handle_t *sh, return 0; } +hidden_def(semanage_module_key_get_priority) int semanage_module_key_set_name(semanage_handle_t *sh, semanage_module_key_t *modkey, @@ -669,6 +776,7 @@ cleanup: return status; } +hidden_def(semanage_module_key_set_name) int semanage_module_key_set_priority(semanage_handle_t *sh, semanage_module_key_t *modkey, @@ -688,8 +796,9 @@ int semanage_module_key_set_priority(semanage_handle_t *sh, return 0; } +hidden_def(semanage_module_key_set_priority) -int semanage_module_get_enabled(semanage_handle_t *sh, +int semanage_module_get_enabled_1_1(semanage_handle_t *sh, const semanage_module_key_t *modkey, int *enabled) { @@ -709,6 +818,11 @@ int semanage_module_get_enabled(semanage_handle_t *sh, return sh->funcs->get_enabled(sh, modkey, enabled); } +int semanage_module_get_enabled_1_0(semanage_module_info_t *modinfo) +{ + return modinfo->enabled; +} + int semanage_module_set_enabled(semanage_handle_t *sh, const semanage_module_key_t *modkey, int enabled) @@ -733,6 +847,63 @@ int semanage_module_set_enabled(semanage_handle_t *sh, return sh->funcs->set_enabled(sh, modkey, enabled); } +hidden_def(semanage_module_set_enabled) + +/* This function exists only for ABI compatibility. It has been deprecated and + * should not be used. Instead, use semanage_module_set_enabled() */ +int semanage_module_enable(semanage_handle_t *sh, char *module_name) +{ + int rc = -1; + semanage_module_key_t *modkey = NULL; + + rc = semanage_module_key_create(sh, &modkey); + if (rc != 0) + goto exit; + + rc = semanage_module_key_set_name(sh, modkey, module_name); + if (rc != 0) + goto exit; + + rc = semanage_module_set_enabled(sh, modkey, 1); + if (rc != 0) + goto exit; + + rc = 0; + +exit: + semanage_module_key_destroy(sh, modkey); + free(modkey); + + return rc; +} + +/* This function exists only for ABI compatibility. It has been deprecated and + * should not be used. Instead, use semanage_module_set_enabled() */ +int semanage_module_disable(semanage_handle_t *sh, char *module_name) +{ + int rc = -1; + semanage_module_key_t *modkey = NULL; + + rc = semanage_module_key_create(sh, &modkey); + if (rc != 0) + goto exit; + + rc = semanage_module_key_set_name(sh, modkey, module_name); + if (rc != 0) + goto exit; + + rc = semanage_module_set_enabled(sh, modkey, 0); + if (rc != 0) + goto exit; + + rc = 0; + +exit: + semanage_module_key_destroy(sh, modkey); + free(modkey); + + return rc; +} /* Converts a string to a priority * diff --git a/libsemanage/src/modules.h b/libsemanage/src/modules.h index 64d4a157..8a5c01f4 100644 --- a/libsemanage/src/modules.h +++ b/libsemanage/src/modules.h @@ -24,11 +24,18 @@ #include -#include "semanage/modules.h" - +#include "module_internal.h" +int semanage_module_install_pp(semanage_handle_t * sh, + char *module_data, size_t data_len); +int semanage_module_install_hll(semanage_handle_t * sh, + char *module_data, size_t data_len, const char *name, const char *ext_lang); +int semanage_module_upgrade(semanage_handle_t * sh, + char *module_data, size_t data_len); int semanage_module_upgrade_file(semanage_handle_t * sh, const char *module_name); +int semanage_module_install_base(semanage_handle_t * sh, + char *module_data, size_t data_len); int semanage_module_install_base_file(semanage_handle_t * sh, const char *module_name); diff --git a/libsemanage/src/node_internal.h b/libsemanage/src/node_internal.h index 234143b4..58175603 100644 --- a/libsemanage/src/node_internal.h +++ b/libsemanage/src/node_internal.h @@ -6,6 +6,29 @@ #include #include "database.h" #include "handle.h" +#include "dso.h" + +hidden_proto(semanage_node_create) + hidden_proto(semanage_node_compare) + hidden_proto(semanage_node_compare2) + hidden_proto(semanage_node_clone) + hidden_proto(semanage_node_free) + hidden_proto(semanage_node_key_extract) + hidden_proto(semanage_node_key_free) + hidden_proto(semanage_node_get_addr) + hidden_proto(semanage_node_get_addr_bytes) + hidden_proto(semanage_node_get_mask) + hidden_proto(semanage_node_get_mask_bytes) + hidden_proto(semanage_node_get_proto) + hidden_proto(semanage_node_set_addr) + hidden_proto(semanage_node_set_addr_bytes) + hidden_proto(semanage_node_set_mask) + hidden_proto(semanage_node_set_mask_bytes) + hidden_proto(semanage_node_set_proto) + hidden_proto(semanage_node_get_proto_str) + hidden_proto(semanage_node_get_con) + hidden_proto(semanage_node_set_con) + hidden_proto(semanage_node_list_local) /* NODE RECORD: method table */ extern record_table_t SEMANAGE_NODE_RTABLE; @@ -22,11 +45,11 @@ extern int node_policydb_dbase_init(semanage_handle_t * handle, extern void node_policydb_dbase_release(dbase_config_t * dconfig); -extern int semanage_node_validate_local(semanage_handle_t * handle); +extern int hidden semanage_node_validate_local(semanage_handle_t * handle); /* ==== Internal (to nodes) API === */ - int semanage_node_compare2_qsort(const semanage_node_t ** node, +hidden int semanage_node_compare2_qsort(const semanage_node_t ** node, const semanage_node_t ** node2); #endif diff --git a/libsemanage/src/node_record.c b/libsemanage/src/node_record.c index e1c6e03a..5368ceee 100644 --- a/libsemanage/src/node_record.c +++ b/libsemanage/src/node_record.c @@ -32,6 +32,7 @@ int semanage_node_compare(const semanage_node_t * node, return sepol_node_compare(node, key); } +hidden_def(semanage_node_compare) int semanage_node_compare2(const semanage_node_t * node, const semanage_node_t * node2) @@ -40,8 +41,9 @@ int semanage_node_compare2(const semanage_node_t * node, return sepol_node_compare2(node, node2); } +hidden_def(semanage_node_compare2) - int semanage_node_compare2_qsort(const semanage_node_t ** node, +hidden int semanage_node_compare2_qsort(const semanage_node_t ** node, const semanage_node_t ** node2) { @@ -66,6 +68,7 @@ int semanage_node_key_extract(semanage_handle_t * handle, return sepol_node_key_extract(handle->sepolh, node, key_ptr); } +hidden_def(semanage_node_key_extract) void semanage_node_key_free(semanage_node_key_t * key) { @@ -73,6 +76,7 @@ void semanage_node_key_free(semanage_node_key_t * key) sepol_node_key_free(key); } +hidden_def(semanage_node_key_free) /* Address */ int semanage_node_get_addr(semanage_handle_t * handle, @@ -82,6 +86,7 @@ int semanage_node_get_addr(semanage_handle_t * handle, return sepol_node_get_addr(handle->sepolh, node, addr_ptr); } +hidden_def(semanage_node_get_addr) int semanage_node_get_addr_bytes(semanage_handle_t * handle, const semanage_node_t * node, @@ -91,6 +96,7 @@ int semanage_node_get_addr_bytes(semanage_handle_t * handle, return sepol_node_get_addr_bytes(handle->sepolh, node, addr, addr_sz); } +hidden_def(semanage_node_get_addr_bytes) int semanage_node_set_addr(semanage_handle_t * handle, semanage_node_t * node, int proto, const char *addr) @@ -99,6 +105,7 @@ int semanage_node_set_addr(semanage_handle_t * handle, return sepol_node_set_addr(handle->sepolh, node, proto, addr); } +hidden_def(semanage_node_set_addr) int semanage_node_set_addr_bytes(semanage_handle_t * handle, semanage_node_t * node, @@ -108,6 +115,7 @@ int semanage_node_set_addr_bytes(semanage_handle_t * handle, return sepol_node_set_addr_bytes(handle->sepolh, node, addr, addr_sz); } +hidden_def(semanage_node_set_addr_bytes) /* Netmask */ int semanage_node_get_mask(semanage_handle_t * handle, @@ -117,6 +125,7 @@ int semanage_node_get_mask(semanage_handle_t * handle, return sepol_node_get_mask(handle->sepolh, node, mask_ptr); } +hidden_def(semanage_node_get_mask) int semanage_node_get_mask_bytes(semanage_handle_t * handle, const semanage_node_t * node, @@ -126,6 +135,7 @@ int semanage_node_get_mask_bytes(semanage_handle_t * handle, return sepol_node_get_mask_bytes(handle->sepolh, node, mask, mask_sz); } +hidden_def(semanage_node_get_mask_bytes) int semanage_node_set_mask(semanage_handle_t * handle, semanage_node_t * node, int proto, const char *mask) @@ -134,6 +144,7 @@ int semanage_node_set_mask(semanage_handle_t * handle, return sepol_node_set_mask(handle->sepolh, node, proto, mask); } +hidden_def(semanage_node_set_mask) int semanage_node_set_mask_bytes(semanage_handle_t * handle, semanage_node_t * node, @@ -143,6 +154,7 @@ int semanage_node_set_mask_bytes(semanage_handle_t * handle, return sepol_node_set_mask_bytes(handle->sepolh, node, mask, mask_sz); } +hidden_def(semanage_node_set_mask_bytes) /* Protocol */ int semanage_node_get_proto(const semanage_node_t * node) @@ -151,6 +163,7 @@ int semanage_node_get_proto(const semanage_node_t * node) return sepol_node_get_proto(node); } +hidden_def(semanage_node_get_proto) void semanage_node_set_proto(semanage_node_t * node, int proto) { @@ -158,6 +171,7 @@ void semanage_node_set_proto(semanage_node_t * node, int proto) sepol_node_set_proto(node, proto); } +hidden_def(semanage_node_set_proto) const char *semanage_node_get_proto_str(int proto) { @@ -165,6 +179,7 @@ const char *semanage_node_get_proto_str(int proto) return sepol_node_get_proto_str(proto); } +hidden_def(semanage_node_get_proto_str) /* Context */ semanage_context_t *semanage_node_get_con(const semanage_node_t * node) @@ -173,6 +188,7 @@ semanage_context_t *semanage_node_get_con(const semanage_node_t * node) return sepol_node_get_con(node); } +hidden_def(semanage_node_get_con) int semanage_node_set_con(semanage_handle_t * handle, semanage_node_t * node, semanage_context_t * con) @@ -181,6 +197,7 @@ int semanage_node_set_con(semanage_handle_t * handle, return sepol_node_set_con(handle->sepolh, node, con); } +hidden_def(semanage_node_set_con) /* Create/Clone/Destroy */ int semanage_node_create(semanage_handle_t * handle, @@ -190,6 +207,7 @@ int semanage_node_create(semanage_handle_t * handle, return sepol_node_create(handle->sepolh, node_ptr); } +hidden_def(semanage_node_create) int semanage_node_clone(semanage_handle_t * handle, const semanage_node_t * node, @@ -199,6 +217,7 @@ int semanage_node_clone(semanage_handle_t * handle, return sepol_node_clone(handle->sepolh, node, node_ptr); } +hidden_def(semanage_node_clone) void semanage_node_free(semanage_node_t * node) { @@ -206,6 +225,7 @@ void semanage_node_free(semanage_node_t * node) sepol_node_free(node); } +hidden_def(semanage_node_free) /* Port base functions */ record_table_t SEMANAGE_NODE_RTABLE = { diff --git a/libsemanage/src/nodes_file.c b/libsemanage/src/nodes_file.c index c3647f2a..f6c8895d 100644 --- a/libsemanage/src/nodes_file.c +++ b/libsemanage/src/nodes_file.c @@ -15,6 +15,7 @@ typedef struct dbase_file dbase_t; #include #include #include "node_internal.h" +#include "context_internal.h" #include "database_file.h" #include "parse_utils.h" #include "debug.h" diff --git a/libsemanage/src/nodes_local.c b/libsemanage/src/nodes_local.c index c85fe4e7..93af4501 100644 --- a/libsemanage/src/nodes_local.c +++ b/libsemanage/src/nodes_local.c @@ -69,3 +69,4 @@ int semanage_node_list_local(semanage_handle_t * handle, return dbase_list(handle, dconfig, records, count); } +hidden_def(semanage_node_list_local) diff --git a/libsemanage/src/port_internal.h b/libsemanage/src/port_internal.h index 67017472..ebd2bc84 100644 --- a/libsemanage/src/port_internal.h +++ b/libsemanage/src/port_internal.h @@ -6,6 +6,25 @@ #include #include "database.h" #include "handle.h" +#include "dso.h" + +hidden_proto(semanage_port_create) + hidden_proto(semanage_port_compare) + hidden_proto(semanage_port_compare2) + hidden_proto(semanage_port_clone) + hidden_proto(semanage_port_free) + hidden_proto(semanage_port_key_extract) + hidden_proto(semanage_port_key_free) + hidden_proto(semanage_port_get_high) + hidden_proto(semanage_port_get_low) + hidden_proto(semanage_port_set_port) + hidden_proto(semanage_port_set_range) + hidden_proto(semanage_port_get_proto) + hidden_proto(semanage_port_set_proto) + hidden_proto(semanage_port_get_proto_str) + hidden_proto(semanage_port_get_con) + hidden_proto(semanage_port_set_con) + hidden_proto(semanage_port_list_local) /* PORT RECORD: method table */ extern record_table_t SEMANAGE_PORT_RTABLE; @@ -22,11 +41,11 @@ extern int port_policydb_dbase_init(semanage_handle_t * handle, extern void port_policydb_dbase_release(dbase_config_t * dconfig); -extern int semanage_port_validate_local(semanage_handle_t * handle); +extern int hidden semanage_port_validate_local(semanage_handle_t * handle); /* ==== Internal (to ports) API === */ - int semanage_port_compare2_qsort(const semanage_port_t ** port, +hidden int semanage_port_compare2_qsort(const semanage_port_t ** port, const semanage_port_t ** port2); #endif diff --git a/libsemanage/src/port_record.c b/libsemanage/src/port_record.c index f8a1633e..b878ca78 100644 --- a/libsemanage/src/port_record.c +++ b/libsemanage/src/port_record.c @@ -31,6 +31,7 @@ int semanage_port_compare(const semanage_port_t * port, return sepol_port_compare(port, key); } +hidden_def(semanage_port_compare) int semanage_port_compare2(const semanage_port_t * port, const semanage_port_t * port2) @@ -39,8 +40,9 @@ int semanage_port_compare2(const semanage_port_t * port, return sepol_port_compare2(port, port2); } +hidden_def(semanage_port_compare2) - int semanage_port_compare2_qsort(const semanage_port_t ** port, +hidden int semanage_port_compare2_qsort(const semanage_port_t ** port, const semanage_port_t ** port2) { @@ -63,6 +65,7 @@ int semanage_port_key_extract(semanage_handle_t * handle, return sepol_port_key_extract(handle->sepolh, port, key_ptr); } +hidden_def(semanage_port_key_extract) void semanage_port_key_free(semanage_port_key_t * key) { @@ -70,6 +73,7 @@ void semanage_port_key_free(semanage_port_key_t * key) sepol_port_key_free(key); } +hidden_def(semanage_port_key_free) /* Protocol */ int semanage_port_get_proto(const semanage_port_t * port) @@ -78,6 +82,7 @@ int semanage_port_get_proto(const semanage_port_t * port) return sepol_port_get_proto(port); } +hidden_def(semanage_port_get_proto) void semanage_port_set_proto(semanage_port_t * port, int proto) { @@ -85,6 +90,7 @@ void semanage_port_set_proto(semanage_port_t * port, int proto) sepol_port_set_proto(port, proto); } +hidden_def(semanage_port_set_proto) const char *semanage_port_get_proto_str(int proto) { @@ -92,6 +98,7 @@ const char *semanage_port_get_proto_str(int proto) return sepol_port_get_proto_str(proto); } +hidden_def(semanage_port_get_proto_str) /* Port */ int semanage_port_get_low(const semanage_port_t * port) @@ -100,6 +107,7 @@ int semanage_port_get_low(const semanage_port_t * port) return sepol_port_get_low(port); } +hidden_def(semanage_port_get_low) int semanage_port_get_high(const semanage_port_t * port) { @@ -107,6 +115,7 @@ int semanage_port_get_high(const semanage_port_t * port) return sepol_port_get_high(port); } +hidden_def(semanage_port_get_high) void semanage_port_set_port(semanage_port_t * port, int port_num) { @@ -114,6 +123,7 @@ void semanage_port_set_port(semanage_port_t * port, int port_num) sepol_port_set_port(port, port_num); } +hidden_def(semanage_port_set_port) void semanage_port_set_range(semanage_port_t * port, int low, int high) { @@ -121,6 +131,7 @@ void semanage_port_set_range(semanage_port_t * port, int low, int high) sepol_port_set_range(port, low, high); } +hidden_def(semanage_port_set_range) /* Context */ semanage_context_t *semanage_port_get_con(const semanage_port_t * port) @@ -129,6 +140,7 @@ semanage_context_t *semanage_port_get_con(const semanage_port_t * port) return sepol_port_get_con(port); } +hidden_def(semanage_port_get_con) int semanage_port_set_con(semanage_handle_t * handle, semanage_port_t * port, semanage_context_t * con) @@ -137,6 +149,7 @@ int semanage_port_set_con(semanage_handle_t * handle, return sepol_port_set_con(handle->sepolh, port, con); } +hidden_def(semanage_port_set_con) /* Create/Clone/Destroy */ int semanage_port_create(semanage_handle_t * handle, @@ -146,6 +159,7 @@ int semanage_port_create(semanage_handle_t * handle, return sepol_port_create(handle->sepolh, port_ptr); } +hidden_def(semanage_port_create) int semanage_port_clone(semanage_handle_t * handle, const semanage_port_t * port, @@ -155,6 +169,7 @@ int semanage_port_clone(semanage_handle_t * handle, return sepol_port_clone(handle->sepolh, port, port_ptr); } +hidden_def(semanage_port_clone) void semanage_port_free(semanage_port_t * port) { @@ -162,6 +177,7 @@ void semanage_port_free(semanage_port_t * port) sepol_port_free(port); } +hidden_def(semanage_port_free) /* Port base functions */ record_table_t SEMANAGE_PORT_RTABLE = { diff --git a/libsemanage/src/ports_file.c b/libsemanage/src/ports_file.c index ade4102f..4738d467 100644 --- a/libsemanage/src/ports_file.c +++ b/libsemanage/src/ports_file.c @@ -15,6 +15,7 @@ typedef struct dbase_file dbase_t; #include #include #include "port_internal.h" +#include "context_internal.h" #include "database_file.h" #include "parse_utils.h" #include "debug.h" diff --git a/libsemanage/src/ports_local.c b/libsemanage/src/ports_local.c index e7e9bdbf..ffd5a838 100644 --- a/libsemanage/src/ports_local.c +++ b/libsemanage/src/ports_local.c @@ -71,8 +71,9 @@ int semanage_port_list_local(semanage_handle_t * handle, return dbase_list(handle, dconfig, records, count); } +hidden_def(semanage_port_list_local) -int semanage_port_validate_local(semanage_handle_t * handle) +int hidden semanage_port_validate_local(semanage_handle_t * handle) { semanage_port_t **ports = NULL; diff --git a/libsemanage/src/semanage_store.c b/libsemanage/src/semanage_store.c index c6a736fe..58dded6e 100644 --- a/libsemanage/src/semanage_store.c +++ b/libsemanage/src/semanage_store.c @@ -707,8 +707,7 @@ static int semanage_filename_select(const struct dirent *d) /* Copies a file from src to dst. If dst already exists then * overwrite it. Returns 0 on success, -1 on error. */ -int semanage_copy_file(const char *src, const char *dst, mode_t mode, - bool syncrequired) +int semanage_copy_file(const char *src, const char *dst, mode_t mode) { int in, out, retval = 0, amount_read, n, errsv = errno; char tmp[PATH_MAX]; @@ -736,11 +735,8 @@ int semanage_copy_file(const char *src, const char *dst, mode_t mode, } umask(mask); while (retval == 0 && (amount_read = read(in, buf, sizeof(buf))) > 0) { - if (write(out, buf, amount_read) != amount_read) { - if (errno) - errsv = errno; - else - errsv = EIO; + if (write(out, buf, amount_read) < 0) { + errsv = errno; retval = -1; } } @@ -749,10 +745,6 @@ int semanage_copy_file(const char *src, const char *dst, mode_t mode, retval = -1; } close(in); - if (syncrequired && fsync(out) < 0) { - errsv = errno; - retval = -1; - } if (close(out) < 0) { errsv = errno; retval = -1; @@ -819,8 +811,7 @@ static int semanage_copy_dir_flags(const char *src, const char *dst, int flag) umask(mask); } else if (S_ISREG(sb.st_mode) && flag == 1) { mask = umask(0077); - if (semanage_copy_file(path, path2, sb.st_mode, - false) < 0) { + if (semanage_copy_file(path, path2, sb.st_mode) < 0) { umask(mask); goto cleanup; } @@ -1485,6 +1476,7 @@ int semanage_reload_policy(semanage_handle_t * sh) return r; } +hidden_def(semanage_reload_policy) /* This expands the file_context.tmpl file to file_context and homedirs.template */ int semanage_split_fc(semanage_handle_t * sh) @@ -1648,8 +1640,7 @@ static int semanage_install_final_tmp(semanage_handle_t * sh) goto cleanup; } - ret = semanage_copy_file(src, dst, sh->conf->file_mode, - true); + ret = semanage_copy_file(src, dst, sh->conf->file_mode); if (ret < 0) { ERR(sh, "Could not copy %s to %s.", src, dst); goto cleanup; @@ -1736,19 +1727,6 @@ static int semanage_commit_sandbox(semanage_handle_t * sh) } close(fd); - /* sync changes in sandbox to filesystem */ - fd = open(sandbox, O_DIRECTORY); - if (fd == -1) { - ERR(sh, "Error while opening %s for syncfs(): %d", sandbox, errno); - return -1; - } - if (syncfs(fd) == -1) { - ERR(sh, "Error while syncing %s to filesystem: %d", sandbox, errno); - close(fd); - return -1; - } - close(fd); - retval = commit_number; if (semanage_get_active_lock(sh) < 0) { diff --git a/libsemanage/src/semanage_store.h b/libsemanage/src/semanage_store.h index b9ec5664..34bf8523 100644 --- a/libsemanage/src/semanage_store.h +++ b/libsemanage/src/semanage_store.h @@ -24,7 +24,6 @@ #ifndef SEMANAGE_MODULE_STORE_H #define SEMANAGE_MODULE_STORE_H -#include #include #include #include @@ -163,7 +162,6 @@ int semanage_nc_sort(semanage_handle_t * sh, size_t buf_len, char **sorted_buf, size_t * sorted_buf_len); -int semanage_copy_file(const char *src, const char *dst, mode_t mode, - bool syncrequired); +int semanage_copy_file(const char *src, const char *dst, mode_t mode); #endif diff --git a/libsemanage/src/semanageswig_python.i b/libsemanage/src/semanageswig_python.i index 5f011396..8dd79fc2 100644 --- a/libsemanage/src/semanageswig_python.i +++ b/libsemanage/src/semanageswig_python.i @@ -30,6 +30,8 @@ %} %include "stdint.i" +%ignore semanage_module_install_pp; +%ignore semanage_module_install_hll; %wrapper %{ diff --git a/libsemanage/src/semanageswig_python_exception.i b/libsemanage/src/semanageswig_python_exception.i index 372ec948..06c60267 100644 --- a/libsemanage/src/semanageswig_python_exception.i +++ b/libsemanage/src/semanageswig_python_exception.i @@ -7,6 +7,7 @@ } } + %exception semanage_get_hll_compiler_path { $action if (result < 0) { @@ -15,6 +16,7 @@ } } + %exception semanage_get_disable_dontaudit { $action if (result < 0) { @@ -23,6 +25,7 @@ } } + %exception semanage_set_default_priority { $action if (result < 0) { @@ -31,6 +34,7 @@ } } + %exception semanage_is_managed { $action if (result < 0) { @@ -39,6 +43,7 @@ } } + %exception semanage_connect { $action if (result < 0) { @@ -47,6 +52,7 @@ } } + %exception semanage_disconnect { $action if (result < 0) { @@ -55,6 +61,7 @@ } } + %exception semanage_begin_transaction { $action if (result < 0) { @@ -63,6 +70,7 @@ } } + %exception semanage_commit { $action if (result < 0) { @@ -71,6 +79,7 @@ } } + %exception semanage_access_check { $action if (result < 0) { @@ -79,6 +88,7 @@ } } + %exception semanage_is_connected { $action if (result < 0) { @@ -87,6 +97,7 @@ } } + %exception semanage_mls_enabled { $action if (result < 0) { @@ -95,6 +106,7 @@ } } + %exception semanage_set_root { $action if (result < 0) { @@ -103,6 +115,7 @@ } } + %exception semanage_get_preserve_tunables { $action if (result < 0) { @@ -111,6 +124,7 @@ } } + %exception semanage_get_ignore_module_cache { $action if (result < 0) { @@ -119,6 +133,7 @@ } } + %exception select { $action if (result < 0) { @@ -127,6 +142,7 @@ } } + %exception pselect { $action if (result < 0) { @@ -135,6 +151,7 @@ } } + %exception semanage_module_install { $action if (result < 0) { @@ -143,6 +160,7 @@ } } + %exception semanage_module_install_file { $action if (result < 0) { @@ -151,6 +169,7 @@ } } + %exception semanage_module_remove { $action if (result < 0) { @@ -159,6 +178,7 @@ } } + %exception semanage_module_extract { $action if (result < 0) { @@ -167,6 +187,7 @@ } } + %exception semanage_module_list { $action if (result < 0) { @@ -175,6 +196,7 @@ } } + %exception semanage_module_info_create { $action if (result < 0) { @@ -183,6 +205,7 @@ } } + %exception semanage_module_info_destroy { $action if (result < 0) { @@ -191,6 +214,7 @@ } } + %exception semanage_module_info_get_priority { $action if (result < 0) { @@ -199,6 +223,7 @@ } } + %exception semanage_module_info_get_name { $action if (result < 0) { @@ -207,6 +232,7 @@ } } + %exception semanage_module_info_get_lang_ext { $action if (result < 0) { @@ -215,6 +241,7 @@ } } + %exception semanage_module_info_get_enabled { $action if (result < 0) { @@ -223,6 +250,7 @@ } } + %exception semanage_module_info_set_priority { $action if (result < 0) { @@ -231,6 +259,7 @@ } } + %exception semanage_module_info_set_name { $action if (result < 0) { @@ -239,6 +268,7 @@ } } + %exception semanage_module_info_set_lang_ext { $action if (result < 0) { @@ -247,6 +277,7 @@ } } + %exception semanage_module_info_set_enabled { $action if (result < 0) { @@ -255,6 +286,7 @@ } } + %exception semanage_module_key_create { $action if (result < 0) { @@ -263,6 +295,7 @@ } } + %exception semanage_module_key_destroy { $action if (result < 0) { @@ -271,6 +304,7 @@ } } + %exception semanage_module_key_get_name { $action if (result < 0) { @@ -279,6 +313,7 @@ } } + %exception semanage_module_key_get_priority { $action if (result < 0) { @@ -287,6 +322,7 @@ } } + %exception semanage_module_key_set_name { $action if (result < 0) { @@ -295,6 +331,7 @@ } } + %exception semanage_module_key_set_priority { $action if (result < 0) { @@ -303,6 +340,7 @@ } } + %exception semanage_module_set_enabled { $action if (result < 0) { @@ -311,6 +349,7 @@ } } + %exception semanage_module_get_module_info { $action if (result < 0) { @@ -319,6 +358,7 @@ } } + %exception semanage_module_list_all { $action if (result < 0) { @@ -327,6 +367,7 @@ } } + %exception semanage_module_install_info { $action if (result < 0) { @@ -335,6 +376,7 @@ } } + %exception semanage_module_remove_key { $action if (result < 0) { @@ -343,6 +385,7 @@ } } + %exception semanage_module_get_enabled { $action if (result < 0) { @@ -351,6 +394,7 @@ } } + %exception semanage_msg_get_level { $action if (result < 0) { @@ -359,6 +403,7 @@ } } + %exception semanage_bool_key_create { $action if (result < 0) { @@ -367,6 +412,7 @@ } } + %exception semanage_bool_key_extract { $action if (result < 0) { @@ -375,6 +421,7 @@ } } + %exception semanage_bool_compare { $action if (result < 0) { @@ -383,6 +430,7 @@ } } + %exception semanage_bool_compare2 { $action if (result < 0) { @@ -391,6 +439,7 @@ } } + %exception semanage_bool_set_name { $action if (result < 0) { @@ -399,6 +448,7 @@ } } + %exception semanage_bool_get_value { $action if (result < 0) { @@ -407,6 +457,7 @@ } } + %exception semanage_bool_create { $action if (result < 0) { @@ -415,6 +466,7 @@ } } + %exception semanage_bool_clone { $action if (result < 0) { @@ -423,6 +475,7 @@ } } + %exception semanage_user_key_create { $action if (result < 0) { @@ -431,6 +484,7 @@ } } + %exception semanage_user_key_extract { $action if (result < 0) { @@ -439,6 +493,7 @@ } } + %exception semanage_user_compare { $action if (result < 0) { @@ -447,6 +502,7 @@ } } + %exception semanage_user_compare2 { $action if (result < 0) { @@ -455,6 +511,7 @@ } } + %exception semanage_user_set_name { $action if (result < 0) { @@ -463,6 +520,7 @@ } } + %exception semanage_user_set_prefix { $action if (result < 0) { @@ -471,6 +529,7 @@ } } + %exception semanage_user_set_mlslevel { $action if (result < 0) { @@ -479,6 +538,7 @@ } } + %exception semanage_user_set_mlsrange { $action if (result < 0) { @@ -487,6 +547,7 @@ } } + %exception semanage_user_get_num_roles { $action if (result < 0) { @@ -495,6 +556,7 @@ } } + %exception semanage_user_add_role { $action if (result < 0) { @@ -503,6 +565,7 @@ } } + %exception semanage_user_has_role { $action if (result < 0) { @@ -511,6 +574,7 @@ } } + %exception semanage_user_get_roles { $action if (result < 0) { @@ -519,6 +583,7 @@ } } + %exception semanage_user_set_roles { $action if (result < 0) { @@ -527,6 +592,7 @@ } } + %exception semanage_user_create { $action if (result < 0) { @@ -535,6 +601,7 @@ } } + %exception semanage_user_clone { $action if (result < 0) { @@ -543,6 +610,7 @@ } } + %exception semanage_seuser_key_create { $action if (result < 0) { @@ -551,6 +619,7 @@ } } + %exception semanage_seuser_key_extract { $action if (result < 0) { @@ -559,6 +628,7 @@ } } + %exception semanage_seuser_compare { $action if (result < 0) { @@ -567,6 +637,7 @@ } } + %exception semanage_seuser_compare2 { $action if (result < 0) { @@ -575,6 +646,7 @@ } } + %exception semanage_seuser_set_name { $action if (result < 0) { @@ -583,6 +655,7 @@ } } + %exception semanage_seuser_set_sename { $action if (result < 0) { @@ -591,6 +664,7 @@ } } + %exception semanage_seuser_set_mlsrange { $action if (result < 0) { @@ -599,6 +673,7 @@ } } + %exception semanage_seuser_create { $action if (result < 0) { @@ -607,6 +682,7 @@ } } + %exception semanage_seuser_clone { $action if (result < 0) { @@ -615,6 +691,7 @@ } } + %exception semanage_context_set_user { $action if (result < 0) { @@ -623,6 +700,7 @@ } } + %exception semanage_context_set_role { $action if (result < 0) { @@ -631,6 +709,7 @@ } } + %exception semanage_context_set_type { $action if (result < 0) { @@ -639,6 +718,7 @@ } } + %exception semanage_context_set_mls { $action if (result < 0) { @@ -647,6 +727,7 @@ } } + %exception semanage_context_create { $action if (result < 0) { @@ -655,6 +736,7 @@ } } + %exception semanage_context_clone { $action if (result < 0) { @@ -663,6 +745,7 @@ } } + %exception semanage_context_from_string { $action if (result < 0) { @@ -671,6 +754,7 @@ } } + %exception semanage_context_to_string { $action if (result < 0) { @@ -679,6 +763,7 @@ } } + %exception semanage_iface_compare { $action if (result < 0) { @@ -687,6 +772,7 @@ } } + %exception semanage_iface_compare2 { $action if (result < 0) { @@ -695,6 +781,7 @@ } } + %exception semanage_iface_key_create { $action if (result < 0) { @@ -703,6 +790,7 @@ } } + %exception semanage_iface_key_extract { $action if (result < 0) { @@ -711,6 +799,7 @@ } } + %exception semanage_iface_set_name { $action if (result < 0) { @@ -719,6 +808,7 @@ } } + %exception semanage_iface_set_ifcon { $action if (result < 0) { @@ -727,6 +817,7 @@ } } + %exception semanage_iface_set_msgcon { $action if (result < 0) { @@ -735,6 +826,7 @@ } } + %exception semanage_iface_create { $action if (result < 0) { @@ -743,6 +835,7 @@ } } + %exception semanage_iface_clone { $action if (result < 0) { @@ -751,6 +844,7 @@ } } + %exception semanage_port_compare { $action if (result < 0) { @@ -759,6 +853,7 @@ } } + %exception semanage_port_compare2 { $action if (result < 0) { @@ -767,6 +862,7 @@ } } + %exception semanage_port_key_create { $action if (result < 0) { @@ -775,6 +871,7 @@ } } + %exception semanage_port_key_extract { $action if (result < 0) { @@ -783,6 +880,7 @@ } } + %exception semanage_port_get_proto { $action if (result < 0) { @@ -791,6 +889,7 @@ } } + %exception semanage_port_get_low { $action if (result < 0) { @@ -799,6 +898,7 @@ } } + %exception semanage_port_get_high { $action if (result < 0) { @@ -807,6 +907,7 @@ } } + %exception semanage_port_set_con { $action if (result < 0) { @@ -815,6 +916,7 @@ } } + %exception semanage_port_create { $action if (result < 0) { @@ -823,6 +925,7 @@ } } + %exception semanage_port_clone { $action if (result < 0) { @@ -831,6 +934,7 @@ } } + %exception semanage_ibpkey_compare { $action if (result < 0) { @@ -839,6 +943,7 @@ } } + %exception semanage_ibpkey_compare2 { $action if (result < 0) { @@ -847,6 +952,7 @@ } } + %exception semanage_ibpkey_key_create { $action if (result < 0) { @@ -855,6 +961,7 @@ } } + %exception semanage_ibpkey_key_extract { $action if (result < 0) { @@ -863,6 +970,7 @@ } } + %exception semanage_ibpkey_get_subnet_prefix { $action if (result < 0) { @@ -871,6 +979,7 @@ } } + %exception semanage_ibpkey_set_subnet_prefix { $action if (result < 0) { @@ -879,6 +988,7 @@ } } + %exception semanage_ibpkey_get_low { $action if (result < 0) { @@ -887,6 +997,7 @@ } } + %exception semanage_ibpkey_get_high { $action if (result < 0) { @@ -895,6 +1006,7 @@ } } + %exception semanage_ibpkey_set_con { $action if (result < 0) { @@ -903,6 +1015,7 @@ } } + %exception semanage_ibpkey_create { $action if (result < 0) { @@ -911,6 +1024,7 @@ } } + %exception semanage_ibpkey_clone { $action if (result < 0) { @@ -919,6 +1033,7 @@ } } + %exception semanage_ibendport_compare { $action if (result < 0) { @@ -927,6 +1042,7 @@ } } + %exception semanage_ibendport_compare2 { $action if (result < 0) { @@ -935,6 +1051,7 @@ } } + %exception semanage_ibendport_key_create { $action if (result < 0) { @@ -943,6 +1060,7 @@ } } + %exception semanage_ibendport_key_extract { $action if (result < 0) { @@ -951,6 +1069,7 @@ } } + %exception semanage_ibendport_get_ibdev_name { $action if (result < 0) { @@ -959,6 +1078,7 @@ } } + %exception semanage_ibendport_set_ibdev_name { $action if (result < 0) { @@ -967,6 +1087,7 @@ } } + %exception semanage_ibendport_get_port { $action if (result < 0) { @@ -975,6 +1096,7 @@ } } + %exception semanage_ibendport_set_con { $action if (result < 0) { @@ -983,6 +1105,7 @@ } } + %exception semanage_ibendport_create { $action if (result < 0) { @@ -991,6 +1114,7 @@ } } + %exception semanage_ibendport_clone { $action if (result < 0) { @@ -999,6 +1123,7 @@ } } + %exception semanage_node_compare { $action if (result < 0) { @@ -1007,6 +1132,7 @@ } } + %exception semanage_node_compare2 { $action if (result < 0) { @@ -1015,6 +1141,7 @@ } } + %exception semanage_node_key_create { $action if (result < 0) { @@ -1023,6 +1150,7 @@ } } + %exception semanage_node_key_extract { $action if (result < 0) { @@ -1031,6 +1159,7 @@ } } + %exception semanage_node_get_addr { $action if (result < 0) { @@ -1039,6 +1168,7 @@ } } + %exception semanage_node_get_addr_bytes { $action if (result < 0) { @@ -1047,6 +1177,7 @@ } } + %exception semanage_node_set_addr { $action if (result < 0) { @@ -1055,6 +1186,7 @@ } } + %exception semanage_node_set_addr_bytes { $action if (result < 0) { @@ -1063,6 +1195,7 @@ } } + %exception semanage_node_get_mask { $action if (result < 0) { @@ -1071,6 +1204,7 @@ } } + %exception semanage_node_get_mask_bytes { $action if (result < 0) { @@ -1079,6 +1213,7 @@ } } + %exception semanage_node_set_mask { $action if (result < 0) { @@ -1087,6 +1222,7 @@ } } + %exception semanage_node_set_mask_bytes { $action if (result < 0) { @@ -1095,6 +1231,7 @@ } } + %exception semanage_node_get_proto { $action if (result < 0) { @@ -1103,6 +1240,7 @@ } } + %exception semanage_node_set_con { $action if (result < 0) { @@ -1111,6 +1249,7 @@ } } + %exception semanage_node_create { $action if (result < 0) { @@ -1119,6 +1258,7 @@ } } + %exception semanage_node_clone { $action if (result < 0) { @@ -1127,6 +1267,7 @@ } } + %exception semanage_bool_modify_local { $action if (result < 0) { @@ -1135,6 +1276,7 @@ } } + %exception semanage_bool_del_local { $action if (result < 0) { @@ -1143,6 +1285,7 @@ } } + %exception semanage_bool_query_local { $action if (result < 0) { @@ -1151,6 +1294,7 @@ } } + %exception semanage_bool_exists_local { $action if (result < 0) { @@ -1159,6 +1303,7 @@ } } + %exception semanage_bool_count_local { $action if (result < 0) { @@ -1167,6 +1312,7 @@ } } + %exception semanage_bool_iterate_local { $action if (result < 0) { @@ -1175,6 +1321,7 @@ } } + %exception semanage_bool_list_local { $action if (result < 0) { @@ -1183,6 +1330,7 @@ } } + %exception semanage_bool_query { $action if (result < 0) { @@ -1191,6 +1339,7 @@ } } + %exception semanage_bool_exists { $action if (result < 0) { @@ -1199,6 +1348,7 @@ } } + %exception semanage_bool_count { $action if (result < 0) { @@ -1207,6 +1357,7 @@ } } + %exception semanage_bool_iterate { $action if (result < 0) { @@ -1215,6 +1366,7 @@ } } + %exception semanage_bool_list { $action if (result < 0) { @@ -1223,6 +1375,7 @@ } } + %exception semanage_bool_set_active { $action if (result < 0) { @@ -1231,6 +1384,7 @@ } } + %exception semanage_bool_query_active { $action if (result < 0) { @@ -1239,6 +1393,7 @@ } } + %exception semanage_bool_exists_active { $action if (result < 0) { @@ -1247,6 +1402,7 @@ } } + %exception semanage_bool_count_active { $action if (result < 0) { @@ -1255,6 +1411,7 @@ } } + %exception semanage_bool_iterate_active { $action if (result < 0) { @@ -1263,6 +1420,7 @@ } } + %exception semanage_bool_list_active { $action if (result < 0) { @@ -1271,6 +1429,7 @@ } } + %exception semanage_user_modify_local { $action if (result < 0) { @@ -1279,6 +1438,7 @@ } } + %exception semanage_user_del_local { $action if (result < 0) { @@ -1287,6 +1447,7 @@ } } + %exception semanage_user_query_local { $action if (result < 0) { @@ -1295,6 +1456,7 @@ } } + %exception semanage_user_exists_local { $action if (result < 0) { @@ -1303,6 +1465,7 @@ } } + %exception semanage_user_count_local { $action if (result < 0) { @@ -1311,6 +1474,7 @@ } } + %exception semanage_user_iterate_local { $action if (result < 0) { @@ -1319,6 +1483,7 @@ } } + %exception semanage_user_list_local { $action if (result < 0) { @@ -1327,6 +1492,7 @@ } } + %exception semanage_user_query { $action if (result < 0) { @@ -1335,6 +1501,7 @@ } } + %exception semanage_user_exists { $action if (result < 0) { @@ -1343,6 +1510,7 @@ } } + %exception semanage_user_count { $action if (result < 0) { @@ -1351,6 +1519,7 @@ } } + %exception semanage_user_iterate { $action if (result < 0) { @@ -1359,6 +1528,7 @@ } } + %exception semanage_user_list { $action if (result < 0) { @@ -1367,6 +1537,7 @@ } } + %exception semanage_fcontext_compare { $action if (result < 0) { @@ -1375,6 +1546,7 @@ } } + %exception semanage_fcontext_compare2 { $action if (result < 0) { @@ -1383,6 +1555,7 @@ } } + %exception semanage_fcontext_key_create { $action if (result < 0) { @@ -1391,6 +1564,7 @@ } } + %exception semanage_fcontext_key_extract { $action if (result < 0) { @@ -1399,6 +1573,7 @@ } } + %exception semanage_fcontext_set_expr { $action if (result < 0) { @@ -1407,6 +1582,7 @@ } } + %exception semanage_fcontext_get_type { $action if (result < 0) { @@ -1415,6 +1591,7 @@ } } + %exception semanage_fcontext_set_con { $action if (result < 0) { @@ -1423,6 +1600,7 @@ } } + %exception semanage_fcontext_create { $action if (result < 0) { @@ -1431,6 +1609,7 @@ } } + %exception semanage_fcontext_clone { $action if (result < 0) { @@ -1439,6 +1618,7 @@ } } + %exception semanage_fcontext_modify_local { $action if (result < 0) { @@ -1447,6 +1627,7 @@ } } + %exception semanage_fcontext_del_local { $action if (result < 0) { @@ -1455,6 +1636,7 @@ } } + %exception semanage_fcontext_query_local { $action if (result < 0) { @@ -1463,6 +1645,7 @@ } } + %exception semanage_fcontext_exists_local { $action if (result < 0) { @@ -1471,6 +1654,7 @@ } } + %exception semanage_fcontext_count_local { $action if (result < 0) { @@ -1479,6 +1663,7 @@ } } + %exception semanage_fcontext_iterate_local { $action if (result < 0) { @@ -1487,6 +1672,7 @@ } } + %exception semanage_fcontext_list_local { $action if (result < 0) { @@ -1495,6 +1681,7 @@ } } + %exception semanage_fcontext_query { $action if (result < 0) { @@ -1503,6 +1690,7 @@ } } + %exception semanage_fcontext_exists { $action if (result < 0) { @@ -1511,6 +1699,7 @@ } } + %exception semanage_fcontext_count { $action if (result < 0) { @@ -1519,6 +1708,7 @@ } } + %exception semanage_fcontext_iterate { $action if (result < 0) { @@ -1527,6 +1717,7 @@ } } + %exception semanage_fcontext_list { $action if (result < 0) { @@ -1535,6 +1726,7 @@ } } + %exception semanage_fcontext_list_homedirs { $action if (result < 0) { @@ -1543,6 +1735,7 @@ } } + %exception semanage_seuser_modify_local { $action if (result < 0) { @@ -1551,6 +1744,7 @@ } } + %exception semanage_seuser_del_local { $action if (result < 0) { @@ -1559,6 +1753,7 @@ } } + %exception semanage_seuser_query_local { $action if (result < 0) { @@ -1567,6 +1762,7 @@ } } + %exception semanage_seuser_exists_local { $action if (result < 0) { @@ -1575,6 +1771,7 @@ } } + %exception semanage_seuser_count_local { $action if (result < 0) { @@ -1583,6 +1780,7 @@ } } + %exception semanage_seuser_iterate_local { $action if (result < 0) { @@ -1591,6 +1789,7 @@ } } + %exception semanage_seuser_list_local { $action if (result < 0) { @@ -1599,6 +1798,7 @@ } } + %exception semanage_seuser_query { $action if (result < 0) { @@ -1607,6 +1807,7 @@ } } + %exception semanage_seuser_exists { $action if (result < 0) { @@ -1615,6 +1816,7 @@ } } + %exception semanage_seuser_count { $action if (result < 0) { @@ -1623,6 +1825,7 @@ } } + %exception semanage_seuser_iterate { $action if (result < 0) { @@ -1631,6 +1834,7 @@ } } + %exception semanage_seuser_list { $action if (result < 0) { @@ -1639,6 +1843,7 @@ } } + %exception semanage_port_modify_local { $action if (result < 0) { @@ -1647,6 +1852,7 @@ } } + %exception semanage_port_del_local { $action if (result < 0) { @@ -1655,6 +1861,7 @@ } } + %exception semanage_port_query_local { $action if (result < 0) { @@ -1663,6 +1870,7 @@ } } + %exception semanage_port_exists_local { $action if (result < 0) { @@ -1671,6 +1879,7 @@ } } + %exception semanage_port_count_local { $action if (result < 0) { @@ -1679,6 +1888,7 @@ } } + %exception semanage_port_iterate_local { $action if (result < 0) { @@ -1687,6 +1897,7 @@ } } + %exception semanage_port_list_local { $action if (result < 0) { @@ -1695,6 +1906,7 @@ } } + %exception semanage_port_query { $action if (result < 0) { @@ -1703,6 +1915,7 @@ } } + %exception semanage_port_exists { $action if (result < 0) { @@ -1711,6 +1924,7 @@ } } + %exception semanage_port_count { $action if (result < 0) { @@ -1719,6 +1933,7 @@ } } + %exception semanage_port_iterate { $action if (result < 0) { @@ -1727,6 +1942,7 @@ } } + %exception semanage_port_list { $action if (result < 0) { @@ -1735,6 +1951,7 @@ } } + %exception semanage_ibpkey_modify_local { $action if (result < 0) { @@ -1743,6 +1960,7 @@ } } + %exception semanage_ibpkey_del_local { $action if (result < 0) { @@ -1751,6 +1969,7 @@ } } + %exception semanage_ibpkey_query_local { $action if (result < 0) { @@ -1759,6 +1978,7 @@ } } + %exception semanage_ibpkey_exists_local { $action if (result < 0) { @@ -1767,6 +1987,7 @@ } } + %exception semanage_ibpkey_count_local { $action if (result < 0) { @@ -1775,6 +1996,7 @@ } } + %exception semanage_ibpkey_iterate_local { $action if (result < 0) { @@ -1783,6 +2005,7 @@ } } + %exception semanage_ibpkey_list_local { $action if (result < 0) { @@ -1791,6 +2014,7 @@ } } + %exception semanage_ibendport_modify_local { $action if (result < 0) { @@ -1799,6 +2023,7 @@ } } + %exception semanage_ibendport_del_local { $action if (result < 0) { @@ -1807,6 +2032,7 @@ } } + %exception semanage_ibendport_query_local { $action if (result < 0) { @@ -1815,6 +2041,7 @@ } } + %exception semanage_ibendport_exists_local { $action if (result < 0) { @@ -1823,6 +2050,7 @@ } } + %exception semanage_ibendport_count_local { $action if (result < 0) { @@ -1831,6 +2059,7 @@ } } + %exception semanage_ibendport_iterate_local { $action if (result < 0) { @@ -1839,6 +2068,7 @@ } } + %exception semanage_ibendport_list_local { $action if (result < 0) { @@ -1847,6 +2077,7 @@ } } + %exception semanage_ibendport_query { $action if (result < 0) { @@ -1855,6 +2086,7 @@ } } + %exception semanage_ibendport_exists { $action if (result < 0) { @@ -1863,6 +2095,7 @@ } } + %exception semanage_ibendport_count { $action if (result < 0) { @@ -1871,6 +2104,7 @@ } } + %exception semanage_ibendport_iterate { $action if (result < 0) { @@ -1879,6 +2113,7 @@ } } + %exception semanage_ibendport_list { $action if (result < 0) { @@ -1887,6 +2122,7 @@ } } + %exception semanage_ibpkey_query { $action if (result < 0) { @@ -1895,6 +2131,7 @@ } } + %exception semanage_ibpkey_exists { $action if (result < 0) { @@ -1903,6 +2140,7 @@ } } + %exception semanage_ibpkey_count { $action if (result < 0) { @@ -1911,6 +2149,7 @@ } } + %exception semanage_ibpkey_iterate { $action if (result < 0) { @@ -1919,6 +2158,7 @@ } } + %exception semanage_ibpkey_list { $action if (result < 0) { @@ -1927,6 +2167,7 @@ } } + %exception semanage_iface_modify_local { $action if (result < 0) { @@ -1935,6 +2176,7 @@ } } + %exception semanage_iface_del_local { $action if (result < 0) { @@ -1943,6 +2185,7 @@ } } + %exception semanage_iface_query_local { $action if (result < 0) { @@ -1951,6 +2194,7 @@ } } + %exception semanage_iface_exists_local { $action if (result < 0) { @@ -1959,6 +2203,7 @@ } } + %exception semanage_iface_count_local { $action if (result < 0) { @@ -1967,6 +2212,7 @@ } } + %exception semanage_iface_iterate_local { $action if (result < 0) { @@ -1975,6 +2221,7 @@ } } + %exception semanage_iface_list_local { $action if (result < 0) { @@ -1983,6 +2230,7 @@ } } + %exception semanage_iface_query { $action if (result < 0) { @@ -1991,6 +2239,7 @@ } } + %exception semanage_iface_exists { $action if (result < 0) { @@ -1999,6 +2248,7 @@ } } + %exception semanage_iface_count { $action if (result < 0) { @@ -2007,6 +2257,7 @@ } } + %exception semanage_iface_iterate { $action if (result < 0) { @@ -2015,6 +2266,7 @@ } } + %exception semanage_iface_list { $action if (result < 0) { @@ -2023,6 +2275,7 @@ } } + %exception semanage_node_modify_local { $action if (result < 0) { @@ -2031,6 +2284,7 @@ } } + %exception semanage_node_del_local { $action if (result < 0) { @@ -2039,6 +2293,7 @@ } } + %exception semanage_node_query_local { $action if (result < 0) { @@ -2047,6 +2302,7 @@ } } + %exception semanage_node_exists_local { $action if (result < 0) { @@ -2055,6 +2311,7 @@ } } + %exception semanage_node_count_local { $action if (result < 0) { @@ -2063,6 +2320,7 @@ } } + %exception semanage_node_iterate_local { $action if (result < 0) { @@ -2071,6 +2329,7 @@ } } + %exception semanage_node_list_local { $action if (result < 0) { @@ -2079,6 +2338,7 @@ } } + %exception semanage_node_query { $action if (result < 0) { @@ -2087,6 +2347,7 @@ } } + %exception semanage_node_exists { $action if (result < 0) { @@ -2095,6 +2356,7 @@ } } + %exception semanage_node_count { $action if (result < 0) { @@ -2103,6 +2365,7 @@ } } + %exception semanage_node_iterate { $action if (result < 0) { @@ -2111,6 +2374,7 @@ } } + %exception semanage_node_list { $action if (result < 0) { @@ -2118,3 +2382,4 @@ SWIG_fail; } } + diff --git a/libsemanage/src/seuser_internal.h b/libsemanage/src/seuser_internal.h index fdb52ef9..bf9cab0c 100644 --- a/libsemanage/src/seuser_internal.h +++ b/libsemanage/src/seuser_internal.h @@ -7,6 +7,24 @@ #include #include "database.h" #include "handle.h" +#include "dso.h" + +hidden_proto(semanage_seuser_clone) + hidden_proto(semanage_seuser_compare) + hidden_proto(semanage_seuser_compare2) + hidden_proto(semanage_seuser_create) + hidden_proto(semanage_seuser_free) + hidden_proto(semanage_seuser_get_mlsrange) + hidden_proto(semanage_seuser_get_name) + hidden_proto(semanage_seuser_get_sename) + hidden_proto(semanage_seuser_key_create) + hidden_proto(semanage_seuser_key_extract) + hidden_proto(semanage_seuser_key_free) + hidden_proto(semanage_seuser_set_mlsrange) + hidden_proto(semanage_seuser_set_name) + hidden_proto(semanage_seuser_set_sename) + hidden_proto(semanage_seuser_iterate) + hidden_proto(semanage_seuser_iterate_local) /* SEUSER RECORD: method table */ extern record_table_t SEMANAGE_SEUSER_RTABLE; @@ -18,7 +36,7 @@ extern int seuser_file_dbase_init(semanage_handle_t * handle, extern void seuser_file_dbase_release(dbase_config_t * dconfig); -extern int semanage_seuser_validate_local(semanage_handle_t * handle, +extern int hidden semanage_seuser_validate_local(semanage_handle_t * handle, const sepol_policydb_t * policydb); diff --git a/libsemanage/src/seuser_record.c b/libsemanage/src/seuser_record.c index 44a54758..1ed45948 100644 --- a/libsemanage/src/seuser_record.c +++ b/libsemanage/src/seuser_record.c @@ -59,6 +59,7 @@ int semanage_seuser_key_create(semanage_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(semanage_seuser_key_create) int semanage_seuser_key_extract(semanage_handle_t * handle, const semanage_seuser_t * seuser, @@ -75,6 +76,7 @@ int semanage_seuser_key_extract(semanage_handle_t * handle, return STATUS_ERR; } +hidden_def(semanage_seuser_key_extract) void semanage_seuser_key_free(semanage_seuser_key_t * key) { @@ -82,6 +84,7 @@ void semanage_seuser_key_free(semanage_seuser_key_t * key) free(key); } +hidden_def(semanage_seuser_key_free) int semanage_seuser_compare(const semanage_seuser_t * seuser, const semanage_seuser_key_t * key) @@ -90,6 +93,7 @@ int semanage_seuser_compare(const semanage_seuser_t * seuser, return strcmp(seuser->name, key->name); } +hidden_def(semanage_seuser_compare) int semanage_seuser_compare2(const semanage_seuser_t * seuser, const semanage_seuser_t * seuser2) @@ -98,6 +102,7 @@ int semanage_seuser_compare2(const semanage_seuser_t * seuser, return strcmp(seuser->name, seuser2->name); } +hidden_def(semanage_seuser_compare2) static int semanage_seuser_compare2_qsort(const semanage_seuser_t ** seuser, const semanage_seuser_t ** seuser2) @@ -113,6 +118,7 @@ const char *semanage_seuser_get_name(const semanage_seuser_t * seuser) return seuser->name; } +hidden_def(semanage_seuser_get_name) int semanage_seuser_set_name(semanage_handle_t * handle, semanage_seuser_t * seuser, const char *name) @@ -128,6 +134,7 @@ int semanage_seuser_set_name(semanage_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(semanage_seuser_set_name) /* Selinux Name */ const char *semanage_seuser_get_sename(const semanage_seuser_t * seuser) @@ -136,6 +143,7 @@ const char *semanage_seuser_get_sename(const semanage_seuser_t * seuser) return seuser->sename; } +hidden_def(semanage_seuser_get_sename) int semanage_seuser_set_sename(semanage_handle_t * handle, semanage_seuser_t * seuser, const char *sename) @@ -152,6 +160,7 @@ int semanage_seuser_set_sename(semanage_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(semanage_seuser_set_sename) /* MLS Range */ const char *semanage_seuser_get_mlsrange(const semanage_seuser_t * seuser) @@ -160,6 +169,7 @@ const char *semanage_seuser_get_mlsrange(const semanage_seuser_t * seuser) return seuser->mls_range; } +hidden_def(semanage_seuser_get_mlsrange) int semanage_seuser_set_mlsrange(semanage_handle_t * handle, semanage_seuser_t * seuser, @@ -176,6 +186,7 @@ int semanage_seuser_set_mlsrange(semanage_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(semanage_seuser_set_mlsrange) /* Create */ int semanage_seuser_create(semanage_handle_t * handle, @@ -198,6 +209,7 @@ int semanage_seuser_create(semanage_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(semanage_seuser_create) /* Deep copy clone */ int semanage_seuser_clone(semanage_handle_t * handle, @@ -230,6 +242,7 @@ int semanage_seuser_clone(semanage_handle_t * handle, return STATUS_ERR; } +hidden_def(semanage_seuser_clone) /* Destroy */ void semanage_seuser_free(semanage_seuser_t * seuser) @@ -244,6 +257,7 @@ void semanage_seuser_free(semanage_seuser_t * seuser) free(seuser); } +hidden_def(semanage_seuser_free) /* Record base functions */ record_table_t SEMANAGE_SEUSER_RTABLE = { diff --git a/libsemanage/src/seusers_local.c b/libsemanage/src/seusers_local.c index 6508ec05..3e2761c4 100644 --- a/libsemanage/src/seusers_local.c +++ b/libsemanage/src/seusers_local.c @@ -223,6 +223,7 @@ int semanage_seuser_iterate_local(semanage_handle_t * handle, return dbase_iterate(handle, dconfig, handler, handler_arg); } +hidden_def(semanage_seuser_iterate_local) int semanage_seuser_list_local(semanage_handle_t * handle, semanage_seuser_t *** records, @@ -319,7 +320,7 @@ static int validate_handler(const semanage_seuser_t * seuser, void *varg) * it will (1) deadlock, because iterate is not reentrant outside * a transaction, and (2) be racy, because it makes multiple dbase calls */ -int semanage_seuser_validate_local(semanage_handle_t * handle, +int hidden semanage_seuser_validate_local(semanage_handle_t * handle, const sepol_policydb_t * policydb) { diff --git a/libsemanage/src/seusers_policy.c b/libsemanage/src/seusers_policy.c index 77af0dd2..89fb4d8f 100644 --- a/libsemanage/src/seusers_policy.c +++ b/libsemanage/src/seusers_policy.c @@ -47,6 +47,7 @@ int semanage_seuser_iterate(semanage_handle_t * handle, return dbase_iterate(handle, dconfig, handler, handler_arg); } +hidden_def(semanage_seuser_iterate) int semanage_seuser_list(semanage_handle_t * handle, semanage_seuser_t *** records, unsigned int *count) diff --git a/libsemanage/src/user_base_record.c b/libsemanage/src/user_base_record.c index 47037665..7dfa8c6b 100644 --- a/libsemanage/src/user_base_record.c +++ b/libsemanage/src/user_base_record.c @@ -25,7 +25,7 @@ typedef semanage_user_key_t record_key_t; #include "debug.h" /* Key */ - int semanage_user_base_key_extract(semanage_handle_t * handle, +hidden int semanage_user_base_key_extract(semanage_handle_t * handle, const semanage_user_base_t * user, semanage_user_key_t ** key) { @@ -56,14 +56,14 @@ static int semanage_user_base_compare2_qsort(const semanage_user_base_t ** user, } /* Name */ - const char *semanage_user_base_get_name(const semanage_user_base_t * +hidden const char *semanage_user_base_get_name(const semanage_user_base_t * user) { return sepol_user_get_name(user); } - int semanage_user_base_set_name(semanage_handle_t * handle, +hidden int semanage_user_base_set_name(semanage_handle_t * handle, semanage_user_base_t * user, const char *name) { @@ -72,14 +72,14 @@ static int semanage_user_base_compare2_qsort(const semanage_user_base_t ** user, } /* MLS */ - const char *semanage_user_base_get_mlslevel(const semanage_user_base_t * +hidden const char *semanage_user_base_get_mlslevel(const semanage_user_base_t * user) { return sepol_user_get_mlslevel(user); } - int semanage_user_base_set_mlslevel(semanage_handle_t * handle, +hidden int semanage_user_base_set_mlslevel(semanage_handle_t * handle, semanage_user_base_t * user, const char *mls_level) { @@ -87,14 +87,14 @@ static int semanage_user_base_compare2_qsort(const semanage_user_base_t ** user, return sepol_user_set_mlslevel(handle->sepolh, user, mls_level); } - const char *semanage_user_base_get_mlsrange(const semanage_user_base_t * +hidden const char *semanage_user_base_get_mlsrange(const semanage_user_base_t * user) { return sepol_user_get_mlsrange(user); } - int semanage_user_base_set_mlsrange(semanage_handle_t * handle, +hidden int semanage_user_base_set_mlsrange(semanage_handle_t * handle, semanage_user_base_t * user, const char *mls_range) { @@ -103,13 +103,13 @@ static int semanage_user_base_compare2_qsort(const semanage_user_base_t ** user, } /* Role management */ - int semanage_user_base_get_num_roles(const semanage_user_base_t * user) +hidden int semanage_user_base_get_num_roles(const semanage_user_base_t * user) { return sepol_user_get_num_roles(user); } - int semanage_user_base_add_role(semanage_handle_t * handle, +hidden int semanage_user_base_add_role(semanage_handle_t * handle, semanage_user_base_t * user, const char *role) { @@ -117,21 +117,21 @@ static int semanage_user_base_compare2_qsort(const semanage_user_base_t ** user, return sepol_user_add_role(handle->sepolh, user, role); } - void semanage_user_base_del_role(semanage_user_base_t * user, +hidden void semanage_user_base_del_role(semanage_user_base_t * user, const char *role) { sepol_user_del_role(user, role); } - int semanage_user_base_has_role(const semanage_user_base_t * user, +hidden int semanage_user_base_has_role(const semanage_user_base_t * user, const char *role) { return sepol_user_has_role(user, role); } - int semanage_user_base_get_roles(semanage_handle_t * handle, +hidden int semanage_user_base_get_roles(semanage_handle_t * handle, const semanage_user_base_t * user, const char ***roles_arr, unsigned int *num_roles) @@ -140,7 +140,7 @@ static int semanage_user_base_compare2_qsort(const semanage_user_base_t ** user, return sepol_user_get_roles(handle->sepolh, user, roles_arr, num_roles); } - int semanage_user_base_set_roles(semanage_handle_t * handle, +hidden int semanage_user_base_set_roles(semanage_handle_t * handle, semanage_user_base_t * user, const char **roles_arr, unsigned int num_roles) @@ -150,14 +150,14 @@ static int semanage_user_base_compare2_qsort(const semanage_user_base_t ** user, } /* Create/Clone/Destroy */ - int semanage_user_base_create(semanage_handle_t * handle, +hidden int semanage_user_base_create(semanage_handle_t * handle, semanage_user_base_t ** user_ptr) { return sepol_user_create(handle->sepolh, user_ptr); } - int semanage_user_base_clone(semanage_handle_t * handle, +hidden int semanage_user_base_clone(semanage_handle_t * handle, const semanage_user_base_t * user, semanage_user_base_t ** user_ptr) { @@ -165,7 +165,7 @@ static int semanage_user_base_compare2_qsort(const semanage_user_base_t ** user, return sepol_user_clone(handle->sepolh, user, user_ptr); } - void semanage_user_base_free(semanage_user_base_t * user) +hidden void semanage_user_base_free(semanage_user_base_t * user) { sepol_user_free(user); diff --git a/libsemanage/src/user_extra_record.c b/libsemanage/src/user_extra_record.c index d2707224..efb9c5bf 100644 --- a/libsemanage/src/user_extra_record.c +++ b/libsemanage/src/user_extra_record.c @@ -76,14 +76,14 @@ static int semanage_user_extra_compare2_qsort(const semanage_user_extra_t ** } /* Name */ - const char *semanage_user_extra_get_name(const semanage_user_extra_t * +hidden const char *semanage_user_extra_get_name(const semanage_user_extra_t * user_extra) { return user_extra->name; } - int semanage_user_extra_set_name(semanage_handle_t * handle, +hidden int semanage_user_extra_set_name(semanage_handle_t * handle, semanage_user_extra_t * user_extra, const char *name) { @@ -100,14 +100,14 @@ static int semanage_user_extra_compare2_qsort(const semanage_user_extra_t ** } /* Labeling prefix */ - const char *semanage_user_extra_get_prefix(const semanage_user_extra_t * +hidden const char *semanage_user_extra_get_prefix(const semanage_user_extra_t * user_extra) { return user_extra->prefix; } - int semanage_user_extra_set_prefix(semanage_handle_t * handle, +hidden int semanage_user_extra_set_prefix(semanage_handle_t * handle, semanage_user_extra_t * user_extra, const char *prefix) { @@ -124,7 +124,7 @@ static int semanage_user_extra_compare2_qsort(const semanage_user_extra_t ** } /* Create */ - int semanage_user_extra_create(semanage_handle_t * handle, +hidden int semanage_user_extra_create(semanage_handle_t * handle, semanage_user_extra_t ** user_extra_ptr) { @@ -145,7 +145,7 @@ static int semanage_user_extra_compare2_qsort(const semanage_user_extra_t ** } /* Destroy */ - void semanage_user_extra_free(semanage_user_extra_t * user_extra) +hidden void semanage_user_extra_free(semanage_user_extra_t * user_extra) { if (!user_extra) @@ -157,7 +157,7 @@ static int semanage_user_extra_compare2_qsort(const semanage_user_extra_t ** } /* Deep copy clone */ - int semanage_user_extra_clone(semanage_handle_t * handle, +hidden int semanage_user_extra_clone(semanage_handle_t * handle, const semanage_user_extra_t * user_extra, semanage_user_extra_t ** user_extra_ptr) { diff --git a/libsemanage/src/user_internal.h b/libsemanage/src/user_internal.h index 678a73a5..2fede947 100644 --- a/libsemanage/src/user_internal.h +++ b/libsemanage/src/user_internal.h @@ -7,6 +7,26 @@ #include #include "database.h" #include "handle.h" +#include "dso.h" + +hidden_proto(semanage_user_add_role) + hidden_proto(semanage_user_clone) + hidden_proto(semanage_user_compare) + hidden_proto(semanage_user_compare2) + hidden_proto(semanage_user_create) + hidden_proto(semanage_user_free) + hidden_proto(semanage_user_get_mlslevel) + hidden_proto(semanage_user_get_mlsrange) + hidden_proto(semanage_user_get_name) + hidden_proto(semanage_user_get_roles) + hidden_proto(semanage_user_key_create) + hidden_proto(semanage_user_key_extract) + hidden_proto(semanage_user_key_free) + hidden_proto(semanage_user_set_mlslevel) + hidden_proto(semanage_user_set_mlsrange) + hidden_proto(semanage_user_set_name) + hidden_proto(semanage_user_exists) + hidden_proto(semanage_user_query) /* USER record: method table */ extern record_table_t SEMANAGE_USER_RTABLE; @@ -57,99 +77,99 @@ typedef struct semanage_user_base semanage_user_base_t; #define _SEMANAGE_USER_BASE_DEFINED_ #endif - int semanage_user_base_create(semanage_handle_t * handle, +hidden int semanage_user_base_create(semanage_handle_t * handle, semanage_user_base_t ** user_ptr); - int semanage_user_base_clone(semanage_handle_t * handle, +hidden int semanage_user_base_clone(semanage_handle_t * handle, const semanage_user_base_t * user, semanage_user_base_t ** user_ptr); - int semanage_user_base_key_extract(semanage_handle_t * handle, +hidden int semanage_user_base_key_extract(semanage_handle_t * handle, const semanage_user_base_t * user, semanage_user_key_t ** key); - const char *semanage_user_base_get_name(const semanage_user_base_t * +hidden const char *semanage_user_base_get_name(const semanage_user_base_t * user); - int semanage_user_base_set_name(semanage_handle_t * handle, +hidden int semanage_user_base_set_name(semanage_handle_t * handle, semanage_user_base_t * user, const char *name); - const char *semanage_user_base_get_mlslevel(const semanage_user_base_t * +hidden const char *semanage_user_base_get_mlslevel(const semanage_user_base_t * user); - int semanage_user_base_set_mlslevel(semanage_handle_t * handle, +hidden int semanage_user_base_set_mlslevel(semanage_handle_t * handle, semanage_user_base_t * user, const char *mls_level); - const char *semanage_user_base_get_mlsrange(const semanage_user_base_t * +hidden const char *semanage_user_base_get_mlsrange(const semanage_user_base_t * user); - int semanage_user_base_set_mlsrange(semanage_handle_t * handle, +hidden int semanage_user_base_set_mlsrange(semanage_handle_t * handle, semanage_user_base_t * user, const char *mls_range); - int semanage_user_base_get_num_roles(const semanage_user_base_t * user); +hidden int semanage_user_base_get_num_roles(const semanage_user_base_t * user); - int semanage_user_base_add_role(semanage_handle_t * handle, +hidden int semanage_user_base_add_role(semanage_handle_t * handle, semanage_user_base_t * user, const char *role); - void semanage_user_base_del_role(semanage_user_base_t * user, +hidden void semanage_user_base_del_role(semanage_user_base_t * user, const char *role); - int semanage_user_base_has_role(const semanage_user_base_t * user, +hidden int semanage_user_base_has_role(const semanage_user_base_t * user, const char *role); - int semanage_user_base_get_roles(semanage_handle_t * handle, +hidden int semanage_user_base_get_roles(semanage_handle_t * handle, const semanage_user_base_t * user, const char ***roles_arr, unsigned int *num_roles); - int semanage_user_base_set_roles(semanage_handle_t * handle, +hidden int semanage_user_base_set_roles(semanage_handle_t * handle, semanage_user_base_t * user, const char **roles_arr, unsigned int num_roles); - void semanage_user_base_free(semanage_user_base_t * user); +hidden void semanage_user_base_free(semanage_user_base_t * user); /*=========== Internal API: Extra User record ==========*/ struct semanage_user_extra; typedef struct semanage_user_extra semanage_user_extra_t; - int semanage_user_extra_create(semanage_handle_t * handle, +hidden int semanage_user_extra_create(semanage_handle_t * handle, semanage_user_extra_t ** user_extra_ptr); - int semanage_user_extra_clone(semanage_handle_t * handle, +hidden int semanage_user_extra_clone(semanage_handle_t * handle, const semanage_user_extra_t * user_extra, semanage_user_extra_t ** user_extra_ptr); - const char *semanage_user_extra_get_name(const semanage_user_extra_t * +hidden const char *semanage_user_extra_get_name(const semanage_user_extra_t * user_extra); - int semanage_user_extra_set_name(semanage_handle_t * handle, +hidden int semanage_user_extra_set_name(semanage_handle_t * handle, semanage_user_extra_t * user_extra, const char *name); - const char *semanage_user_extra_get_prefix(const semanage_user_extra_t * +hidden const char *semanage_user_extra_get_prefix(const semanage_user_extra_t * user_extra); - int semanage_user_extra_set_prefix(semanage_handle_t * handle, +hidden int semanage_user_extra_set_prefix(semanage_handle_t * handle, semanage_user_extra_t * user_extra, const char *prefix); - void semanage_user_extra_free(semanage_user_extra_t * user_extra); +hidden void semanage_user_extra_free(semanage_user_extra_t * user_extra); /*======== Internal API: Join record ========== */ - void semanage_user_key_unpack(const semanage_user_key_t * key, +hidden void semanage_user_key_unpack(const semanage_user_key_t * key, const char **name); - int semanage_user_join(semanage_handle_t * handle, +hidden int semanage_user_join(semanage_handle_t * handle, const semanage_user_base_t * record1, const semanage_user_extra_t * record2, semanage_user_t ** result); - int semanage_user_split(semanage_handle_t * handle, +hidden int semanage_user_split(semanage_handle_t * handle, const semanage_user_t * record, semanage_user_base_t ** split1, semanage_user_extra_t ** split2); diff --git a/libsemanage/src/user_record.c b/libsemanage/src/user_record.c index bb8f4de1..45239250 100644 --- a/libsemanage/src/user_record.c +++ b/libsemanage/src/user_record.c @@ -37,6 +37,7 @@ int semanage_user_key_create(semanage_handle_t * handle, return sepol_user_key_create(handle->sepolh, name, key); } +hidden_def(semanage_user_key_create) int semanage_user_key_extract(semanage_handle_t * handle, const semanage_user_t * user, @@ -46,6 +47,7 @@ int semanage_user_key_extract(semanage_handle_t * handle, return semanage_user_base_key_extract(handle, user->base, key); } +hidden_def(semanage_user_key_extract) void semanage_user_key_free(semanage_user_key_t * key) { @@ -53,8 +55,9 @@ void semanage_user_key_free(semanage_user_key_t * key) sepol_user_key_free(key); } +hidden_def(semanage_user_key_free) - void semanage_user_key_unpack(const semanage_user_key_t * key, +hidden void semanage_user_key_unpack(const semanage_user_key_t * key, const char **name) { @@ -70,6 +73,7 @@ int semanage_user_compare(const semanage_user_t * user, return strcmp(user->name, name); } +hidden_def(semanage_user_compare) int semanage_user_compare2(const semanage_user_t * user, const semanage_user_t * user2) @@ -78,6 +82,7 @@ int semanage_user_compare2(const semanage_user_t * user, return strcmp(user->name, user2->name); } +hidden_def(semanage_user_compare2) static int semanage_user_compare2_qsort(const semanage_user_t ** user, const semanage_user_t ** user2) @@ -92,6 +97,7 @@ const char *semanage_user_get_name(const semanage_user_t * user) return user->name; } +hidden_def(semanage_user_get_name) int semanage_user_set_name(semanage_handle_t * handle, semanage_user_t * user, const char *name) @@ -120,6 +126,7 @@ int semanage_user_set_name(semanage_handle_t * handle, return STATUS_ERR; } +hidden_def(semanage_user_set_name) /* Labeling prefix */ const char *semanage_user_get_prefix(const semanage_user_t * user) @@ -142,6 +149,7 @@ const char *semanage_user_get_mlslevel(const semanage_user_t * user) return semanage_user_base_get_mlslevel(user->base); } +hidden_def(semanage_user_get_mlslevel) int semanage_user_set_mlslevel(semanage_handle_t * handle, semanage_user_t * user, const char *mls_level) @@ -150,6 +158,7 @@ int semanage_user_set_mlslevel(semanage_handle_t * handle, return semanage_user_base_set_mlslevel(handle, user->base, mls_level); } +hidden_def(semanage_user_set_mlslevel) const char *semanage_user_get_mlsrange(const semanage_user_t * user) { @@ -157,6 +166,7 @@ const char *semanage_user_get_mlsrange(const semanage_user_t * user) return semanage_user_base_get_mlsrange(user->base); } +hidden_def(semanage_user_get_mlsrange) int semanage_user_set_mlsrange(semanage_handle_t * handle, semanage_user_t * user, const char *mls_range) @@ -165,6 +175,7 @@ int semanage_user_set_mlsrange(semanage_handle_t * handle, return semanage_user_base_set_mlsrange(handle, user->base, mls_range); } +hidden_def(semanage_user_set_mlsrange) /* Role management */ int semanage_user_get_num_roles(const semanage_user_t * user) @@ -180,6 +191,7 @@ int semanage_user_add_role(semanage_handle_t * handle, return semanage_user_base_add_role(handle, user->base, role); } +hidden_def(semanage_user_add_role) void semanage_user_del_role(semanage_user_t * user, const char *role) { @@ -202,6 +214,7 @@ int semanage_user_get_roles(semanage_handle_t * handle, num_roles); } +hidden_def(semanage_user_get_roles) int semanage_user_set_roles(semanage_handle_t * handle, semanage_user_t * user, @@ -242,6 +255,7 @@ int semanage_user_create(semanage_handle_t * handle, return STATUS_ERR; } +hidden_def(semanage_user_create) int semanage_user_clone(semanage_handle_t * handle, const semanage_user_t * user, @@ -275,6 +289,7 @@ int semanage_user_clone(semanage_handle_t * handle, return STATUS_ERR; } +hidden_def(semanage_user_clone) void semanage_user_free(semanage_user_t * user) { @@ -288,9 +303,10 @@ void semanage_user_free(semanage_user_t * user) free(user); } +hidden_def(semanage_user_free) /* Join properties */ - int semanage_user_join(semanage_handle_t * handle, +hidden int semanage_user_join(semanage_handle_t * handle, const semanage_user_base_t * record1, const semanage_user_extra_t * record2, semanage_user_t ** result) @@ -353,7 +369,7 @@ void semanage_user_free(semanage_user_t * user) return STATUS_ERR; } - int semanage_user_split(semanage_handle_t * handle, +hidden int semanage_user_split(semanage_handle_t * handle, const semanage_user_t * record, semanage_user_base_t ** split1, semanage_user_extra_t ** split2) diff --git a/libsemanage/src/users_policy.c b/libsemanage/src/users_policy.c index a7551324..74f59dc1 100644 --- a/libsemanage/src/users_policy.c +++ b/libsemanage/src/users_policy.c @@ -19,6 +19,7 @@ int semanage_user_query(semanage_handle_t * handle, return dbase_query(handle, dconfig, key, response); } +hidden_def(semanage_user_query) int semanage_user_exists(semanage_handle_t * handle, const semanage_user_key_t * key, int *response) @@ -28,6 +29,7 @@ int semanage_user_exists(semanage_handle_t * handle, return dbase_exists(handle, dconfig, key, response); } +hidden_def(semanage_user_exists) int semanage_user_count(semanage_handle_t * handle, unsigned int *response) { diff --git a/libsemanage/tests/libsemanage-tests.c b/libsemanage/tests/libsemanage-tests.c index ee176703..2ae4a21b 100644 --- a/libsemanage/tests/libsemanage-tests.c +++ b/libsemanage/tests/libsemanage-tests.c @@ -41,17 +41,13 @@ #include #define DECLARE_SUITE(name) \ - do { \ - suite = CU_add_suite(#name, name##_test_init, name##_test_cleanup); \ - if (NULL == suite) { \ - CU_cleanup_registry(); \ - return CU_get_error(); \ - } \ - if (name##_add_tests(suite)) { \ - CU_cleanup_registry(); \ - return CU_get_error(); \ - } \ - } while (0) + suite = CU_add_suite(#name, name##_test_init, name##_test_cleanup); \ + if (NULL == suite) { \ + CU_cleanup_registry(); \ + return CU_get_error(); } \ + if (name##_add_tests(suite)) { \ + CU_cleanup_registry(); \ + return CU_get_error(); } static void usage(char *progname) { diff --git a/libsepol/VERSION b/libsepol/VERSION index e6852d8a..9f55b2cc 100644 --- a/libsepol/VERSION +++ b/libsepol/VERSION @@ -1 +1 @@ -3.3-rc1 +3.0 diff --git a/libsepol/cil/include/cil/cil.h b/libsepol/cil/include/cil/cil.h index 482ca522..f8cfc3be 100644 --- a/libsepol/cil/include/cil/cil.h +++ b/libsepol/cil/include/cil/cil.h @@ -42,7 +42,7 @@ typedef struct cil_db cil_db_t; extern void cil_db_init(cil_db_t **db); extern void cil_db_destroy(cil_db_t **db); -extern int cil_add_file(cil_db_t *db, const char *name, const char *data, size_t size); +extern int cil_add_file(cil_db_t *db, char *name, char *data, size_t size); extern int cil_compile(cil_db_t *db); extern int cil_build_policydb(cil_db_t *db, sepol_policydb_t **sepol_db); @@ -51,7 +51,6 @@ extern int cil_selinuxusers_to_string(cil_db_t *db, char **out, size_t *size); extern int cil_filecons_to_string(cil_db_t *db, char **out, size_t *size); extern void cil_set_disable_dontaudit(cil_db_t *db, int disable_dontaudit); extern void cil_set_multiple_decls(cil_db_t *db, int multiple_decls); -extern void cil_set_qualified_names(struct cil_db *db, int qualified_names); extern void cil_set_disable_neverallow(cil_db_t *db, int disable_neverallow); extern void cil_set_preserve_tunables(cil_db_t *db, int preserve_tunables); extern int cil_set_handle_unknown(cil_db_t *db, int handle_unknown); @@ -61,9 +60,6 @@ extern void cil_set_attrs_expand_size(struct cil_db *db, unsigned attrs_expand_s extern void cil_set_target_platform(cil_db_t *db, int target_platform); extern void cil_set_policy_version(cil_db_t *db, int policy_version); extern void cil_write_policy_conf(FILE *out, struct cil_db *db); -extern int cil_write_parse_ast(FILE *out, cil_db_t *db); -extern int cil_write_build_ast(FILE *out, cil_db_t *db); -extern int cil_write_resolve_ast(FILE *out, cil_db_t *db); enum cil_log_level { CIL_ERR = 1, @@ -71,7 +67,7 @@ enum cil_log_level { CIL_INFO }; extern void cil_set_log_level(enum cil_log_level lvl); -extern void cil_set_log_handler(void (*handler)(int lvl, const char *msg)); +extern void cil_set_log_handler(void (*handler)(int lvl, char *msg)); #ifdef __GNUC__ __attribute__ ((format(printf, 2, 3))) diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c index 4cc7f87f..d222ad3a 100644 --- a/libsepol/cil/src/cil.c +++ b/libsepol/cil/src/cil.c @@ -50,11 +50,28 @@ #include "cil_binary.h" #include "cil_policy.h" #include "cil_strpool.h" -#include "cil_write_ast.h" +#include "dso.h" -const int cil_sym_sizes[CIL_SYM_ARRAY_NUM][CIL_SYM_NUM] = { +#ifndef DISABLE_SYMVER +asm(".symver cil_build_policydb_pdb, cil_build_policydb@LIBSEPOL_1.0"); +asm(".symver cil_build_policydb_create_pdb, cil_build_policydb@@LIBSEPOL_1.1"); + +asm(".symver cil_compile_pdb, cil_compile@LIBSEPOL_1.0"); +asm(".symver cil_compile_nopdb, cil_compile@@LIBSEPOL_1.1"); + +asm(".symver cil_userprefixes_to_string_pdb, cil_userprefixes_to_string@LIBSEPOL_1.0"); +asm(".symver cil_userprefixes_to_string_nopdb, cil_userprefixes_to_string@@LIBSEPOL_1.1"); + +asm(".symver cil_selinuxusers_to_string_pdb, cil_selinuxusers_to_string@LIBSEPOL_1.0"); +asm(".symver cil_selinuxusers_to_string_nopdb, cil_selinuxusers_to_string@@LIBSEPOL_1.1"); + +asm(".symver cil_filecons_to_string_pdb, cil_filecons_to_string@LIBSEPOL_1.0"); +asm(".symver cil_filecons_to_string_nopdb, cil_filecons_to_string@@LIBSEPOL_1.1"); +#endif + +int cil_sym_sizes[CIL_SYM_ARRAY_NUM][CIL_SYM_NUM] = { {64, 64, 64, 1 << 13, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}, - {8, 8, 8, 32, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + {64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} @@ -142,8 +159,6 @@ char *CIL_KEY_HANDLEUNKNOWN_DENY; char *CIL_KEY_HANDLEUNKNOWN_REJECT; char *CIL_KEY_MACRO; char *CIL_KEY_IN; -char *CIL_KEY_IN_BEFORE; -char *CIL_KEY_IN_AFTER; char *CIL_KEY_MLS; char *CIL_KEY_DEFAULTRANGE; char *CIL_KEY_BLOCKINHERIT; @@ -222,9 +237,7 @@ char *CIL_KEY_IOCTL; char *CIL_KEY_UNORDERED; char *CIL_KEY_SRC_INFO; char *CIL_KEY_SRC_CIL; -char *CIL_KEY_SRC_HLL_LMS; -char *CIL_KEY_SRC_HLL_LMX; -char *CIL_KEY_SRC_HLL_LME; +char *CIL_KEY_SRC_HLL; static void cil_init_keys(void) { @@ -357,8 +370,6 @@ static void cil_init_keys(void) CIL_KEY_DEFAULTTYPE = cil_strpool_add("defaulttype"); CIL_KEY_MACRO = cil_strpool_add("macro"); CIL_KEY_IN = cil_strpool_add("in"); - CIL_KEY_IN_BEFORE = cil_strpool_add("before"); - CIL_KEY_IN_AFTER = cil_strpool_add("after"); CIL_KEY_MLS = cil_strpool_add("mls"); CIL_KEY_DEFAULTRANGE = cil_strpool_add("defaultrange"); CIL_KEY_GLOB = cil_strpool_add("*"); @@ -390,10 +401,8 @@ static void cil_init_keys(void) CIL_KEY_IOCTL = cil_strpool_add("ioctl"); CIL_KEY_UNORDERED = cil_strpool_add("unordered"); CIL_KEY_SRC_INFO = cil_strpool_add(""); - CIL_KEY_SRC_CIL = cil_strpool_add("cil"); - CIL_KEY_SRC_HLL_LMS = cil_strpool_add("lms"); - CIL_KEY_SRC_HLL_LMX = cil_strpool_add("lmx"); - CIL_KEY_SRC_HLL_LME = cil_strpool_add("lme"); + CIL_KEY_SRC_CIL = cil_strpool_add(""); + CIL_KEY_SRC_HLL = cil_strpool_add(""); } void cil_db_init(struct cil_db **db) @@ -447,8 +456,6 @@ void cil_db_init(struct cil_db **db) (*db)->preserve_tunables = CIL_FALSE; (*db)->handle_unknown = -1; (*db)->mls = -1; - (*db)->multiple_decls = CIL_FALSE; - (*db)->qualified_names = CIL_FALSE; (*db)->target_platform = SEPOL_TARGET_SELINUX; (*db)->policy_version = POLICYDB_VERSION_MAX; } @@ -510,7 +517,7 @@ void cil_root_destroy(struct cil_root *root) free(root); } -int cil_add_file(cil_db_t *db, const char *name, const char *data, size_t size) +int cil_add_file(cil_db_t *db, char *name, char *data, size_t size) { char *buffer = NULL; int rc; @@ -538,7 +545,11 @@ exit: return rc; } +#ifdef DISABLE_SYMVER int cil_compile(struct cil_db *db) +#else +int cil_compile_nopdb(struct cil_db *db) +#endif { int rc = SEPOL_ERR; @@ -549,7 +560,7 @@ int cil_compile(struct cil_db *db) cil_log(CIL_INFO, "Building AST from Parse Tree\n"); rc = cil_build_ast(db, db->parse->root, db->ast->root); if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Failed to build AST\n"); + cil_log(CIL_INFO, "Failed to build ast\n"); goto exit; } @@ -559,21 +570,21 @@ int cil_compile(struct cil_db *db) cil_log(CIL_INFO, "Resolving AST\n"); rc = cil_resolve_ast(db, db->ast->root); if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Failed to resolve AST\n"); + cil_log(CIL_INFO, "Failed to resolve ast\n"); goto exit; } cil_log(CIL_INFO, "Qualifying Names\n"); rc = cil_fqn_qualify(db->ast->root); if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Failed to qualify names\n"); + cil_log(CIL_INFO, "Failed to qualify names\n"); goto exit; } cil_log(CIL_INFO, "Compile post process\n"); rc = cil_post_process(db); if (rc != SEPOL_OK ) { - cil_log(CIL_ERR, "Post process failed\n"); + cil_log(CIL_INFO, "Post process failed\n"); goto exit; } @@ -582,98 +593,33 @@ exit: return rc; } -int cil_write_parse_ast(FILE *out, cil_db_t *db) +#ifndef DISABLE_SYMVER +int cil_compile_pdb(struct cil_db *db, __attribute__((unused)) sepol_policydb_t *sepol_db) { - int rc = SEPOL_ERR; - - if (db == NULL) { - goto exit; - } - - cil_log(CIL_INFO, "Writing Parse AST\n"); - rc = cil_write_ast(out, CIL_WRITE_AST_PHASE_PARSE, db->parse->root); - if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Failed to write parse ast\n"); - goto exit; - } - -exit: - return rc; + return cil_compile_nopdb(db); } -int cil_write_build_ast(FILE *out, cil_db_t *db) +int cil_build_policydb_pdb(cil_db_t *db, sepol_policydb_t *sepol_db) { - int rc = SEPOL_ERR; + int rc; - if (db == NULL) { - goto exit; - } - - cil_log(CIL_INFO, "Building AST from Parse Tree\n"); - rc = cil_build_ast(db, db->parse->root, db->ast->root); + cil_log(CIL_INFO, "Building policy binary\n"); + rc = cil_binary_create_allocated_pdb(db, sepol_db); if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Failed to build ast\n"); - goto exit; - } - - cil_log(CIL_INFO, "Destroying Parse Tree\n"); - cil_tree_destroy(&db->parse); - - cil_log(CIL_INFO, "Writing Build AST\n"); - rc = cil_write_ast(out, CIL_WRITE_AST_PHASE_BUILD, db->ast->root); - if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Failed to write build ast\n"); - goto exit; - } - -exit: - return rc; -} - -int cil_write_resolve_ast(FILE *out, cil_db_t *db) -{ - int rc = SEPOL_ERR; - - if (db == NULL) { - goto exit; - } - - cil_log(CIL_INFO, "Building AST from Parse Tree\n"); - rc = cil_build_ast(db, db->parse->root, db->ast->root); - if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Failed to build ast\n"); - goto exit; - } - - cil_log(CIL_INFO, "Destroying Parse Tree\n"); - cil_tree_destroy(&db->parse); - - cil_log(CIL_INFO, "Resolving AST\n"); - rc = cil_resolve_ast(db, db->ast->root); - if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Failed to resolve ast\n"); - goto exit; - } - - cil_log(CIL_INFO, "Qualifying Names\n"); - rc = cil_fqn_qualify(db->ast->root); - if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Failed to qualify names\n"); - goto exit; - } - - cil_log(CIL_INFO, "Writing Resolve AST\n"); - rc = cil_write_ast(out, CIL_WRITE_AST_PHASE_RESOLVE, db->ast->root); - if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Failed to write resolve ast\n"); + cil_log(CIL_ERR, "Failed to generate binary\n"); goto exit; } exit: return rc; } +#endif +#ifdef DISABLE_SYMVER int cil_build_policydb(cil_db_t *db, sepol_policydb_t **sepol_db) +#else +int cil_build_policydb_create_pdb(cil_db_t *db, sepol_policydb_t **sepol_db) +#endif { int rc; @@ -1421,7 +1367,11 @@ const char * cil_node_to_string(struct cil_tree_node *node) return ""; } +#ifdef DISABLE_SYMVER int cil_userprefixes_to_string(struct cil_db *db, char **out, size_t *size) +#else +int cil_userprefixes_to_string_nopdb(struct cil_db *db, char **out, size_t *size) +#endif { int rc = SEPOL_ERR; size_t str_len = 0; @@ -1466,6 +1416,13 @@ exit: } +#ifndef DISABLE_SYMVER +int cil_userprefixes_to_string_pdb(struct cil_db *db, __attribute__((unused)) sepol_policydb_t *sepol_db, char **out, size_t *size) +{ + return cil_userprefixes_to_string_nopdb(db, out, size); +} +#endif + static int cil_cats_to_ebitmap(struct cil_cats *cats, struct ebitmap* cats_ebitmap) { int rc = SEPOL_ERR; @@ -1481,7 +1438,7 @@ static int cil_cats_to_ebitmap(struct cil_cats *cats, struct ebitmap* cats_ebitm } cil_list_for_each(i, cats->datum_expr) { - node = NODE(i->data); + node = DATUM(i->data)->nodes->head->data; if (node->flavor == CIL_CATSET) { cs = (struct cil_catset*)i->data; cil_list_for_each(j, cs->cats->datum_expr) { @@ -1653,7 +1610,11 @@ static int __cil_level_to_string(struct cil_level *lvl, char *out) return str_tmp - out; } +#ifdef DISABLE_SYMVER int cil_selinuxusers_to_string(struct cil_db *db, char **out, size_t *size) +#else +int cil_selinuxusers_to_string_nopdb(struct cil_db *db, char **out, size_t *size) +#endif { size_t str_len = 0; int buf_pos = 0; @@ -1710,7 +1671,18 @@ int cil_selinuxusers_to_string(struct cil_db *db, char **out, size_t *size) return SEPOL_OK; } +#ifndef DISABLE_SYMVER +int cil_selinuxusers_to_string_pdb(struct cil_db *db, __attribute__((unused)) sepol_policydb_t *sepol_db, char **out, size_t *size) +{ + return cil_selinuxusers_to_string_nopdb(db, out, size); +} +#endif + +#ifdef DISABLE_SYMVER int cil_filecons_to_string(struct cil_db *db, char **out, size_t *size) +#else +int cil_filecons_to_string_nopdb(struct cil_db *db, char **out, size_t *size) +#endif { uint32_t i = 0; int buf_pos = 0; @@ -1828,6 +1800,13 @@ int cil_filecons_to_string(struct cil_db *db, char **out, size_t *size) return SEPOL_OK; } +#ifndef DISABLE_SYMVER +int cil_filecons_to_string_pdb(struct cil_db *db, __attribute__((unused)) sepol_policydb_t *sepol_db, char **out, size_t *size) +{ + return cil_filecons_to_string_nopdb(db, out, size); +} +#endif + void cil_set_disable_dontaudit(struct cil_db *db, int disable_dontaudit) { db->disable_dontaudit = disable_dontaudit; @@ -1881,11 +1860,6 @@ void cil_set_multiple_decls(struct cil_db *db, int multiple_decls) db->multiple_decls = multiple_decls; } -void cil_set_qualified_names(struct cil_db *db, int qualified_names) -{ - db->qualified_names = qualified_names; -} - void cil_set_target_platform(struct cil_db *db, int target_platform) { db->target_platform = target_platform; @@ -1896,7 +1870,7 @@ void cil_set_policy_version(struct cil_db *db, int policy_version) db->policy_version = policy_version; } -void cil_symtab_array_init(symtab_t symtab[], const int symtab_sizes[CIL_SYM_NUM]) +void cil_symtab_array_init(symtab_t symtab[], int symtab_sizes[CIL_SYM_NUM]) { uint32_t i = 0; for (i = 0; i < CIL_SYM_NUM; i++) { @@ -2005,63 +1979,6 @@ exit: return SEPOL_ERR; } -int cil_string_to_uint32(const char *string, uint32_t *value, int base) -{ - unsigned long val; - char *end = NULL; - int rc = SEPOL_ERR; - - if (string == NULL || value == NULL) { - goto exit; - } - - errno = 0; - val = strtoul(string, &end, base); - if (errno != 0 || end == string || *end != '\0') { - rc = SEPOL_ERR; - goto exit; - } - - /* Ensure that the value fits a 32-bit integer without triggering -Wtype-limits */ -#if ULONG_MAX > UINT32_MAX - if (val > UINT32_MAX) { - rc = SEPOL_ERR; - goto exit; - } -#endif - - *value = val; - - return SEPOL_OK; - -exit: - cil_log(CIL_ERR, "Failed to create uint32_t from string\n"); - return rc; -} - -int cil_string_to_uint64(const char *string, uint64_t *value, int base) -{ - char *end = NULL; - int rc = SEPOL_ERR; - - if (string == NULL || value == NULL) { - goto exit; - } - - errno = 0; - *value = strtoull(string, &end, base); - if (errno != 0 || end == string || *end != '\0') { - rc = SEPOL_ERR; - goto exit; - } - - return SEPOL_OK; - -exit: - cil_log(CIL_ERR, "Failed to create uint64_t from string\n"); - return rc; -} - void cil_sort_init(struct cil_sort **sort) { *sort = cil_malloc(sizeof(**sort)); @@ -2186,7 +2103,6 @@ void cil_in_init(struct cil_in **in) *in = cil_malloc(sizeof(**in)); cil_symtab_array_init((*in)->symtab, cil_sym_sizes[CIL_SYM_ARRAY_IN]); - (*in)->is_after = CIL_FALSE; (*in)->block_str = NULL; } @@ -2824,6 +2740,7 @@ void cil_call_init(struct cil_call **call) void cil_optional_init(struct cil_optional **optional) { *optional = cil_malloc(sizeof(**optional)); + (*optional)->enabled = CIL_TRUE; cil_symtab_datum_init(&(*optional)->datum); } @@ -2890,7 +2807,6 @@ void cil_mls_init(struct cil_mls **mls) void cil_src_info_init(struct cil_src_info **info) { *info = cil_malloc(sizeof(**info)); - (*info)->kind = NULL; - (*info)->hll_line = 0; + (*info)->is_cil = 0; (*info)->path = NULL; } diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c index 43c37fc2..03d53e1f 100644 --- a/libsepol/cil/src/cil_binary.c +++ b/libsepol/cil/src/cil_binary.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -55,6 +56,9 @@ #include "cil_find.h" #include "cil_build_ast.h" +/* There are 44000 filename_trans in current fedora policy. 1.33 times this is the recommended + * size of a hashtable. The next power of 2 of this is 2 ** 16. + */ #define ROLE_TRANS_TABLE_SIZE (1 << 10) #define AVRULEX_TABLE_SIZE (1 << 10) #define PERMS_PER_CLASS 32 @@ -144,7 +148,7 @@ static int __cil_get_sepol_level_datum(policydb_t *pdb, struct cil_symtab_datum static int __cil_expand_user(struct cil_symtab_datum *datum, ebitmap_t *new) { - struct cil_tree_node *node = NODE(datum); + struct cil_tree_node *node = datum->nodes->head->data; struct cil_user *user = NULL; struct cil_userattribute *attr = NULL; @@ -172,7 +176,7 @@ exit: static int __cil_expand_role(struct cil_symtab_datum *datum, ebitmap_t *new) { - struct cil_tree_node *node = NODE(datum); + struct cil_tree_node *node = datum->nodes->head->data; if (node->flavor == CIL_ROLEATTRIBUTE) { struct cil_roleattribute *attr = (struct cil_roleattribute *)datum; @@ -198,7 +202,7 @@ exit: static int __cil_expand_type(struct cil_symtab_datum *datum, ebitmap_t *new) { - struct cil_tree_node *node = NODE(datum); + struct cil_tree_node *node = datum->nodes->head->data; if (node->flavor == CIL_TYPEATTRIBUTE) { struct cil_typeattribute *attr = (struct cil_typeattribute *)datum; @@ -590,11 +594,11 @@ exit: int __cil_typeattr_bitmap_init(policydb_t *pdb) { int rc = SEPOL_ERR; - uint32_t i; pdb->type_attr_map = cil_malloc(pdb->p_types.nprim * sizeof(ebitmap_t)); pdb->attr_type_map = cil_malloc(pdb->p_types.nprim * sizeof(ebitmap_t)); + uint32_t i = 0; for (i = 0; i < pdb->p_types.nprim; i++) { ebitmap_init(&pdb->type_attr_map[i]); ebitmap_init(&pdb->attr_type_map[i]); @@ -1070,7 +1074,7 @@ int __cil_type_rule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct ci type_datum_t *sepol_src = NULL; type_datum_t *sepol_tgt = NULL; class_datum_t *sepol_obj = NULL; - struct cil_list *class_list = NULL; + struct cil_list *class_list; type_datum_t *sepol_result = NULL; ebitmap_t src_bitmap, tgt_bitmap; ebitmap_node_t *node1, *node2; @@ -1126,12 +1130,13 @@ int __cil_typetransition_to_avtab(policydb_t *pdb, const struct cil_db *db, stru type_datum_t *sepol_src = NULL; type_datum_t *sepol_tgt = NULL; class_datum_t *sepol_obj = NULL; - struct cil_list *class_list = NULL; + struct cil_list *class_list; type_datum_t *sepol_result = NULL; + filename_trans_t *newkey = NULL; + filename_trans_datum_t *newdatum = NULL, *otype = NULL; ebitmap_t src_bitmap, tgt_bitmap; ebitmap_node_t *node1, *node2; unsigned int i, j; - uint32_t otype; struct cil_list_item *c; char *name = DATUM(typetrans->name)->name; @@ -1172,14 +1177,22 @@ int __cil_typetransition_to_avtab(policydb_t *pdb, const struct cil_db *db, stru rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj); if (rc != SEPOL_OK) goto exit; - rc = policydb_filetrans_insert( - pdb, sepol_src->s.value, sepol_tgt->s.value, - sepol_obj->s.value, name, NULL, - sepol_result->s.value, &otype - ); + newkey = cil_calloc(1, sizeof(*newkey)); + newdatum = cil_calloc(1, sizeof(*newdatum)); + newkey->stype = sepol_src->s.value; + newkey->ttype = sepol_tgt->s.value; + newkey->tclass = sepol_obj->s.value; + newkey->name = cil_strdup(name); + newdatum->otype = sepol_result->s.value; + + rc = hashtab_insert(pdb->filename_trans, + (hashtab_key_t)newkey, + newdatum); if (rc != SEPOL_OK) { if (rc == SEPOL_EEXIST) { - if (sepol_result->s.value!= otype) { + otype = hashtab_search(pdb->filename_trans, + (hashtab_key_t)newkey); + if (newdatum->otype != otype->otype) { cil_log(CIL_ERR, "Conflicting name type transition rules\n"); } else { rc = SEPOL_OK; @@ -1187,6 +1200,9 @@ int __cil_typetransition_to_avtab(policydb_t *pdb, const struct cil_db *db, stru } else { cil_log(CIL_ERR, "Out of memory\n"); } + free(newkey->name); + free(newkey); + free(newdatum); if (rc != SEPOL_OK) { goto exit; } @@ -1523,7 +1539,7 @@ int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_ /* index of the u32 containing the permission */ #define XPERM_IDX(x) (x >> 5) /* set bits 0 through x-1 within the u32 */ -#define XPERM_SETBITS(x) ((1U << (x & 0x1f)) - 1) +#define XPERM_SETBITS(x) ((1 << (x & 0x1f)) - 1) /* low value for this u32 */ #define XPERM_LOW(x) (x << 5) /* high value for this u32 */ @@ -1665,6 +1681,14 @@ exit: } cil_list_destroy(&xperms_list, CIL_FALSE); } + + // hashtab_t does not have a way to free keys or datum since it doesn't + // know what they are. We won't need the keys/datum after this function, so + // clean them up here. + free(avtab_key); + ebitmap_destroy(datum); + free(datum); + return rc; } @@ -1874,15 +1898,6 @@ exit: return rc; } -static int __cil_avrulex_ioctl_destroy(hashtab_key_t k, hashtab_datum_t datum, __attribute__((unused)) void *args) -{ - free(k); - ebitmap_destroy(datum); - free(datum); - - return SEPOL_OK; -} - int __cil_cond_to_policydb_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args) { int rc; @@ -1975,7 +1990,7 @@ static void __cil_expr_to_string(struct cil_list *expr, enum cil_flavor flavor, curr = expr->head; if (curr->flavor == CIL_OP) { - op = (enum cil_flavor)(uintptr_t)curr->data; + op = (enum cil_flavor)curr->data; if (op == CIL_ALL) { *out = cil_strdup(CIL_KEY_ALL); @@ -2074,7 +2089,7 @@ static int __cil_cond_expr_to_sepol_expr_helper(policydb_t *pdb, struct cil_list if (item == NULL) { goto exit; } else if (item->flavor == CIL_OP) { - enum cil_flavor cil_op = (enum cil_flavor)(uintptr_t)item->data; + enum cil_flavor cil_op = (enum cil_flavor)item->data; op = cil_malloc(sizeof(*op)); op->bool = 0; @@ -2174,57 +2189,12 @@ static int __cil_cond_expr_to_sepol_expr(policydb_t *pdb, struct cil_list *cil_e return SEPOL_OK; } -int __cil_validate_cond_expr(cond_expr_t *cond_expr) -{ - cond_expr_t *e; - int depth = -1; - - for (e = cond_expr; e != NULL; e = e->next) { - switch (e->expr_type) { - case COND_BOOL: - if (depth == (COND_EXPR_MAXDEPTH - 1)) { - cil_log(CIL_ERR,"Conditional expression exceeded max allowable depth\n"); - return SEPOL_ERR; - } - depth++; - break; - case COND_NOT: - if (depth < 0) { - cil_log(CIL_ERR,"Invalid conditional expression\n"); - return SEPOL_ERR; - } - break; - case COND_OR: - case COND_AND: - case COND_XOR: - case COND_EQ: - case COND_NEQ: - if (depth < 1) { - cil_log(CIL_ERR,"Invalid conditional expression\n"); - return SEPOL_ERR; - } - depth--; - break; - default: - cil_log(CIL_ERR,"Invalid conditional expression\n"); - return SEPOL_ERR; - } - } - - if (depth != 0) { - cil_log(CIL_ERR,"Invalid conditional expression\n"); - return SEPOL_ERR; - } - - return SEPOL_OK; -} - int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_tree_node *node) { int rc = SEPOL_ERR; struct cil_args_booleanif bool_args; struct cil_booleanif *cil_boolif = (struct cil_booleanif*)node->data; - struct cil_tree_node *cb_node; + struct cil_tree_node *cb_node = node->cl_head; struct cil_tree_node *true_node = NULL; struct cil_tree_node *false_node = NULL; struct cil_tree_node *tmp_node = NULL; @@ -2247,11 +2217,6 @@ int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct c goto exit; } - rc = __cil_validate_cond_expr(tmp_cond->expr); - if (rc != SEPOL_OK) { - goto exit; - } - tmp_cond->true_list = &tmp_cl; rc = cond_normalize_expr(pdb, tmp_cond); @@ -2335,7 +2300,7 @@ int cil_roletrans_to_policydb(policydb_t *pdb, const struct cil_db *db, struct c role_datum_t *sepol_src = NULL; type_datum_t *sepol_tgt = NULL; class_datum_t *sepol_obj = NULL; - struct cil_list *class_list = NULL; + struct cil_list *class_list; role_datum_t *sepol_result = NULL; role_trans_t *new = NULL; uint32_t *new_role = NULL; @@ -2560,7 +2525,7 @@ int __cil_constrain_expr_leaf_to_sepol_expr(policydb_t *pdb, const struct cil_db struct cil_list_item *l_item = op_item->next; struct cil_list_item *r_item = op_item->next->next; - enum cil_flavor l_operand = (enum cil_flavor)(uintptr_t)l_item->data; + enum cil_flavor l_operand = (enum cil_flavor)l_item->data; switch (l_operand) { case CIL_CONS_U1: @@ -2591,7 +2556,7 @@ int __cil_constrain_expr_leaf_to_sepol_expr(policydb_t *pdb, const struct cil_db expr->attr = CEXPR_TYPE | CEXPR_XTARGET; break; case CIL_CONS_L1: { - enum cil_flavor r_operand = (enum cil_flavor)(uintptr_t)r_item->data; + enum cil_flavor r_operand = (enum cil_flavor)r_item->data; if (r_operand == CIL_CONS_L2) { expr->attr = CEXPR_L1L2; @@ -2606,7 +2571,7 @@ int __cil_constrain_expr_leaf_to_sepol_expr(policydb_t *pdb, const struct cil_db expr->attr = CEXPR_L2H2; break; case CIL_CONS_H1: { - enum cil_flavor r_operand = (enum cil_flavor)(uintptr_t)r_item->data; + enum cil_flavor r_operand = (enum cil_flavor)r_item->data; if (r_operand == CIL_CONS_L2) { expr->attr = CEXPR_H1L2; } else { @@ -2654,7 +2619,6 @@ int __cil_constrain_expr_to_sepol_expr_helper(policydb_t *pdb, const struct cil_ int rc = SEPOL_ERR; struct cil_list_item *item; enum cil_flavor flavor; - enum cil_flavor cil_op; constraint_expr_t *op, *h1, *h2, *t1, *t2; int is_leaf = CIL_FALSE; @@ -2671,7 +2635,7 @@ int __cil_constrain_expr_to_sepol_expr_helper(policydb_t *pdb, const struct cil_ goto exit; } - cil_op = (enum cil_flavor)(uintptr_t)item->data; + enum cil_flavor cil_op = (enum cil_flavor)item->data; switch (cil_op) { case CIL_NOT: op->expr_type = CEXPR_NOT; @@ -2762,49 +2726,6 @@ int __cil_constrain_expr_to_sepol_expr(policydb_t *pdb, const struct cil_db *db, return SEPOL_OK; } -int __cil_validate_constrain_expr(constraint_expr_t *sepol_expr) -{ - constraint_expr_t *e; - int depth = -1; - - for (e = sepol_expr; e != NULL; e = e->next) { - switch (e->expr_type) { - case CEXPR_NOT: - if (depth < 0) { - cil_log(CIL_ERR,"Invalid constraint expression\n"); - return SEPOL_ERR; - } - break; - case CEXPR_AND: - case CEXPR_OR: - if (depth < 1) { - cil_log(CIL_ERR,"Invalid constraint expression\n"); - return SEPOL_ERR; - } - depth--; - break; - case CEXPR_ATTR: - case CEXPR_NAMES: - if (depth == (CEXPR_MAXDEPTH - 1)) { - cil_log(CIL_ERR,"Constraint expression exceeded max allowable depth\n"); - return SEPOL_ERR; - } - depth++; - break; - default: - cil_log(CIL_ERR,"Invalid constraint expression\n"); - return SEPOL_ERR; - } - } - - if (depth != 0) { - cil_log(CIL_ERR,"Invalid constraint expression\n"); - return SEPOL_ERR; - } - - return SEPOL_OK; -} - int cil_constrain_to_policydb_helper(policydb_t *pdb, const struct cil_db *db, struct cil_symtab_datum *class, struct cil_list *perms, struct cil_list *expr) { int rc = SEPOL_ERR; @@ -2828,11 +2749,6 @@ int cil_constrain_to_policydb_helper(policydb_t *pdb, const struct cil_db *db, s goto exit; } - rc = __cil_validate_constrain_expr(sepol_expr); - if (rc != SEPOL_OK) { - goto exit; - } - sepol_constrain->expr = sepol_expr; sepol_constrain->next = sepol_class->constraints; sepol_class->constraints = sepol_constrain; @@ -2840,7 +2756,6 @@ int cil_constrain_to_policydb_helper(policydb_t *pdb, const struct cil_db *db, s return SEPOL_OK; exit: - constraint_expr_destroy(sepol_expr); free(sepol_constrain); return rc; } @@ -2943,7 +2858,7 @@ int __cil_cats_to_mls_level(policydb_t *pdb, struct cil_cats *cats, mls_level_t cat_datum_t *sepol_cat = NULL; cil_list_for_each(i, cats->datum_expr) { - struct cil_tree_node *node = NODE(i->data); + struct cil_tree_node *node = DATUM(i->data)->nodes->head->data; if (node->flavor == CIL_CATSET) { struct cil_list_item *j; struct cil_catset *cs = i->data; @@ -3163,7 +3078,7 @@ int cil_rangetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, st type_datum_t *sepol_src = NULL; type_datum_t *sepol_tgt = NULL; class_datum_t *sepol_class = NULL; - struct cil_list *class_list = NULL; + struct cil_list *class_list; range_trans_t *newkey = NULL; struct mls_range *newdatum = NULL; ebitmap_t src_bitmap, tgt_bitmap; @@ -3600,7 +3515,7 @@ int cil_default_to_policydb(policydb_t *pdb, struct cil_default *def) { struct cil_list_item *curr; class_datum_t *sepol_class; - struct cil_list *class_list = NULL; + struct cil_list *class_list; cil_list_for_each(curr, def->class_datums) { struct cil_list_item *c; @@ -3655,7 +3570,7 @@ int cil_defaultrange_to_policydb(policydb_t *pdb, struct cil_defaultrange *def) { struct cil_list_item *curr; class_datum_t *sepol_class; - struct cil_list *class_list = NULL; + struct cil_list *class_list; cil_list_for_each(curr, def->class_datums) { struct cil_list_item *c; @@ -3701,7 +3616,7 @@ int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args) type_value_to_cil = args->type_value_to_cil; if (node->flavor >= CIL_MIN_DECLARATIVE) { - if (node != NODE(node->data)) { + if (node != DATUM(node->data)->nodes->head->data) { goto exit; } } @@ -4274,7 +4189,7 @@ static unsigned int avrulex_hash(__attribute__((unused)) hashtab_t h, const_hash uint32_t hash = 0; -#define mix(input) do { \ +#define mix(input) { \ uint32_t v = input; \ v *= c1; \ v = (v << r1) | (v >> (32 - r1)); \ @@ -4282,7 +4197,7 @@ static unsigned int avrulex_hash(__attribute__((unused)) hashtab_t h, const_hash hash ^= v; \ hash = (hash << r2) | (hash >> (32 - r2)); \ hash = hash * m + n; \ -} while (0) +} mix(k->target_class); mix(k->target_type); @@ -4363,13 +4278,15 @@ static int __cil_rule_to_sepol_class_perms(policydb_t *pdb, struct cil_list *cla rc = __cil_perms_to_datum(cp->perms, sepol_class, &data); if (rc != SEPOL_OK) goto exit; - if (data != 0) { /* Only add if there are permissions */ - cpn = cil_malloc(sizeof(class_perm_node_t)); - cpn->tclass = sepol_class->s.value; - cpn->data = data; - cpn->next = *sepol_class_perms; - *sepol_class_perms = cpn; + if (data == 0) { + /* No permissions */ + return SEPOL_OK; } + cpn = cil_malloc(sizeof(class_perm_node_t)); + cpn->tclass = sepol_class->s.value; + cpn->data = data; + cpn->next = *sepol_class_perms; + *sepol_class_perms = cpn; } else { /* MAP */ struct cil_list_item *j = NULL; cil_list_for_each(j, cp->perms) { @@ -4450,7 +4367,7 @@ static void __cil_init_sepol_type_set(type_set_t *t) static int __cil_add_sepol_type(policydb_t *pdb, const struct cil_db *db, struct cil_symtab_datum *datum, ebitmap_t *map) { int rc = SEPOL_ERR; - struct cil_tree_node *n = NODE(datum); + struct cil_tree_node *n = datum->nodes->head->data; type_datum_t *sepol_datum = NULL; if (n->flavor == CIL_TYPEATTRIBUTE) { @@ -4480,8 +4397,7 @@ static avrule_t *__cil_init_sepol_avrule(uint32_t kind, struct cil_tree_node *no avrule_t *avrule; struct cil_tree_node *source_node; char *source_path; - char *lm_kind; - uint32_t hll_line; + int is_cil; avrule = cil_malloc(sizeof(avrule_t)); avrule->specified = kind; @@ -4493,11 +4409,11 @@ static avrule_t *__cil_init_sepol_avrule(uint32_t kind, struct cil_tree_node *no avrule->source_filename = NULL; avrule->source_line = node->line; - source_node = cil_tree_get_next_path(node, &lm_kind, &hll_line, &source_path); + source_node = cil_tree_get_next_path(node, &source_path, &is_cil); if (source_node) { avrule->source_filename = source_path; - if (lm_kind != CIL_KEY_SRC_CIL) { - avrule->source_line = hll_line + node->hll_offset - source_node->hll_offset - 1; + if (!is_cil) { + avrule->source_line = node->hll_line; } } @@ -5037,7 +4953,6 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p exit: hashtab_destroy(role_trans_table); - hashtab_map(avrulex_ioctl_table, __cil_avrulex_ioctl_destroy, NULL); hashtab_destroy(avrulex_ioctl_table); free(type_value_to_cil); free(class_value_to_cil); diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c index f1f09f11..307b1ee3 100644 --- a/libsepol/cil/src/cil_build_ast.c +++ b/libsepol/cil/src/cil_build_ast.c @@ -49,11 +49,10 @@ struct cil_args_build { struct cil_tree_node *ast; struct cil_db *db; + struct cil_tree_node *macro; + struct cil_tree_node *boolif; struct cil_tree_node *tunif; struct cil_tree_node *in; - struct cil_tree_node *macro; - struct cil_tree_node *optional; - struct cil_tree_node *boolif; }; int cil_fill_list(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **list) @@ -64,7 +63,7 @@ int cil_fill_list(struct cil_tree_node *current, enum cil_flavor flavor, struct CIL_SYN_N_STRINGS, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); rc = __cil_verify_syntax(current, syntax, syntax_len); if (rc != SEPOL_OK) { @@ -83,70 +82,35 @@ exit: return rc; } -static int cil_allow_multiple_decls(struct cil_db *db, enum cil_flavor f_new, enum cil_flavor f_old) +/* + * Determine whether or not multiple declarations of the same key can share a + * datum, given the new datum and the one already present in a given symtab. + */ +int cil_is_datum_multiple_decl(__attribute__((unused)) struct cil_symtab_datum *cur, + __attribute__((unused)) struct cil_symtab_datum *old, + enum cil_flavor f) { - if (f_new != f_old) { - return CIL_FALSE; - } + int rc = CIL_FALSE; - switch (f_new) { + switch (f) { case CIL_TYPE: case CIL_TYPEATTRIBUTE: - if (db->multiple_decls) { - return CIL_TRUE; - } - break; - case CIL_OPTIONAL: - return CIL_TRUE; + /* type and typeattribute statements insert empty datums, ret true */ + rc = CIL_TRUE; break; default: break; } - - return CIL_FALSE; -} - -int cil_add_decl_to_symtab(struct cil_db *db, symtab_t *symtab, hashtab_key_t key, struct cil_symtab_datum *datum, struct cil_tree_node *node) -{ - int rc; - - if (symtab == NULL || datum == NULL || node == NULL) { - return SEPOL_ERR; - } - - rc = cil_symtab_insert(symtab, key, datum, node); - if (rc == SEPOL_EEXIST) { - struct cil_symtab_datum *prev; - rc = cil_symtab_get_datum(symtab, key, &prev); - if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Re-declaration of %s %s, but previous declaration could not be found\n",cil_node_to_string(node), key); - return SEPOL_ERR; - } - if (!cil_allow_multiple_decls(db, node->flavor, FLAVOR(prev))) { - /* multiple_decls not ok, ret error */ - struct cil_tree_node *n = NODE(prev); - cil_log(CIL_ERR, "Re-declaration of %s %s\n", - cil_node_to_string(node), key); - cil_tree_log(node, CIL_ERR, "Previous declaration of %s", - cil_node_to_string(n)); - return SEPOL_ERR; - } - /* multiple_decls is enabled and works for this datum type, add node */ - cil_list_append(prev->nodes, CIL_NODE, node); - node->data = prev; - cil_symtab_datum_destroy(datum); - free(datum); - } - - return SEPOL_OK; + return rc; } int cil_gen_node(struct cil_db *db, struct cil_tree_node *ast_node, struct cil_symtab_datum *datum, hashtab_key_t key, enum cil_sym_index sflavor, enum cil_flavor nflavor) { int rc = SEPOL_ERR; symtab_t *symtab = NULL; + struct cil_symtab_datum *prev; - rc = cil_verify_name(db, (const char*)key, nflavor); + rc = __cil_verify_name((const char*)key); if (rc != SEPOL_OK) { goto exit; } @@ -159,21 +123,53 @@ int cil_gen_node(struct cil_db *db, struct cil_tree_node *ast_node, struct cil_s ast_node->data = datum; ast_node->flavor = nflavor; - rc = cil_add_decl_to_symtab(db, symtab, key, datum, ast_node); - if (rc != SEPOL_OK) { - goto exit; + if (symtab != NULL) { + rc = cil_symtab_insert(symtab, (hashtab_key_t)key, datum, ast_node); + if (rc == SEPOL_EEXIST) { + if (!db->multiple_decls || + cil_symtab_get_datum(symtab, (hashtab_key_t)key, &prev) != SEPOL_OK || + !cil_is_datum_multiple_decl(datum, prev, nflavor)) { + + /* multiple_decls not ok, ret error */ + cil_log(CIL_ERR, "Re-declaration of %s %s\n", + cil_node_to_string(ast_node), key); + if (cil_symtab_get_datum(symtab, key, &datum) == SEPOL_OK) { + if (sflavor == CIL_SYM_BLOCKS) { + struct cil_tree_node *node = datum->nodes->head->data; + cil_tree_log(node, CIL_ERR, "Previous declaration"); + } + } + goto exit; + } + /* multiple_decls is enabled and works for this datum type, add node */ + cil_list_append(prev->nodes, CIL_NODE, ast_node); + ast_node->data = prev; + cil_symtab_datum_destroy(datum); + free(datum); + } } - if (ast_node->parent->flavor == CIL_MACRO) { - rc = cil_verify_decl_does_not_shadow_macro_parameter(ast_node->parent->data, ast_node, key); - if (rc != SEPOL_OK) { - goto exit; + if (ast_node->flavor >= CIL_MIN_DECLARATIVE && ast_node->parent->flavor == CIL_MACRO) { + struct cil_list_item *item; + struct cil_list *param_list = ((struct cil_macro*)ast_node->parent->data)->params; + if (param_list != NULL) { + cil_list_for_each(item, param_list) { + struct cil_param *param = item->data; + if (param->flavor == ast_node->flavor) { + if (param->str == key) { + cil_log(CIL_ERR, "%s %s shadows a macro parameter in macro declaration\n", cil_node_to_string(ast_node), key); + rc = SEPOL_ERR; + goto exit; + } + } + } } } return SEPOL_OK; exit: + cil_log(CIL_ERR, "Failed to create node\n"); return rc; } @@ -195,7 +191,7 @@ int cil_gen_block(struct cil_db *db, struct cil_tree_node *parse_current, struct CIL_SYN_N_LISTS | CIL_SYN_END, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *key = NULL; struct cil_block *block = NULL; int rc = SEPOL_ERR; @@ -204,11 +200,6 @@ int cil_gen_block(struct cil_db *db, struct cil_tree_node *parse_current, struct goto exit; } - if (db->qualified_names) { - cil_log(CIL_ERR, "Blocks are not allowed when the option for qualified names is used\n"); - goto exit; - } - rc = __cil_verify_syntax(parse_current, syntax, syntax_len); if (rc != SEPOL_OK) { goto exit; @@ -236,30 +227,13 @@ exit: void cil_destroy_block(struct cil_block *block) { - struct cil_list_item *item; - struct cil_tree_node *bi_node; - struct cil_blockinherit *inherit; - if (block == NULL) { return; } cil_symtab_datum_destroy(&block->datum); cil_symtab_array_destroy(block->symtab); - if (block->bi_nodes != NULL) { - /* unlink blockinherit->block */ - cil_list_for_each(item, block->bi_nodes) { - bi_node = item->data; - /* the conditions should always be true, but better be sure */ - if (bi_node->flavor == CIL_BLOCKINHERIT) { - inherit = bi_node->data; - if (inherit->block == block) { - inherit->block = NULL; - } - } - } - cil_list_destroy(&block->bi_nodes, CIL_FALSE); - } + cil_list_destroy(&block->bi_nodes, CIL_FALSE); free(block); } @@ -271,7 +245,7 @@ int cil_gen_blockinherit(struct cil_db *db, struct cil_tree_node *parse_current, CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_blockinherit *inherit = NULL; int rc = SEPOL_ERR; @@ -279,11 +253,6 @@ int cil_gen_blockinherit(struct cil_db *db, struct cil_tree_node *parse_current, goto exit; } - if (db->qualified_names) { - cil_log(CIL_ERR, "Block inherit rules are not allowed when the option for qualified names is used\n"); - goto exit; - } - rc = __cil_verify_syntax(parse_current, syntax, syntax_len); if (rc != SEPOL_OK) { goto exit; @@ -310,19 +279,6 @@ void cil_destroy_blockinherit(struct cil_blockinherit *inherit) return; } - if (inherit->block != NULL && inherit->block->bi_nodes != NULL) { - struct cil_tree_node *node; - struct cil_list_item *item; - - cil_list_for_each(item, inherit->block->bi_nodes) { - node = item->data; - if (node->data == inherit) { - cil_list_remove(inherit->block->bi_nodes, CIL_NODE, node, CIL_FALSE); - break; - } - } - } - free(inherit); } @@ -333,7 +289,7 @@ int cil_gen_blockabstract(struct cil_db *db, struct cil_tree_node *parse_current CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_blockabstract *abstract = NULL; int rc = SEPOL_ERR; @@ -341,11 +297,6 @@ int cil_gen_blockabstract(struct cil_db *db, struct cil_tree_node *parse_current goto exit; } - if (db->qualified_names) { - cil_log(CIL_ERR, "Block abstract rules are not allowed when the option for qualified names is used\n"); - goto exit; - } - rc = __cil_verify_syntax(parse_current, syntax, syntax_len); if (rc != SEPOL_OK) { goto exit; @@ -380,11 +331,10 @@ int cil_gen_in(struct cil_db *db, struct cil_tree_node *parse_current, struct ci enum cil_syntax syntax[] = { CIL_SYN_STRING, CIL_SYN_STRING, - CIL_SYN_STRING | CIL_SYN_N_LISTS, - CIL_SYN_N_LISTS | CIL_SYN_END, + CIL_SYN_N_LISTS, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); int rc = SEPOL_ERR; struct cil_in *in = NULL; @@ -392,11 +342,6 @@ int cil_gen_in(struct cil_db *db, struct cil_tree_node *parse_current, struct ci goto exit; } - if (db->qualified_names) { - cil_log(CIL_ERR, "In-statements are not allowed when the option for qualified names is used\n"); - goto exit; - } - rc = __cil_verify_syntax(parse_current, syntax, syntax_len); if (rc != SEPOL_OK) { goto exit; @@ -404,29 +349,14 @@ int cil_gen_in(struct cil_db *db, struct cil_tree_node *parse_current, struct ci cil_in_init(&in); - if (parse_current->next->next->data) { - char *is_after_str = parse_current->next->data; - if (is_after_str == CIL_KEY_IN_BEFORE) { - in->is_after = CIL_FALSE; - } else if (is_after_str == CIL_KEY_IN_AFTER) { - in->is_after = CIL_TRUE; - } else { - cil_log(CIL_ERR, "Value must be either \'before\' or \'after\'\n"); - rc = SEPOL_ERR; - goto exit; - } - in->block_str = parse_current->next->next->data; - } else { - in->is_after = CIL_FALSE; - in->block_str = parse_current->next->data; - } + in->block_str = parse_current->next->data; ast_node->data = in; ast_node->flavor = CIL_IN; return SEPOL_OK; exit: - cil_tree_log(parse_current, CIL_ERR, "Bad in-statement"); + cil_tree_log(parse_current, CIL_ERR, "Bad in statement"); cil_destroy_in(in); return rc; } @@ -450,7 +380,7 @@ int cil_gen_class(struct cil_db *db, struct cil_tree_node *parse_current, struct CIL_SYN_LIST | CIL_SYN_EMPTY_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *key = NULL; struct cil_class *class = NULL; struct cil_tree_node *perms = NULL; @@ -483,8 +413,6 @@ int cil_gen_class(struct cil_db *db, struct cil_tree_node *parse_current, struct } if (class->num_perms > CIL_PERMS_PER_CLASS) { cil_tree_log(parse_current, CIL_ERR, "Too many permissions in class '%s'", class->datum.name); - cil_tree_children_destroy(ast_node); - rc = SEPOL_ERR; goto exit; } @@ -518,7 +446,7 @@ int cil_gen_classorder(struct cil_db *db, struct cil_tree_node *parse_current, s CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_classorder *classorder = NULL; struct cil_list_item *curr = NULL; struct cil_list_item *head = NULL; @@ -635,7 +563,7 @@ int cil_gen_perm_nodes(struct cil_db *db, struct cil_tree_node *current_perm, st cil_tree_node_init(&new_ast); new_ast->parent = ast_node; new_ast->line = current_perm->line; - new_ast->hll_offset = current_perm->hll_offset; + new_ast->hll_line = current_perm->hll_line; rc = cil_gen_perm(db, current_perm, new_ast, flavor, num_perms); if (rc != SEPOL_OK) { @@ -669,7 +597,7 @@ int cil_fill_perms(struct cil_tree_node *start_perm, struct cil_list **perms) CIL_SYN_N_STRINGS | CIL_SYN_N_LISTS, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); rc = __cil_verify_syntax(start_perm->cl_head, syntax, syntax_len); if (rc != SEPOL_OK) { @@ -696,7 +624,7 @@ int cil_fill_classperms(struct cil_tree_node *parse_current, struct cil_classper CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); rc = __cil_verify_syntax(parse_current, syntax, syntax_len); if (rc != SEPOL_OK) { @@ -752,11 +680,20 @@ int cil_fill_classperms_list(struct cil_tree_node *parse_current, struct cil_lis { int rc = SEPOL_ERR; struct cil_tree_node *curr; + enum cil_syntax syntax[] = { + CIL_SYN_STRING | CIL_SYN_LIST, + }; + int syntax_len = sizeof(syntax)/sizeof(*syntax); if (parse_current == NULL || cp_list == NULL) { goto exit; } + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + cil_list_init(cp_list, CIL_CLASSPERMS); curr = parse_current->cl_head; @@ -817,7 +754,7 @@ int cil_gen_classpermission(struct cil_db *db, struct cil_tree_node *parse_curre CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); if (db == NULL || parse_current == NULL || ast_node == NULL) { goto exit; @@ -875,7 +812,7 @@ int cil_gen_classpermissionset(struct cil_db *db, struct cil_tree_node *parse_cu CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); if (db == NULL || parse_current == NULL || ast_node == NULL) { goto exit; @@ -925,7 +862,7 @@ int cil_gen_map_class(struct cil_db *db, struct cil_tree_node *parse_current, st CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *key = NULL; struct cil_class *map = NULL; int rc = SEPOL_ERR; @@ -969,7 +906,7 @@ int cil_gen_classmapping(struct cil_db *db, struct cil_tree_node *parse_current, CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); if (db == NULL || parse_current == NULL || ast_node == NULL) { goto exit; @@ -1021,7 +958,7 @@ int cil_gen_common(struct cil_db *db, struct cil_tree_node *parse_current, struc CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *key = NULL; struct cil_class *common = NULL; int rc = SEPOL_ERR; @@ -1050,8 +987,6 @@ int cil_gen_common(struct cil_db *db, struct cil_tree_node *parse_current, struc } if (common->num_perms > CIL_PERMS_PER_CLASS) { cil_tree_log(parse_current, CIL_ERR, "Too many permissions in common '%s'", common->datum.name); - cil_tree_children_destroy(ast_node); - rc = SEPOL_ERR; goto exit; } @@ -1073,7 +1008,7 @@ int cil_gen_classcommon(struct cil_db *db, struct cil_tree_node *parse_current, CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_classcommon *clscom = NULL; int rc = SEPOL_ERR; @@ -1119,7 +1054,7 @@ int cil_gen_sid(struct cil_db *db, struct cil_tree_node *parse_current, struct c CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *key = NULL; struct cil_sid *sid = NULL; int rc = SEPOL_ERR; @@ -1169,7 +1104,7 @@ int cil_gen_sidcontext(struct cil_db *db, struct cil_tree_node *parse_current, s CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_sidcontext *sidcon = NULL; int rc = SEPOL_ERR; @@ -1228,7 +1163,7 @@ int cil_gen_sidorder(struct cil_db *db, struct cil_tree_node *parse_current, str CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_sidorder *sidorder = NULL; struct cil_list_item *curr = NULL; int rc = SEPOL_ERR; @@ -1288,7 +1223,7 @@ int cil_gen_user(struct cil_db *db, struct cil_tree_node *parse_current, struct CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *key = NULL; struct cil_user *user = NULL; int rc = SEPOL_ERR; @@ -1339,7 +1274,7 @@ int cil_gen_userattribute(struct cil_db *db, struct cil_tree_node *parse_current CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *key = NULL; struct cil_userattribute *attr = NULL; int rc = SEPOL_ERR; @@ -1406,7 +1341,7 @@ int cil_gen_userattributeset(struct cil_db *db, struct cil_tree_node *parse_curr CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_userattributeset *attrset = NULL; int rc = SEPOL_ERR; @@ -1459,7 +1394,7 @@ int cil_gen_userlevel(struct cil_db *db, struct cil_tree_node *parse_current, st CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_userlevel *usrlvl = NULL; int rc = SEPOL_ERR; @@ -1519,7 +1454,7 @@ int cil_gen_userrange(struct cil_db *db, struct cil_tree_node *parse_current, st CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_userrange *userrange = NULL; int rc = SEPOL_ERR; @@ -1579,7 +1514,7 @@ int cil_gen_userprefix(struct cil_db *db, struct cil_tree_node *parse_current, s CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_userprefix *userprefix = NULL; int rc = SEPOL_ERR; @@ -1625,7 +1560,7 @@ int cil_gen_selinuxuser(struct cil_db *db, struct cil_tree_node *parse_current, CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_selinuxuser *selinuxuser = NULL; int rc = SEPOL_ERR; @@ -1672,7 +1607,7 @@ int cil_gen_selinuxuserdefault(struct cil_db *db, struct cil_tree_node *parse_cu CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_selinuxuser *selinuxuser = NULL; int rc = SEPOL_ERR; @@ -1731,7 +1666,7 @@ int cil_gen_role(struct cil_db *db, struct cil_tree_node *parse_current, struct CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *key = NULL; struct cil_role *role = NULL; int rc = SEPOL_ERR; @@ -1783,7 +1718,7 @@ int cil_gen_roletype(struct cil_db *db, struct cil_tree_node *parse_current, str CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_roletype *roletype = NULL; int rc = SEPOL_ERR; @@ -1829,7 +1764,7 @@ int cil_gen_userrole(struct cil_db *db, struct cil_tree_node *parse_current, str CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_userrole *userrole = NULL; int rc = SEPOL_ERR; @@ -1877,7 +1812,7 @@ int cil_gen_roletransition(struct cil_tree_node *parse_current, struct cil_tree_ CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_roletransition *roletrans = NULL; int rc = SEPOL_ERR; @@ -1925,7 +1860,7 @@ int cil_gen_roleallow(struct cil_db *db, struct cil_tree_node *parse_current, st CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_roleallow *roleallow = NULL; int rc = SEPOL_ERR; @@ -1970,7 +1905,7 @@ int cil_gen_roleattribute(struct cil_db *db, struct cil_tree_node *parse_current CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *key = NULL; struct cil_roleattribute *attr = NULL; int rc = SEPOL_ERR; @@ -1984,6 +1919,12 @@ int cil_gen_roleattribute(struct cil_db *db, struct cil_tree_node *parse_current goto exit; } + if (parse_current->next->data == CIL_KEY_SELF) { + cil_log(CIL_ERR, "The keyword '%s' is reserved\n", CIL_KEY_SELF); + rc = SEPOL_ERR; + goto exit; + } + cil_roleattribute_init(&attr); key = parse_current->next->data; @@ -2034,7 +1975,7 @@ int cil_gen_roleattributeset(struct cil_db *db, struct cil_tree_node *parse_curr CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_roleattributeset *attrset = NULL; int rc = SEPOL_ERR; @@ -2088,7 +2029,7 @@ int cil_gen_avrule(struct cil_tree_node *parse_current, struct cil_tree_node *as CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_avrule *rule = NULL; int rc = SEPOL_ERR; @@ -2150,7 +2091,7 @@ int cil_fill_permissionx(struct cil_tree_node *parse_current, struct cil_permiss CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); int rc = SEPOL_ERR; rc = __cil_verify_syntax(parse_current, syntax, syntax_len); @@ -2188,7 +2129,7 @@ int cil_gen_permissionx(struct cil_db *db, struct cil_tree_node *parse_current, CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *key = NULL; struct cil_permissionx *permx = NULL; int rc = SEPOL_ERR; @@ -2248,7 +2189,7 @@ int cil_gen_avrulex(struct cil_tree_node *parse_current, struct cil_tree_node *a CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_avrule *rule = NULL; int rc = SEPOL_ERR; @@ -2300,7 +2241,7 @@ int cil_gen_type_rule(struct cil_tree_node *parse_current, struct cil_tree_node CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_type_rule *rule = NULL; int rc = SEPOL_ERR; @@ -2348,7 +2289,7 @@ int cil_gen_type(struct cil_db *db, struct cil_tree_node *parse_current, struct CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *key = NULL; struct cil_type *type = NULL; int rc = SEPOL_ERR; @@ -2362,6 +2303,12 @@ int cil_gen_type(struct cil_db *db, struct cil_tree_node *parse_current, struct goto exit; } + if (parse_current->next->data == CIL_KEY_SELF) { + cil_log(CIL_ERR, "The keyword '%s' is reserved\n", CIL_KEY_SELF); + rc = SEPOL_ERR; + goto exit; + } + cil_type_init(&type); key = parse_current->next->data; @@ -2396,7 +2343,7 @@ int cil_gen_typeattribute(struct cil_db *db, struct cil_tree_node *parse_current CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *key = NULL; struct cil_typeattribute *attr = NULL; int rc = SEPOL_ERR; @@ -2410,6 +2357,12 @@ int cil_gen_typeattribute(struct cil_db *db, struct cil_tree_node *parse_current goto exit; } + if (parse_current->next->data == CIL_KEY_SELF) { + cil_log(CIL_ERR, "The keyword '%s' is reserved\n", CIL_KEY_SELF); + rc = SEPOL_ERR; + goto exit; + } + cil_typeattribute_init(&attr); key = parse_current->next->data; @@ -2461,7 +2414,7 @@ int cil_gen_bool(struct cil_db *db, struct cil_tree_node *parse_current, struct CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *key = NULL; struct cil_bool *boolean = NULL; int rc = SEPOL_ERR; @@ -2525,7 +2478,7 @@ int cil_gen_tunable(struct cil_db *db, struct cil_tree_node *parse_current, stru CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *key = NULL; struct cil_tunable *tunable = NULL; int rc = SEPOL_ERR; @@ -2591,13 +2544,18 @@ static enum cil_flavor __cil_get_expr_operator_flavor(const char *op) else return CIL_NONE; } -static int __cil_fill_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr); +static int __cil_fill_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr, int *depth); -static int __cil_fill_expr_helper(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr) +static int __cil_fill_expr_helper(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr, int *depth) { int rc = SEPOL_ERR; enum cil_flavor op; + if (flavor == CIL_BOOL && *depth > COND_EXPR_MAXDEPTH) { + cil_log(CIL_ERR, "Max depth of %d exceeded for boolean expression\n", COND_EXPR_MAXDEPTH); + goto exit; + } + op = __cil_get_expr_operator_flavor(current->data); rc = cil_verify_expr_syntax(current, op, flavor); @@ -2610,20 +2568,26 @@ static int __cil_fill_expr_helper(struct cil_tree_node *current, enum cil_flavor current = current->next; } + if (op == CIL_NONE || op == CIL_ALL) { + (*depth)++; + } + for (;current != NULL; current = current->next) { - rc = __cil_fill_expr(current, flavor, expr); + rc = __cil_fill_expr(current, flavor, expr, depth); if (rc != SEPOL_OK) { goto exit; } } + (*depth)--; + return SEPOL_OK; exit: return rc; } -static int __cil_fill_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr) +static int __cil_fill_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr, int *depth) { int rc = SEPOL_ERR; @@ -2637,7 +2601,7 @@ static int __cil_fill_expr(struct cil_tree_node *current, enum cil_flavor flavor } else { struct cil_list *sub_expr; cil_list_init(&sub_expr, flavor); - rc = __cil_fill_expr_helper(current->cl_head, flavor, sub_expr); + rc = __cil_fill_expr_helper(current->cl_head, flavor, sub_expr, depth); if (rc != SEPOL_OK) { cil_list_destroy(&sub_expr, CIL_TRUE); goto exit; @@ -2655,13 +2619,14 @@ exit: int cil_gen_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **expr) { int rc = SEPOL_ERR; + int depth = 0; cil_list_init(expr, flavor); if (current->cl_head == NULL) { - rc = __cil_fill_expr(current, flavor, *expr); + rc = __cil_fill_expr(current, flavor, *expr, &depth); } else { - rc = __cil_fill_expr_helper(current->cl_head, flavor, *expr); + rc = __cil_fill_expr_helper(current->cl_head, flavor, *expr, &depth); } if (rc != SEPOL_OK) { @@ -2756,12 +2721,8 @@ static int __cil_fill_constraint_leaf_expr(struct cil_tree_node *current, enum c cil_list_append(*leaf_expr, CIL_STRING, current->next->next->data); } else if (r_flavor == CIL_LIST) { struct cil_list *sub_list; - rc = cil_fill_list(current->next->next->cl_head, leaf_expr_flavor, &sub_list); - if (rc != SEPOL_OK) { - cil_list_destroy(leaf_expr, CIL_TRUE); - goto exit; - } - cil_list_append(*leaf_expr, CIL_LIST, sub_list); + cil_fill_list(current->next->next->cl_head, leaf_expr_flavor, &sub_list); + cil_list_append(*leaf_expr, CIL_LIST, &sub_list); } else { cil_list_append(*leaf_expr, CIL_CONS_OPERAND, (void *)r_flavor); } @@ -2773,7 +2734,7 @@ exit: return SEPOL_ERR; } -static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **expr) +static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **expr, int *depth) { int rc = SEPOL_ERR; enum cil_flavor op; @@ -2785,6 +2746,12 @@ static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_fl goto exit; } + if (*depth > CEXPR_MAXDEPTH) { + cil_log(CIL_ERR, "Max depth of %d exceeded for constraint expression\n", CEXPR_MAXDEPTH); + rc = SEPOL_ERR; + goto exit; + } + op = __cil_get_constraint_operator_flavor(current->data); rc = cil_verify_constraint_expr_syntax(current, op); @@ -2798,13 +2765,14 @@ static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_fl case CIL_CONS_DOM: case CIL_CONS_DOMBY: case CIL_CONS_INCOMP: + (*depth)++; rc = __cil_fill_constraint_leaf_expr(current, flavor, op, expr); if (rc != SEPOL_OK) { goto exit; } break; case CIL_NOT: - rc = __cil_fill_constraint_expr(current->next->cl_head, flavor, &lexpr); + rc = __cil_fill_constraint_expr(current->next->cl_head, flavor, &lexpr, depth); if (rc != SEPOL_OK) { goto exit; } @@ -2813,11 +2781,11 @@ static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_fl cil_list_append(*expr, CIL_LIST, lexpr); break; default: - rc = __cil_fill_constraint_expr(current->next->cl_head, flavor, &lexpr); + rc = __cil_fill_constraint_expr(current->next->cl_head, flavor, &lexpr, depth); if (rc != SEPOL_OK) { goto exit; } - rc = __cil_fill_constraint_expr(current->next->next->cl_head, flavor, &rexpr); + rc = __cil_fill_constraint_expr(current->next->next->cl_head, flavor, &rexpr, depth); if (rc != SEPOL_OK) { cil_list_destroy(&lexpr, CIL_TRUE); goto exit; @@ -2829,6 +2797,8 @@ static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_fl break; } + (*depth)--; + return SEPOL_OK; exit: @@ -2838,12 +2808,13 @@ exit: int cil_gen_constraint_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **expr) { int rc = SEPOL_ERR; + int depth = 0; if (current->cl_head == NULL) { goto exit; } - rc = __cil_fill_constraint_expr(current->cl_head, flavor, expr); + rc = __cil_fill_constraint_expr(current->cl_head, flavor, expr, &depth); if (rc != SEPOL_OK) { goto exit; } @@ -2865,9 +2836,10 @@ int cil_gen_boolif(struct cil_db *db, struct cil_tree_node *parse_current, struc CIL_SYN_LIST | CIL_SYN_END, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_booleanif *bif = NULL; struct cil_tree_node *next = NULL; + struct cil_tree_node *cond = NULL; int rc = SEPOL_ERR; if (db == NULL || parse_current == NULL || ast_node == NULL) { @@ -2887,12 +2859,27 @@ int cil_gen_boolif(struct cil_db *db, struct cil_tree_node *parse_current, struc goto exit; } - rc = cil_verify_conditional_blocks(parse_current->next->next); - if (rc != SEPOL_OK) { + cond = parse_current->next->next; + + /* Destroying expr tree after stack is created*/ + if (cond->cl_head->data != CIL_KEY_CONDTRUE && + cond->cl_head->data != CIL_KEY_CONDFALSE) { + rc = SEPOL_ERR; + cil_log(CIL_ERR, "Conditional neither true nor false\n"); goto exit; } - /* Destroying expr tree */ + if (cond->next != NULL) { + cond = cond->next; + if (cond->cl_head->data != CIL_KEY_CONDTRUE && + cond->cl_head->data != CIL_KEY_CONDFALSE) { + rc = SEPOL_ERR; + cil_log(CIL_ERR, "Conditional neither true nor false\n"); + goto exit; + } + } + + next = parse_current->next->next; cil_tree_subtree_destroy(parse_current->next); parse_current->next = next; @@ -2933,9 +2920,10 @@ int cil_gen_tunif(struct cil_db *db, struct cil_tree_node *parse_current, struct CIL_SYN_LIST | CIL_SYN_END, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_tunableif *tif = NULL; struct cil_tree_node *next = NULL; + struct cil_tree_node *cond = NULL; int rc = SEPOL_ERR; if (db == NULL || parse_current == NULL || ast_node == NULL) { @@ -2954,12 +2942,27 @@ int cil_gen_tunif(struct cil_db *db, struct cil_tree_node *parse_current, struct goto exit; } - rc = cil_verify_conditional_blocks(parse_current->next->next); - if (rc != SEPOL_OK) { + cond = parse_current->next->next; + + if (cond->cl_head->data != CIL_KEY_CONDTRUE && + cond->cl_head->data != CIL_KEY_CONDFALSE) { + rc = SEPOL_ERR; + cil_log(CIL_ERR, "Conditional neither true nor false\n"); goto exit; } - /* Destroying expr tree */ + if (cond->next != NULL) { + cond = cond->next; + + if (cond->cl_head->data != CIL_KEY_CONDTRUE && + cond->cl_head->data != CIL_KEY_CONDFALSE) { + rc = SEPOL_ERR; + cil_log(CIL_ERR, "Conditional neither true nor false\n"); + goto exit; + } + } + + /* Destroying expr tree after stack is created*/ next = parse_current->next->next; cil_tree_subtree_destroy(parse_current->next); parse_current->next = next; @@ -2994,7 +2997,7 @@ int cil_gen_condblock(struct cil_db *db, struct cil_tree_node *parse_current, st CIL_SYN_N_LISTS, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); int rc = SEPOL_ERR; struct cil_condblock *cb = NULL; @@ -3046,7 +3049,7 @@ int cil_gen_alias(struct cil_db *db, struct cil_tree_node *parse_current, struct CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *key = NULL; struct cil_alias *alias = NULL; enum cil_sym_index sym_index; @@ -3061,6 +3064,12 @@ int cil_gen_alias(struct cil_db *db, struct cil_tree_node *parse_current, struct goto exit; } + if (flavor == CIL_TYPEALIAS && parse_current->next->data == CIL_KEY_SELF) { + cil_log(CIL_ERR, "The keyword '%s' is reserved\n", CIL_KEY_SELF); + rc = SEPOL_ERR; + goto exit; + } + cil_alias_init(&alias); key = parse_current->next->data; @@ -3105,7 +3114,7 @@ int cil_gen_aliasactual(struct cil_db *db, struct cil_tree_node *parse_current, CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_aliasactual *aliasactual = NULL; if (db == NULL || parse_current == NULL || ast_node == NULL) { @@ -3157,7 +3166,7 @@ int cil_gen_typeattributeset(struct cil_db *db, struct cil_tree_node *parse_curr CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_typeattributeset *attrset = NULL; int rc = SEPOL_ERR; @@ -3210,7 +3219,7 @@ int cil_gen_expandtypeattribute(struct cil_db *db, struct cil_tree_node *parse_c CIL_SYN_END }; char *expand_str; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_expandtypeattribute *expandattr = NULL; int rc = SEPOL_ERR; @@ -3243,7 +3252,6 @@ int cil_gen_expandtypeattribute(struct cil_db *db, struct cil_tree_node *parse_c expandattr->expand = CIL_FALSE; } else { cil_log(CIL_ERR, "Value must be either \'true\' or \'false\'"); - rc = SEPOL_ERR; goto exit; } @@ -3278,7 +3286,7 @@ int cil_gen_typepermissive(struct cil_db *db, struct cil_tree_node *parse_curren CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_typepermissive *typeperm = NULL; int rc = SEPOL_ERR; @@ -3327,7 +3335,7 @@ int cil_gen_typetransition(struct cil_db *db, struct cil_tree_node *parse_curren CIL_SYN_STRING | CIL_SYN_END, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *s1, *s2, *s3, *s4, *s5; if (db == NULL || parse_current == NULL || ast_node == NULL ) { @@ -3417,7 +3425,7 @@ int cil_gen_rangetransition(struct cil_db *db, struct cil_tree_node *parse_curre CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_rangetransition *rangetrans = NULL; int rc = SEPOL_ERR; @@ -3480,7 +3488,7 @@ int cil_gen_sensitivity(struct cil_db *db, struct cil_tree_node *parse_current, CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *key = NULL; struct cil_sens *sens = NULL; int rc = SEPOL_ERR; @@ -3532,7 +3540,7 @@ int cil_gen_category(struct cil_db *db, struct cil_tree_node *parse_current, str CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *key = NULL; struct cil_cat *cat = NULL; int rc = SEPOL_ERR; @@ -3582,7 +3590,7 @@ int cil_gen_catset(struct cil_db *db, struct cil_tree_node *parse_current, struc CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *key = NULL; struct cil_catset *catset = NULL; int rc = SEPOL_ERR; @@ -3639,7 +3647,7 @@ int cil_gen_catorder(struct cil_db *db, struct cil_tree_node *parse_current, str CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_catorder *catorder = NULL; struct cil_list_item *curr = NULL; int rc = SEPOL_ERR; @@ -3699,7 +3707,7 @@ int cil_gen_sensitivityorder(struct cil_db *db, struct cil_tree_node *parse_curr CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_sensorder *sensorder = NULL; struct cil_list_item *curr = NULL; int rc = SEPOL_ERR; @@ -3722,7 +3730,7 @@ int cil_gen_sensitivityorder(struct cil_db *db, struct cil_tree_node *parse_curr cil_list_for_each(curr, sensorder->sens_list_str) { if (curr->data == CIL_KEY_UNORDERED) { - cil_log(CIL_ERR, "Sensitivity order cannot be unordered.\n"); + cil_log(CIL_ERR, "Sensitivy order cannot be unordered.\n"); rc = SEPOL_ERR; goto exit; } @@ -3760,7 +3768,7 @@ int cil_gen_senscat(struct cil_db *db, struct cil_tree_node *parse_current, stru CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_senscat *senscat = NULL; int rc = SEPOL_ERR; @@ -3812,7 +3820,7 @@ int cil_gen_level(struct cil_db *db, struct cil_tree_node *parse_current, struct CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *key = NULL; struct cil_level *level = NULL; int rc = SEPOL_ERR; @@ -3870,7 +3878,7 @@ int cil_fill_levelrange(struct cil_tree_node *low, struct cil_levelrange *lvlran CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); int rc = SEPOL_ERR; if (low == NULL || lvlrange == NULL) { @@ -3918,7 +3926,7 @@ int cil_gen_levelrange(struct cil_db *db, struct cil_tree_node *parse_current, s CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *key = NULL; struct cil_levelrange *lvlrange = NULL; int rc = SEPOL_ERR; @@ -3982,7 +3990,7 @@ int cil_gen_constrain(struct cil_db *db, struct cil_tree_node *parse_current, st CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_constrain *cons = NULL; int rc = SEPOL_ERR; @@ -4039,7 +4047,7 @@ int cil_gen_validatetrans(struct cil_db *db, struct cil_tree_node *parse_current CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_validatetrans *validtrans = NULL; int rc = SEPOL_ERR; @@ -4096,7 +4104,7 @@ int cil_fill_context(struct cil_tree_node *user_node, struct cil_context *contex CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); int rc = SEPOL_ERR; if (user_node == NULL || context == NULL) { @@ -4140,7 +4148,7 @@ int cil_gen_context(struct cil_db *db, struct cil_tree_node *parse_current, stru CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *key = NULL; struct cil_context *context = NULL; int rc = SEPOL_ERR; @@ -4183,7 +4191,7 @@ void cil_destroy_context(struct cil_context *context) return; } - cil_symtab_datum_destroy(&context->datum); + cil_symtab_datum_destroy(&context->datum);; if (context->range_str == NULL && context->range != NULL) { cil_destroy_levelrange(context->range); @@ -4201,7 +4209,7 @@ int cil_gen_filecon(struct cil_db *db, struct cil_tree_node *parse_current, stru CIL_SYN_STRING | CIL_SYN_LIST | CIL_SYN_EMPTY_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); int rc = SEPOL_ERR; struct cil_filecon *filecon = NULL; char *type = NULL; @@ -4291,7 +4299,7 @@ int cil_gen_ibpkeycon(__attribute__((unused)) struct cil_db *db, struct cil_tree CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax) / sizeof(*syntax); + int syntax_len = sizeof(syntax) / sizeof(*syntax); int rc = SEPOL_ERR; struct cil_ibpkeycon *ibpkeycon = NULL; @@ -4374,7 +4382,7 @@ int cil_gen_portcon(struct cil_db *db, struct cil_tree_node *parse_current, stru CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); int rc = SEPOL_ERR; struct cil_portcon *portcon = NULL; char *proto; @@ -4476,7 +4484,7 @@ int cil_gen_nodecon(struct cil_db *db, struct cil_tree_node *parse_current, stru CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); int rc = SEPOL_ERR; struct cil_nodecon *nodecon = NULL; @@ -4565,7 +4573,7 @@ int cil_gen_genfscon(struct cil_db *db, struct cil_tree_node *parse_current, str CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); int rc = SEPOL_ERR; struct cil_genfscon *genfscon = NULL; @@ -4628,7 +4636,7 @@ int cil_gen_netifcon(struct cil_db *db, struct cil_tree_node *parse_current, str CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); int rc = SEPOL_ERR; struct cil_netifcon *netifcon = NULL; @@ -4704,7 +4712,7 @@ int cil_gen_ibendportcon(__attribute__((unused)) struct cil_db *db, struct cil_t CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax) / sizeof(*syntax); + int syntax_len = sizeof(syntax) / sizeof(*syntax); int rc = SEPOL_ERR; struct cil_ibendportcon *ibendportcon = NULL; @@ -4765,7 +4773,7 @@ int cil_gen_pirqcon(struct cil_db *db, struct cil_tree_node *parse_current, stru CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); int rc = SEPOL_ERR; struct cil_pirqcon *pirqcon = NULL; @@ -4828,7 +4836,7 @@ int cil_gen_iomemcon(struct cil_db *db, struct cil_tree_node *parse_current, str CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); int rc = SEPOL_ERR; struct cil_iomemcon *iomemcon = NULL; @@ -4913,7 +4921,7 @@ int cil_gen_ioportcon(struct cil_db *db, struct cil_tree_node *parse_current, st CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); int rc = SEPOL_ERR; struct cil_ioportcon *ioportcon = NULL; @@ -4998,7 +5006,7 @@ int cil_gen_pcidevicecon(struct cil_db *db, struct cil_tree_node *parse_current, CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); int rc = SEPOL_ERR; struct cil_pcidevicecon *pcidevicecon = NULL; @@ -5061,7 +5069,7 @@ int cil_gen_devicetreecon(struct cil_db *db, struct cil_tree_node *parse_current CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); int rc = SEPOL_ERR; struct cil_devicetreecon *devicetreecon = NULL; @@ -5122,7 +5130,7 @@ int cil_gen_fsuse(struct cil_db *db, struct cil_tree_node *parse_current, struct CIL_SYN_STRING | CIL_SYN_LIST, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *type = NULL; struct cil_fsuse *fsuse = NULL; int rc = SEPOL_ERR; @@ -5203,7 +5211,6 @@ int cil_gen_macro(struct cil_db *db, struct cil_tree_node *parse_current, struct char *key = NULL; struct cil_macro *macro = NULL; struct cil_tree_node *macro_content = NULL; - struct cil_tree_node *current_item; enum cil_syntax syntax[] = { CIL_SYN_STRING, CIL_SYN_STRING, @@ -5211,7 +5218,7 @@ int cil_gen_macro(struct cil_db *db, struct cil_tree_node *parse_current, struct CIL_SYN_N_LISTS | CIL_SYN_END, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/ sizeof(*syntax); + int syntax_len = sizeof(syntax)/ sizeof(*syntax); if (db == NULL || parse_current == NULL || ast_node == NULL) { goto exit; @@ -5226,7 +5233,7 @@ int cil_gen_macro(struct cil_db *db, struct cil_tree_node *parse_current, struct key = parse_current->next->data; - current_item = parse_current->next->next->cl_head; + struct cil_tree_node *current_item = parse_current->next->next->cl_head; while (current_item != NULL) { enum cil_syntax param_syntax[] = { CIL_SYN_STRING, @@ -5236,7 +5243,6 @@ int cil_gen_macro(struct cil_db *db, struct cil_tree_node *parse_current, struct int param_syntax_len = sizeof(param_syntax)/sizeof(*param_syntax); char *kind = NULL; struct cil_param *param = NULL; - struct cil_list_item *curr_param; rc =__cil_verify_syntax(current_item->cl_head, param_syntax, param_syntax_len); if (rc != SEPOL_OK) { @@ -5288,18 +5294,21 @@ int cil_gen_macro(struct cil_db *db, struct cil_tree_node *parse_current, struct param->str = current_item->cl_head->next->data; - rc = cil_verify_name(db, param->str, param->flavor); + rc = __cil_verify_name(param->str); if (rc != SEPOL_OK) { cil_destroy_param(param); goto exit; } //walk current list and check for duplicate parameters + struct cil_list_item *curr_param; cil_list_for_each(curr_param, macro->params) { if (param->str == ((struct cil_param*)curr_param->data)->str) { - cil_log(CIL_ERR, "Duplicate parameter\n"); - cil_destroy_param(param); - goto exit; + if (param->flavor == ((struct cil_param*)curr_param->data)->flavor) { + cil_log(CIL_ERR, "Duplicate parameter\n"); + cil_destroy_param(param); + goto exit; + } } } @@ -5356,7 +5365,7 @@ int cil_gen_call(struct cil_db *db, struct cil_tree_node *parse_current, struct CIL_SYN_LIST | CIL_SYN_EMPTY_LIST | CIL_SYN_END, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_call *call = NULL; int rc = SEPOL_ERR; @@ -5461,7 +5470,7 @@ int cil_gen_optional(struct cil_db *db, struct cil_tree_node *parse_current, str CIL_SYN_N_LISTS | CIL_SYN_END, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *key = NULL; struct cil_optional *optional = NULL; int rc = SEPOL_ERR; @@ -5509,7 +5518,7 @@ int cil_gen_policycap(struct cil_db *db, struct cil_tree_node *parse_current, st CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *key = NULL; struct cil_policycap *polcap = NULL; int rc = SEPOL_ERR; @@ -5558,7 +5567,7 @@ int cil_gen_ipaddr(struct cil_db *db, struct cil_tree_node *parse_current, struc CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); char *key = NULL; struct cil_ipaddr *ipaddr = NULL; int rc = SEPOL_ERR; @@ -5608,40 +5617,52 @@ void cil_destroy_ipaddr(struct cil_ipaddr *ipaddr) int cil_fill_integer(struct cil_tree_node *int_node, uint32_t *integer, int base) { int rc = SEPOL_ERR; + char *endptr = NULL; + int val; - if (int_node == NULL || int_node->data == NULL || integer == NULL) { + if (int_node == NULL || integer == NULL) { goto exit; } - rc = cil_string_to_uint32(int_node->data, integer, base); - if (rc != SEPOL_OK) { + errno = 0; + val = strtol(int_node->data, &endptr, base); + if (errno != 0 || endptr == int_node->data || *endptr != '\0') { + rc = SEPOL_ERR; goto exit; } + *integer = val; + return SEPOL_OK; exit: - cil_log(CIL_ERR, "Failed to fill 32-bit integer\n"); + cil_log(CIL_ERR, "Failed to create integer from string\n"); return rc; } int cil_fill_integer64(struct cil_tree_node *int_node, uint64_t *integer, int base) { int rc = SEPOL_ERR; + char *endptr = NULL; + uint64_t val; - if (int_node == NULL || int_node->data == NULL || integer == NULL) { + if (int_node == NULL || integer == NULL) { goto exit; } - rc = cil_string_to_uint64(int_node->data, integer, base); - if (rc != SEPOL_OK) { + errno = 0; + val = strtoull(int_node->data, &endptr, base); + if (errno != 0 || endptr == int_node->data || *endptr != '\0') { + rc = SEPOL_ERR; goto exit; } + *integer = val; + return SEPOL_OK; exit: - cil_log(CIL_ERR, "Failed to fill 64-bit integer\n"); + cil_log(CIL_ERR, "Failed to create integer from string\n"); return rc; } @@ -5649,7 +5670,11 @@ int cil_fill_ipaddr(struct cil_tree_node *addr_node, struct cil_ipaddr *addr) { int rc = SEPOL_ERR; - if (addr_node == NULL || addr_node->data == NULL || addr == NULL) { + if (addr_node == NULL || addr == NULL) { + goto exit; + } + + if (addr_node->cl_head != NULL || addr_node->next != NULL) { goto exit; } @@ -5680,7 +5705,7 @@ int cil_fill_level(struct cil_tree_node *curr, struct cil_level *level) CIL_SYN_STRING | CIL_SYN_LIST | CIL_SYN_END, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); if (curr == NULL) { goto exit; @@ -5741,7 +5766,7 @@ int cil_gen_bounds(struct cil_db *db, struct cil_tree_node *parse_current, struc CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_bounds *bounds = NULL; int rc = SEPOL_ERR; @@ -5803,7 +5828,7 @@ int cil_gen_default(struct cil_tree_node *parse_current, struct cil_tree_node *a CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); rc = __cil_verify_syntax(parse_current, syntax, syntax_len); if (rc != SEPOL_OK) { @@ -5872,7 +5897,7 @@ int cil_gen_defaultrange(struct cil_tree_node *parse_current, struct cil_tree_no CIL_SYN_STRING | CIL_SYN_END, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); rc = __cil_verify_syntax(parse_current, syntax, syntax_len); if (rc != SEPOL_OK) { @@ -5893,11 +5918,6 @@ int cil_gen_defaultrange(struct cil_tree_node *parse_current, struct cil_tree_no object = parse_current->next->next->data; if (object == CIL_KEY_SOURCE) { - if (!parse_current->next->next->next) { - cil_log(CIL_ERR, "Missing 'low', 'high', or 'low-high'\n"); - rc = SEPOL_ERR; - goto exit; - } range = parse_current->next->next->next->data; if (range == CIL_KEY_LOW) { def->object_range = CIL_DEFAULT_SOURCE_LOW; @@ -5911,11 +5931,6 @@ int cil_gen_defaultrange(struct cil_tree_node *parse_current, struct cil_tree_no goto exit; } } else if (object == CIL_KEY_TARGET) { - if (!parse_current->next->next->next) { - cil_log(CIL_ERR, "Missing 'low', 'high', or 'low-high'\n"); - rc = SEPOL_ERR; - goto exit; - } range = parse_current->next->next->next->data; if (range == CIL_KEY_LOW) { def->object_range = CIL_DEFAULT_TARGET_LOW; @@ -5968,7 +5983,7 @@ int cil_gen_handleunknown(struct cil_tree_node *parse_current, struct cil_tree_n CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_handleunknown *unknown = NULL; char *unknown_key; @@ -6020,7 +6035,7 @@ int cil_gen_mls(struct cil_tree_node *parse_current, struct cil_tree_node *ast_n CIL_SYN_STRING, CIL_SYN_END }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + int syntax_len = sizeof(syntax)/sizeof(*syntax); struct cil_mls *mls = NULL; if (parse_current == NULL || ast_node == NULL) { @@ -6062,52 +6077,18 @@ void cil_destroy_mls(struct cil_mls *mls) int cil_gen_src_info(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) { - int rc = SEPOL_ERR; - enum cil_syntax syntax[] = { - CIL_SYN_STRING, - CIL_SYN_STRING, - CIL_SYN_STRING, - CIL_SYN_STRING, - CIL_SYN_N_LISTS | CIL_SYN_END, - CIL_SYN_END - }; - size_t syntax_len = sizeof(syntax)/sizeof(*syntax); + /* No need to check syntax, because this is auto generated */ struct cil_src_info *info = NULL; - if (parse_current == NULL || ast_node == NULL) { - goto exit; - } - - rc = __cil_verify_syntax(parse_current, syntax, syntax_len); - if (rc != SEPOL_OK) { - goto exit; - } - cil_src_info_init(&info); - info->kind = parse_current->next->data; - if (info->kind != CIL_KEY_SRC_CIL && info->kind != CIL_KEY_SRC_HLL_LMS && info->kind != CIL_KEY_SRC_HLL_LMX) { - cil_log(CIL_ERR, "Invalid src info kind\n"); - rc = SEPOL_ERR; - goto exit; - } - - rc = cil_string_to_uint32(parse_current->next->next->data, &info->hll_line, 10); - if (rc != SEPOL_OK) { - goto exit; - } - - info->path = parse_current->next->next->next->data; + info->is_cil = (parse_current->next->data == CIL_KEY_SRC_CIL) ? CIL_TRUE : CIL_FALSE; + info->path = parse_current->next->next->data; ast_node->data = info; ast_node->flavor = CIL_SRC_INFO; return SEPOL_OK; - -exit: - cil_tree_log(parse_current, CIL_ERR, "Bad src info"); - cil_destroy_src_info(info); - return rc; } void cil_destroy_src_info(struct cil_src_info *info) @@ -6115,396 +6096,443 @@ void cil_destroy_src_info(struct cil_src_info *info) free(info); } -static int check_for_illegal_statement(struct cil_tree_node *parse_current, struct cil_args_build *args) +int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *finished, void *extra_args) { - if (args->tunif != NULL) { - if (parse_current->data == CIL_KEY_TUNABLE) { - cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in tunableif", (char *)parse_current->data); - return SEPOL_ERR; - } + struct cil_args_build *args = NULL; + struct cil_tree_node *ast_current = NULL; + struct cil_db *db = NULL; + struct cil_tree_node *ast_node = NULL; + struct cil_tree_node *macro = NULL; + struct cil_tree_node *boolif = NULL; + struct cil_tree_node *tunif = NULL; + struct cil_tree_node *in = NULL; + int rc = SEPOL_ERR; + + if (parse_current == NULL || finished == NULL || extra_args == NULL) { + goto exit; } - if (args->in != NULL) { - struct cil_in *in_block = args->in->data; - if (parse_current->data == CIL_KEY_TUNABLE || - parse_current->data == CIL_KEY_IN) { - cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in in-statement", (char *)parse_current->data); - return SEPOL_ERR; - } - if (in_block->is_after == CIL_TRUE) { - if (parse_current->data == CIL_KEY_BLOCKINHERIT || - parse_current->data == CIL_KEY_BLOCKABSTRACT) { - cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in an after in-statement", (char *)parse_current->data); - return SEPOL_ERR; - } + args = extra_args; + ast_current = args->ast; + db = args->db; + macro = args->macro; + boolif = args->boolif; + tunif = args->tunif; + in = args->in; + + if (parse_current->parent->cl_head != parse_current) { + /* ignore anything that isn't following a parenthesis */ + rc = SEPOL_OK; + goto exit; + } else if (parse_current->data == NULL) { + /* the only time parenthesis can immediately following parenthesis is if + * the parent is the root node */ + if (parse_current->parent->parent == NULL) { + rc = SEPOL_OK; + } else { + cil_tree_log(parse_current, CIL_ERR, "Keyword expected after open parenthesis"); } + goto exit; } - if (args->macro != NULL) { - if (parse_current->data == CIL_KEY_TUNABLE || + if (macro != NULL) { + if (parse_current->data == CIL_KEY_MACRO || + parse_current->data == CIL_KEY_TUNABLE || parse_current->data == CIL_KEY_IN || parse_current->data == CIL_KEY_BLOCK || parse_current->data == CIL_KEY_BLOCKINHERIT || - parse_current->data == CIL_KEY_BLOCKABSTRACT || - parse_current->data == CIL_KEY_MACRO) { - cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in macro", (char *)parse_current->data); - return SEPOL_ERR; + parse_current->data == CIL_KEY_BLOCKABSTRACT) { + rc = SEPOL_ERR; + cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in macros", (char *)parse_current->data); + goto exit; } } - if (args->optional != NULL) { - if (parse_current->data == CIL_KEY_TUNABLE || - parse_current->data == CIL_KEY_IN || - parse_current->data == CIL_KEY_BLOCK || - parse_current->data == CIL_KEY_BLOCKABSTRACT || - parse_current->data == CIL_KEY_MACRO) { - cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in optional", (char *)parse_current->data); - return SEPOL_ERR; - } - } - - if (args->boolif != NULL) { - if (parse_current->data != CIL_KEY_TUNABLEIF && - parse_current->data != CIL_KEY_CALL && - parse_current->data != CIL_KEY_CONDTRUE && + if (boolif != NULL) { + if (parse_current->data != CIL_KEY_CONDTRUE && parse_current->data != CIL_KEY_CONDFALSE && + parse_current->data != CIL_KEY_AUDITALLOW && + parse_current->data != CIL_KEY_TUNABLEIF && parse_current->data != CIL_KEY_ALLOW && parse_current->data != CIL_KEY_DONTAUDIT && - parse_current->data != CIL_KEY_AUDITALLOW && parse_current->data != CIL_KEY_TYPETRANSITION && parse_current->data != CIL_KEY_TYPECHANGE && - parse_current->data != CIL_KEY_TYPEMEMBER) { - if (((struct cil_booleanif*)args->boolif->data)->preserved_tunable) { - cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in tunableif being treated as a booleanif", (char *)parse_current->data); + parse_current->data != CIL_KEY_CALL) { + rc = SEPOL_ERR; + cil_tree_log(parse_current, CIL_ERR, "Found %s", (char*)parse_current->data); + if (((struct cil_booleanif*)boolif->data)->preserved_tunable) { + cil_log(CIL_ERR, "%s cannot be defined within tunableif statement (treated as a booleanif due to preserve-tunables)\n", + (char*)parse_current->data); } else { - cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in booleanif", (char *)parse_current->data); + cil_log(CIL_ERR, "%s cannot be defined within booleanif statement\n", + (char*)parse_current->data); } - return SEPOL_ERR; + goto exit; } } - return SEPOL_OK; -} + if (tunif != NULL) { + if (parse_current->data == CIL_KEY_TUNABLE) { + rc = SEPOL_ERR; + cil_tree_log(parse_current, CIL_ERR, "Found tunable"); + cil_log(CIL_ERR, "Tunables cannot be defined within tunableif statement\n"); + goto exit; + } + } -static struct cil_tree_node * parse_statement(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_parent) -{ - struct cil_tree_node *new_ast_node = NULL; - int rc = SEPOL_ERR; + if (in != NULL) { + if (parse_current->data == CIL_KEY_IN) { + rc = SEPOL_ERR; + cil_tree_log(parse_current, CIL_ERR, "Found in-statement"); + cil_log(CIL_ERR, "in-statements cannot be defined within in-statements\n"); + goto exit; + } + } - cil_tree_node_init(&new_ast_node); - new_ast_node->parent = ast_parent; - new_ast_node->line = parse_current->line; - new_ast_node->hll_offset = parse_current->hll_offset; + cil_tree_node_init(&ast_node); + + ast_node->parent = ast_current; + ast_node->line = parse_current->line; + ast_node->hll_line = parse_current->hll_line; if (parse_current->data == CIL_KEY_BLOCK) { - rc = cil_gen_block(db, parse_current, new_ast_node, 0); + rc = cil_gen_block(db, parse_current, ast_node, 0); } else if (parse_current->data == CIL_KEY_BLOCKINHERIT) { - rc = cil_gen_blockinherit(db, parse_current, new_ast_node); + rc = cil_gen_blockinherit(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_BLOCKABSTRACT) { - rc = cil_gen_blockabstract(db, parse_current, new_ast_node); + rc = cil_gen_blockabstract(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_IN) { - rc = cil_gen_in(db, parse_current, new_ast_node); + rc = cil_gen_in(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_CLASS) { - rc = cil_gen_class(db, parse_current, new_ast_node); + rc = cil_gen_class(db, parse_current, ast_node); + // To avoid parsing list of perms again + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_CLASSORDER) { - rc = cil_gen_classorder(db, parse_current, new_ast_node); + rc = cil_gen_classorder(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_MAP_CLASS) { - rc = cil_gen_map_class(db, parse_current, new_ast_node); + rc = cil_gen_map_class(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_CLASSMAPPING) { - rc = cil_gen_classmapping(db, parse_current, new_ast_node); + rc = cil_gen_classmapping(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_CLASSPERMISSION) { - rc = cil_gen_classpermission(db, parse_current, new_ast_node); + rc = cil_gen_classpermission(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_CLASSPERMISSIONSET) { - rc = cil_gen_classpermissionset(db, parse_current, new_ast_node); + rc = cil_gen_classpermissionset(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_COMMON) { - rc = cil_gen_common(db, parse_current, new_ast_node); + rc = cil_gen_common(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_CLASSCOMMON) { - rc = cil_gen_classcommon(db, parse_current, new_ast_node); + rc = cil_gen_classcommon(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_SID) { - rc = cil_gen_sid(db, parse_current, new_ast_node); + rc = cil_gen_sid(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_SIDCONTEXT) { - rc = cil_gen_sidcontext(db, parse_current, new_ast_node); + rc = cil_gen_sidcontext(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_SIDORDER) { - rc = cil_gen_sidorder(db, parse_current, new_ast_node); + rc = cil_gen_sidorder(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_USER) { - rc = cil_gen_user(db, parse_current, new_ast_node); + rc = cil_gen_user(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_USERATTRIBUTE) { - rc = cil_gen_userattribute(db, parse_current, new_ast_node); + rc = cil_gen_userattribute(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_USERATTRIBUTESET) { - rc = cil_gen_userattributeset(db, parse_current, new_ast_node); + rc = cil_gen_userattributeset(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_USERLEVEL) { - rc = cil_gen_userlevel(db, parse_current, new_ast_node); + rc = cil_gen_userlevel(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_USERRANGE) { - rc = cil_gen_userrange(db, parse_current, new_ast_node); + rc = cil_gen_userrange(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_USERBOUNDS) { - rc = cil_gen_bounds(db, parse_current, new_ast_node, CIL_USER); + rc = cil_gen_bounds(db, parse_current, ast_node, CIL_USER); } else if (parse_current->data == CIL_KEY_USERPREFIX) { - rc = cil_gen_userprefix(db, parse_current, new_ast_node); + rc = cil_gen_userprefix(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_SELINUXUSER) { - rc = cil_gen_selinuxuser(db, parse_current, new_ast_node); + rc = cil_gen_selinuxuser(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_SELINUXUSERDEFAULT) { - rc = cil_gen_selinuxuserdefault(db, parse_current, new_ast_node); + rc = cil_gen_selinuxuserdefault(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_TYPE) { - rc = cil_gen_type(db, parse_current, new_ast_node); + rc = cil_gen_type(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_TYPEATTRIBUTE) { - rc = cil_gen_typeattribute(db, parse_current, new_ast_node); + rc = cil_gen_typeattribute(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_TYPEATTRIBUTESET) { - rc = cil_gen_typeattributeset(db, parse_current, new_ast_node); + rc = cil_gen_typeattributeset(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_EXPANDTYPEATTRIBUTE) { - rc = cil_gen_expandtypeattribute(db, parse_current, new_ast_node); + rc = cil_gen_expandtypeattribute(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_TYPEALIAS) { - rc = cil_gen_alias(db, parse_current, new_ast_node, CIL_TYPEALIAS); + rc = cil_gen_alias(db, parse_current, ast_node, CIL_TYPEALIAS); } else if (parse_current->data == CIL_KEY_TYPEALIASACTUAL) { - rc = cil_gen_aliasactual(db, parse_current, new_ast_node, CIL_TYPEALIASACTUAL); + rc = cil_gen_aliasactual(db, parse_current, ast_node, CIL_TYPEALIASACTUAL); } else if (parse_current->data == CIL_KEY_TYPEBOUNDS) { - rc = cil_gen_bounds(db, parse_current, new_ast_node, CIL_TYPE); + rc = cil_gen_bounds(db, parse_current, ast_node, CIL_TYPE); } else if (parse_current->data == CIL_KEY_TYPEPERMISSIVE) { - rc = cil_gen_typepermissive(db, parse_current, new_ast_node); + rc = cil_gen_typepermissive(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_RANGETRANSITION) { - rc = cil_gen_rangetransition(db, parse_current, new_ast_node); + rc = cil_gen_rangetransition(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_ROLE) { - rc = cil_gen_role(db, parse_current, new_ast_node); + rc = cil_gen_role(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_USERROLE) { - rc = cil_gen_userrole(db, parse_current, new_ast_node); + rc = cil_gen_userrole(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_ROLETYPE) { - rc = cil_gen_roletype(db, parse_current, new_ast_node); + rc = cil_gen_roletype(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_ROLETRANSITION) { - rc = cil_gen_roletransition(parse_current, new_ast_node); + rc = cil_gen_roletransition(parse_current, ast_node); } else if (parse_current->data == CIL_KEY_ROLEALLOW) { - rc = cil_gen_roleallow(db, parse_current, new_ast_node); + rc = cil_gen_roleallow(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_ROLEATTRIBUTE) { - rc = cil_gen_roleattribute(db, parse_current, new_ast_node); + rc = cil_gen_roleattribute(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_ROLEATTRIBUTESET) { - rc = cil_gen_roleattributeset(db, parse_current, new_ast_node); + rc = cil_gen_roleattributeset(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_ROLEBOUNDS) { - rc = cil_gen_bounds(db, parse_current, new_ast_node, CIL_ROLE); + rc = cil_gen_bounds(db, parse_current, ast_node, CIL_ROLE); } else if (parse_current->data == CIL_KEY_BOOL) { - rc = cil_gen_bool(db, parse_current, new_ast_node, CIL_FALSE); + rc = cil_gen_bool(db, parse_current, ast_node, CIL_FALSE); } else if (parse_current->data == CIL_KEY_BOOLEANIF) { - rc = cil_gen_boolif(db, parse_current, new_ast_node, CIL_FALSE); + rc = cil_gen_boolif(db, parse_current, ast_node, CIL_FALSE); } else if(parse_current->data == CIL_KEY_TUNABLE) { if (db->preserve_tunables) { - rc = cil_gen_bool(db, parse_current, new_ast_node, CIL_TRUE); + rc = cil_gen_bool(db, parse_current, ast_node, CIL_TRUE); } else { - rc = cil_gen_tunable(db, parse_current, new_ast_node); + rc = cil_gen_tunable(db, parse_current, ast_node); } } else if (parse_current->data == CIL_KEY_TUNABLEIF) { if (db->preserve_tunables) { - rc = cil_gen_boolif(db, parse_current, new_ast_node, CIL_TRUE); + rc = cil_gen_boolif(db, parse_current, ast_node, CIL_TRUE); } else { - rc = cil_gen_tunif(db, parse_current, new_ast_node); + rc = cil_gen_tunif(db, parse_current, ast_node); } } else if (parse_current->data == CIL_KEY_CONDTRUE) { - rc = cil_gen_condblock(db, parse_current, new_ast_node, CIL_CONDTRUE); + rc = cil_gen_condblock(db, parse_current, ast_node, CIL_CONDTRUE); } else if (parse_current->data == CIL_KEY_CONDFALSE) { - rc = cil_gen_condblock(db, parse_current, new_ast_node, CIL_CONDFALSE); + rc = cil_gen_condblock(db, parse_current, ast_node, CIL_CONDFALSE); } else if (parse_current->data == CIL_KEY_ALLOW) { - rc = cil_gen_avrule(parse_current, new_ast_node, CIL_AVRULE_ALLOWED); + rc = cil_gen_avrule(parse_current, ast_node, CIL_AVRULE_ALLOWED); + // So that the object and perms lists do not get parsed again + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_AUDITALLOW) { - rc = cil_gen_avrule(parse_current, new_ast_node, CIL_AVRULE_AUDITALLOW); + rc = cil_gen_avrule(parse_current, ast_node, CIL_AVRULE_AUDITALLOW); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_DONTAUDIT) { - rc = cil_gen_avrule(parse_current, new_ast_node, CIL_AVRULE_DONTAUDIT); + rc = cil_gen_avrule(parse_current, ast_node, CIL_AVRULE_DONTAUDIT); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_NEVERALLOW) { - rc = cil_gen_avrule(parse_current, new_ast_node, CIL_AVRULE_NEVERALLOW); + rc = cil_gen_avrule(parse_current, ast_node, CIL_AVRULE_NEVERALLOW); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_ALLOWX) { - rc = cil_gen_avrulex(parse_current, new_ast_node, CIL_AVRULE_ALLOWED); + rc = cil_gen_avrulex(parse_current, ast_node, CIL_AVRULE_ALLOWED); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_AUDITALLOWX) { - rc = cil_gen_avrulex(parse_current, new_ast_node, CIL_AVRULE_AUDITALLOW); + rc = cil_gen_avrulex(parse_current, ast_node, CIL_AVRULE_AUDITALLOW); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_DONTAUDITX) { - rc = cil_gen_avrulex(parse_current, new_ast_node, CIL_AVRULE_DONTAUDIT); + rc = cil_gen_avrulex(parse_current, ast_node, CIL_AVRULE_DONTAUDIT); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_NEVERALLOWX) { - rc = cil_gen_avrulex(parse_current, new_ast_node, CIL_AVRULE_NEVERALLOW); + rc = cil_gen_avrulex(parse_current, ast_node, CIL_AVRULE_NEVERALLOW); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_PERMISSIONX) { - rc = cil_gen_permissionx(db, parse_current, new_ast_node); + rc = cil_gen_permissionx(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_TYPETRANSITION) { - rc = cil_gen_typetransition(db, parse_current, new_ast_node); + rc = cil_gen_typetransition(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_TYPECHANGE) { - rc = cil_gen_type_rule(parse_current, new_ast_node, CIL_TYPE_CHANGE); + rc = cil_gen_type_rule(parse_current, ast_node, CIL_TYPE_CHANGE); } else if (parse_current->data == CIL_KEY_TYPEMEMBER) { - rc = cil_gen_type_rule(parse_current, new_ast_node, CIL_TYPE_MEMBER); + rc = cil_gen_type_rule(parse_current, ast_node, CIL_TYPE_MEMBER); } else if (parse_current->data == CIL_KEY_SENSITIVITY) { - rc = cil_gen_sensitivity(db, parse_current, new_ast_node); + rc = cil_gen_sensitivity(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_SENSALIAS) { - rc = cil_gen_alias(db, parse_current, new_ast_node, CIL_SENSALIAS); + rc = cil_gen_alias(db, parse_current, ast_node, CIL_SENSALIAS); } else if (parse_current->data == CIL_KEY_SENSALIASACTUAL) { - rc = cil_gen_aliasactual(db, parse_current, new_ast_node, CIL_SENSALIASACTUAL); + rc = cil_gen_aliasactual(db, parse_current, ast_node, CIL_SENSALIASACTUAL); } else if (parse_current->data == CIL_KEY_CATEGORY) { - rc = cil_gen_category(db, parse_current, new_ast_node); + rc = cil_gen_category(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_CATALIAS) { - rc = cil_gen_alias(db, parse_current, new_ast_node, CIL_CATALIAS); + rc = cil_gen_alias(db, parse_current, ast_node, CIL_CATALIAS); } else if (parse_current->data == CIL_KEY_CATALIASACTUAL) { - rc = cil_gen_aliasactual(db, parse_current, new_ast_node, CIL_CATALIASACTUAL); + rc = cil_gen_aliasactual(db, parse_current, ast_node, CIL_CATALIASACTUAL); } else if (parse_current->data == CIL_KEY_CATSET) { - rc = cil_gen_catset(db, parse_current, new_ast_node); + rc = cil_gen_catset(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_CATORDER) { - rc = cil_gen_catorder(db, parse_current, new_ast_node); + rc = cil_gen_catorder(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_SENSITIVITYORDER) { - rc = cil_gen_sensitivityorder(db, parse_current, new_ast_node); + rc = cil_gen_sensitivityorder(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_SENSCAT) { - rc = cil_gen_senscat(db, parse_current, new_ast_node); + rc = cil_gen_senscat(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_LEVEL) { - rc = cil_gen_level(db, parse_current, new_ast_node); + rc = cil_gen_level(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_LEVELRANGE) { - rc = cil_gen_levelrange(db, parse_current, new_ast_node); + rc = cil_gen_levelrange(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_CONSTRAIN) { - rc = cil_gen_constrain(db, parse_current, new_ast_node, CIL_CONSTRAIN); + rc = cil_gen_constrain(db, parse_current, ast_node, CIL_CONSTRAIN); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_MLSCONSTRAIN) { - rc = cil_gen_constrain(db, parse_current, new_ast_node, CIL_MLSCONSTRAIN); + rc = cil_gen_constrain(db, parse_current, ast_node, CIL_MLSCONSTRAIN); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_VALIDATETRANS) { - rc = cil_gen_validatetrans(db, parse_current, new_ast_node, CIL_VALIDATETRANS); + rc = cil_gen_validatetrans(db, parse_current, ast_node, CIL_VALIDATETRANS); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_MLSVALIDATETRANS) { - rc = cil_gen_validatetrans(db, parse_current, new_ast_node, CIL_MLSVALIDATETRANS); + rc = cil_gen_validatetrans(db, parse_current, ast_node, CIL_MLSVALIDATETRANS); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_CONTEXT) { - rc = cil_gen_context(db, parse_current, new_ast_node); + rc = cil_gen_context(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_FILECON) { - rc = cil_gen_filecon(db, parse_current, new_ast_node); + rc = cil_gen_filecon(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_IBPKEYCON) { - rc = cil_gen_ibpkeycon(db, parse_current, new_ast_node); + rc = cil_gen_ibpkeycon(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_IBENDPORTCON) { - rc = cil_gen_ibendportcon(db, parse_current, new_ast_node); + rc = cil_gen_ibendportcon(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_PORTCON) { - rc = cil_gen_portcon(db, parse_current, new_ast_node); + rc = cil_gen_portcon(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_NODECON) { - rc = cil_gen_nodecon(db, parse_current, new_ast_node); + rc = cil_gen_nodecon(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_GENFSCON) { - rc = cil_gen_genfscon(db, parse_current, new_ast_node); + rc = cil_gen_genfscon(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_NETIFCON) { - rc = cil_gen_netifcon(db, parse_current, new_ast_node); + rc = cil_gen_netifcon(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_PIRQCON) { - rc = cil_gen_pirqcon(db, parse_current, new_ast_node); + rc = cil_gen_pirqcon(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_IOMEMCON) { - rc = cil_gen_iomemcon(db, parse_current, new_ast_node); + rc = cil_gen_iomemcon(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_IOPORTCON) { - rc = cil_gen_ioportcon(db, parse_current, new_ast_node); + rc = cil_gen_ioportcon(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_PCIDEVICECON) { - rc = cil_gen_pcidevicecon(db, parse_current, new_ast_node); + rc = cil_gen_pcidevicecon(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_DEVICETREECON) { - rc = cil_gen_devicetreecon(db, parse_current, new_ast_node); + rc = cil_gen_devicetreecon(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_FSUSE) { - rc = cil_gen_fsuse(db, parse_current, new_ast_node); + rc = cil_gen_fsuse(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_MACRO) { - rc = cil_gen_macro(db, parse_current, new_ast_node); + rc = cil_gen_macro(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_CALL) { - rc = cil_gen_call(db, parse_current, new_ast_node); + rc = cil_gen_call(db, parse_current, ast_node); + *finished = 1; } else if (parse_current->data == CIL_KEY_POLICYCAP) { - rc = cil_gen_policycap(db, parse_current, new_ast_node); + rc = cil_gen_policycap(db, parse_current, ast_node); + *finished = 1; } else if (parse_current->data == CIL_KEY_OPTIONAL) { - rc = cil_gen_optional(db, parse_current, new_ast_node); + rc = cil_gen_optional(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_IPADDR) { - rc = cil_gen_ipaddr(db, parse_current, new_ast_node); + rc = cil_gen_ipaddr(db, parse_current, ast_node); } else if (parse_current->data == CIL_KEY_DEFAULTUSER) { - rc = cil_gen_default(parse_current, new_ast_node, CIL_DEFAULTUSER); + rc = cil_gen_default(parse_current, ast_node, CIL_DEFAULTUSER); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_DEFAULTROLE) { - rc = cil_gen_default(parse_current, new_ast_node, CIL_DEFAULTROLE); + rc = cil_gen_default(parse_current, ast_node, CIL_DEFAULTROLE); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_DEFAULTTYPE) { - rc = cil_gen_default(parse_current, new_ast_node, CIL_DEFAULTTYPE); + rc = cil_gen_default(parse_current, ast_node, CIL_DEFAULTTYPE); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_DEFAULTRANGE) { - rc = cil_gen_defaultrange(parse_current, new_ast_node); + rc = cil_gen_defaultrange(parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_HANDLEUNKNOWN) { - rc = cil_gen_handleunknown(parse_current, new_ast_node); + rc = cil_gen_handleunknown(parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_MLS) { - rc = cil_gen_mls(parse_current, new_ast_node); + rc = cil_gen_mls(parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_SRC_INFO) { - rc = cil_gen_src_info(parse_current, new_ast_node); + rc = cil_gen_src_info(parse_current, ast_node); } else { cil_log(CIL_ERR, "Error: Unknown keyword %s\n", (char *)parse_current->data); rc = SEPOL_ERR; } if (rc == SEPOL_OK) { - if (ast_parent->cl_head == NULL) { - ast_parent->cl_head = new_ast_node; + if (ast_current->cl_head == NULL) { + if (ast_current->flavor == CIL_MACRO) { + args->macro = ast_current; + } + + if (ast_current->flavor == CIL_BOOLEANIF) { + args->boolif = ast_current; + } + + if (ast_current->flavor == CIL_TUNABLEIF) { + args->tunif = ast_current; + } + + if (ast_current->flavor == CIL_IN) { + args->in = ast_current; + } + + ast_current->cl_head = ast_node; } else { - ast_parent->cl_tail->next = new_ast_node; + ast_current->cl_tail->next = ast_node; } - ast_parent->cl_tail = new_ast_node; + ast_current->cl_tail = ast_node; + ast_current = ast_node; + args->ast = ast_current; } else { - cil_tree_node_destroy(&new_ast_node); - new_ast_node = NULL; + cil_tree_node_destroy(&ast_node); } - return new_ast_node; -} - -int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *finished, void *extra_args) -{ - struct cil_args_build *args = extra_args; - struct cil_tree_node *new_ast_node = NULL; - int rc = SEPOL_ERR; - - if (parse_current->parent->cl_head != parse_current) { - /* ignore anything that isn't following a parenthesis */ - return SEPOL_OK; - } else if (parse_current->data == NULL) { - /* the only time parenthesis can immediately following parenthesis is if - * the parent is the root node */ - if (parse_current->parent->parent == NULL) { - return SEPOL_OK; - } else { - cil_tree_log(parse_current, CIL_ERR, "Keyword expected after open parenthesis"); - return SEPOL_ERR; - } - } - - rc = check_for_illegal_statement(parse_current, args); - if (rc != SEPOL_OK) { - return SEPOL_ERR; - } - - new_ast_node = parse_statement(args->db, parse_current, args->ast); - if (!new_ast_node) { - return SEPOL_ERR; - } - - args->ast = new_ast_node; - - if (parse_current->data != CIL_KEY_BLOCK && - parse_current->data != CIL_KEY_IN && - parse_current->data != CIL_KEY_TUNABLEIF && - parse_current->data != CIL_KEY_BOOLEANIF && - parse_current->data != CIL_KEY_CONDTRUE && - parse_current->data != CIL_KEY_CONDFALSE && - parse_current->data != CIL_KEY_MACRO && - parse_current->data != CIL_KEY_OPTIONAL && - parse_current->data != CIL_KEY_SRC_INFO) { - /* Skip anything that does not contain a list of policy statements */ - *finished = CIL_TREE_SKIP_NEXT; - } - - return SEPOL_OK; -} - -int __cil_build_ast_first_child_helper(__attribute__((unused)) struct cil_tree_node *parse_current, void *extra_args) -{ - struct cil_args_build *args = extra_args; - struct cil_tree_node *ast = args->ast; - - if (ast->flavor == CIL_TUNABLEIF) { - args->tunif = ast; - } else if (ast->flavor == CIL_IN) { - args->in = ast; - } else if (ast->flavor == CIL_MACRO) { - args->macro = ast; - } else if (ast->flavor == CIL_OPTIONAL) { - args->optional = ast; - } else if (ast->flavor == CIL_BOOLEANIF) { - args->boolif = ast; - } - - return SEPOL_OK; +exit: + return rc; } int __cil_build_ast_last_child_helper(struct cil_tree_node *parse_current, void *extra_args) { - struct cil_args_build *args = extra_args; - struct cil_tree_node *ast = args->ast; + int rc = SEPOL_ERR; + struct cil_tree_node *ast = NULL; + struct cil_args_build *args = NULL; + + if (extra_args == NULL) { + goto exit; + } + + args = extra_args; + ast = args->ast; if (ast->flavor == CIL_ROOT) { - return SEPOL_OK; + rc = SEPOL_OK; + goto exit; } args->ast = ast->parent; + if (ast->flavor == CIL_MACRO) { + args->macro = NULL; + } + + if (ast->flavor == CIL_BOOLEANIF) { + args->boolif = NULL; + } + if (ast->flavor == CIL_TUNABLEIF) { args->tunif = NULL; } @@ -6513,27 +6541,6 @@ int __cil_build_ast_last_child_helper(struct cil_tree_node *parse_current, void args->in = NULL; } - if (ast->flavor == CIL_MACRO) { - args->macro = NULL; - } - - if (ast->flavor == CIL_OPTIONAL) { - struct cil_tree_node *n = ast->parent; - args->optional = NULL; - /* Optionals can be nested */ - while (n && n->flavor != CIL_ROOT) { - if (n->flavor == CIL_OPTIONAL) { - args->optional = n; - break; - } - n = n->parent; - } - } - - if (ast->flavor == CIL_BOOLEANIF) { - args->boolif = NULL; - } - // At this point we no longer have any need for parse_current or any of its // siblings; they have all been converted to the appropriate AST node. The // full parse tree will get deleted elsewhere, but in an attempt to @@ -6542,6 +6549,9 @@ int __cil_build_ast_last_child_helper(struct cil_tree_node *parse_current, void cil_tree_children_destroy(parse_current->parent); return SEPOL_OK; + +exit: + return rc; } int cil_build_ast(struct cil_db *db, struct cil_tree_node *parse_tree, struct cil_tree_node *ast) @@ -6555,13 +6565,12 @@ int cil_build_ast(struct cil_db *db, struct cil_tree_node *parse_tree, struct ci extra_args.ast = ast; extra_args.db = db; + extra_args.macro = NULL; + extra_args.boolif = NULL; extra_args.tunif = NULL; extra_args.in = NULL; - extra_args.macro = NULL; - extra_args.optional = NULL; - extra_args.boolif = NULL; - rc = cil_tree_walk(parse_tree, __cil_build_ast_node_helper, __cil_build_ast_first_child_helper, __cil_build_ast_last_child_helper, &extra_args); + rc = cil_tree_walk(parse_tree, __cil_build_ast_node_helper, NULL, __cil_build_ast_last_child_helper, &extra_args); if (rc != SEPOL_OK) { goto exit; } diff --git a/libsepol/cil/src/cil_build_ast.h b/libsepol/cil/src/cil_build_ast.h index fd9053ce..8153e51e 100644 --- a/libsepol/cil/src/cil_build_ast.h +++ b/libsepol/cil/src/cil_build_ast.h @@ -37,8 +37,6 @@ #include "cil_tree.h" #include "cil_list.h" -int cil_add_decl_to_symtab(struct cil_db *db, symtab_t *symtab, hashtab_key_t key, struct cil_symtab_datum *datum, struct cil_tree_node *node); - int cil_gen_node(struct cil_db *db, struct cil_tree_node *ast_node, struct cil_symtab_datum *datum, hashtab_key_t key, enum cil_sym_index sflavor, enum cil_flavor nflavor); int cil_parse_to_list(struct cil_tree_node *parse_cl_head, struct cil_list *ast_cl, enum cil_flavor flavor); diff --git a/libsepol/cil/src/cil_copy_ast.c b/libsepol/cil/src/cil_copy_ast.c index cdbc84e7..67dd8528 100644 --- a/libsepol/cil/src/cil_copy_ast.c +++ b/libsepol/cil/src/cil_copy_ast.c @@ -40,10 +40,8 @@ #include "cil_copy_ast.h" #include "cil_build_ast.h" #include "cil_strpool.h" -#include "cil_verify.h" struct cil_args_copy { - struct cil_tree_node *orig_dest; struct cil_tree_node *dest; struct cil_db *db; }; @@ -104,19 +102,12 @@ int cil_copy_block(__attribute__((unused)) struct cil_db *db, void *data, void * struct cil_symtab_datum *datum = NULL; cil_symtab_get_datum(symtab, key, &datum); - if (datum != NULL) { - if (FLAVOR(datum) != CIL_BLOCK) { - cil_tree_log(NODE(orig), CIL_ERR, "Block %s being copied", key); - cil_tree_log(NODE(datum), CIL_ERR, " Conflicts with %s already declared", cil_node_to_string(NODE(datum))); - return SEPOL_ERR; - } - cil_tree_log(NODE(orig), CIL_WARN, "Block %s being copied", key); - cil_tree_log(NODE(datum), CIL_WARN, " Previously declared"); - *copy = datum; - } else { + if (datum == NULL) { struct cil_block *new; cil_block_init(&new); *copy = new; + } else { + *copy = datum;; } return SEPOL_OK; @@ -662,6 +653,7 @@ int cil_copy_expandtypeattribute(__attribute__((unused)) struct cil_db *db, void struct cil_expandtypeattribute *orig = data; struct cil_expandtypeattribute *new = NULL; + fprintf(stderr, "%s %u\n", __func__, __LINE__); cil_expandtypeattribute_init(&new); if (orig->attr_strs != NULL) { @@ -1520,33 +1512,78 @@ int cil_copy_macro(__attribute__((unused)) struct cil_db *db, void *data, void * struct cil_symtab_datum *datum = NULL; cil_symtab_get_datum(symtab, key, &datum); - if (datum != NULL) { - if (FLAVOR(datum) != CIL_MACRO) { - cil_tree_log(NODE(orig), CIL_ERR, "Macro %s being copied", key); - cil_tree_log(NODE(datum), CIL_ERR, " Conflicts with %s already declared", cil_node_to_string(NODE(datum))); - return SEPOL_ERR; - } - cil_tree_log(NODE(orig), CIL_WARN, "Skipping macro %s", key); - cil_tree_log(NODE(datum), CIL_WARN, " Previously declared"); - *copy = NULL; - } else { + if (datum == NULL) { struct cil_macro *new; cil_macro_init(&new); if (orig->params != NULL) { cil_copy_list(orig->params, &new->params); } + *copy = new; + + } else { + struct cil_list_item *curr_orig = NULL; + struct cil_list_item *curr_new = NULL; + struct cil_param *param_orig = NULL; + struct cil_param *param_new = NULL; + + if (((struct cil_macro*)datum)->params != NULL) { + curr_new = ((struct cil_macro*)datum)->params->head; + } + + if (orig->params != NULL) { + curr_orig = orig->params->head; + } + + if (curr_orig != NULL && curr_new != NULL) { + while (curr_orig != NULL) { + if (curr_new == NULL) { + goto exit; + } + + param_orig = (struct cil_param*)curr_orig->data; + param_new = (struct cil_param*)curr_new->data; + if (param_orig->str != param_new->str) { + goto exit; + } else if (param_orig->flavor != param_new->flavor) { + goto exit; + } + + curr_orig = curr_orig->next; + curr_new = curr_new->next; + } + + if (curr_new != NULL) { + goto exit; + } + } else if (!(curr_orig == NULL && curr_new == NULL)) { + goto exit; + } + + *copy = datum; } return SEPOL_OK; + +exit: + cil_log(CIL_INFO, "cil_copy_macro: macro cannot be redefined\n"); + return SEPOL_ERR; } -int cil_copy_optional(__attribute__((unused)) struct cil_db *db, __attribute__((unused)) void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +int cil_copy_optional(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab) { - struct cil_optional *new; + struct cil_optional *orig = data; + char *key = orig->datum.name; + struct cil_symtab_datum *datum = NULL; - cil_optional_init(&new); - *copy = new; + cil_symtab_get_datum(symtab, key, &datum); + if (datum == NULL) { + struct cil_optional *new; + cil_optional_init(&new); + *copy = new; + } else { + *copy = datum; + } return SEPOL_OK; } @@ -1704,8 +1741,7 @@ int cil_copy_src_info(__attribute__((unused)) struct cil_db *db, void *data, voi cil_src_info_init(&new); - new->kind = orig->kind; - new->hll_line = orig->hll_line; + new->is_cil = orig->is_cil; new->path = orig->path; *copy = new; @@ -1713,7 +1749,7 @@ int cil_copy_src_info(__attribute__((unused)) struct cil_db *db, void *data, voi return SEPOL_OK; } -int __cil_copy_node_helper(struct cil_tree_node *orig, uint32_t *finished, void *extra_args) +int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) uint32_t *finished, void *extra_args) { int rc = SEPOL_ERR; struct cil_tree_node *parent = NULL; @@ -1721,6 +1757,7 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, uint32_t *finished, void struct cil_db *db = NULL; struct cil_args_copy *args = NULL; struct cil_tree_node *namespace = NULL; + struct cil_param *param = NULL; enum cil_sym_index sym_index = CIL_SYM_UNKNOWN; symtab_t *symtab = NULL; void *data = NULL; @@ -2018,33 +2055,15 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, uint32_t *finished, void rc = (*copy_func)(db, orig->data, &data, symtab); if (rc == SEPOL_OK) { - if (orig->flavor == CIL_MACRO && data == NULL) { - /* Skipping macro re-declaration */ - if (args->orig_dest->flavor != CIL_BLOCKINHERIT) { - cil_log(CIL_ERR, " Re-declaration of macro is only allowed when inheriting a block\n"); - return SEPOL_ERR; - } - *finished = CIL_TREE_SKIP_HEAD; - return SEPOL_OK; - } - cil_tree_node_init(&new); new->parent = parent; new->line = orig->line; - new->hll_offset = orig->hll_offset; + new->hll_line = orig->hll_line; new->flavor = orig->flavor; new->data = data; - if (orig->flavor == CIL_BLOCK && DATUM(data)->nodes->head != NULL) { - /* Duplicate block */ - if (args->orig_dest->flavor != CIL_BLOCKINHERIT) { - cil_log(CIL_ERR, " Re-declaration of block is only allowed when inheriting a block\n"); - rc = SEPOL_ERR; - goto exit; - } - cil_list_append(DATUM(new->data)->nodes, CIL_NODE, new); - } else if (orig->flavor >= CIL_MIN_DECLARATIVE) { + if (orig->flavor >= CIL_MIN_DECLARATIVE) { /* Check the flavor of data if was found in the destination symtab */ if (DATUM(data)->nodes->head && FLAVOR(data) != orig->flavor) { cil_tree_log(orig, CIL_ERR, "Incompatible flavor when trying to copy %s", DATUM(data)->name); @@ -2053,11 +2072,7 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, uint32_t *finished, void rc = SEPOL_ERR; goto exit; } - - rc = cil_add_decl_to_symtab(db, symtab, DATUM(orig->data)->name, DATUM(data), new); - if (rc != SEPOL_OK) { - goto exit; - } + rc = cil_symtab_insert(symtab, ((struct cil_symtab_datum*)orig->data)->name, ((struct cil_symtab_datum*)data), new); namespace = new; while (namespace->flavor != CIL_MACRO && namespace->flavor != CIL_BLOCK && namespace->flavor != CIL_ROOT) { @@ -2065,9 +2080,21 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, uint32_t *finished, void } if (namespace->flavor == CIL_MACRO) { - rc = cil_verify_decl_does_not_shadow_macro_parameter(namespace->data, orig, DATUM(orig->data)->name); - if (rc != SEPOL_OK) { - goto exit; + struct cil_macro *macro = namespace->data; + struct cil_list *param_list = macro->params; + if (param_list != NULL) { + struct cil_list_item *item; + cil_list_for_each(item, param_list) { + param = item->data; + if (param->flavor == new->flavor) { + if (param->str == ((struct cil_symtab_datum*)new->data)->name) { + cil_tree_log(orig, CIL_ERR, "%s %s shadows a macro parameter", cil_node_to_string(new), ((struct cil_symtab_datum*)orig->data)->name); + cil_tree_log(namespace, CIL_ERR, "Note: macro declaration"); + rc = SEPOL_ERR; + goto exit; + } + } + } } } } @@ -2096,7 +2123,6 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, uint32_t *finished, void args->dest = new; } } else { - cil_tree_log(orig, CIL_ERR, "Problem copying %s node", cil_node_to_string(orig)); goto exit; } @@ -2129,13 +2155,12 @@ int cil_copy_ast(struct cil_db *db, struct cil_tree_node *orig, struct cil_tree_ int rc = SEPOL_ERR; struct cil_args_copy extra_args; - extra_args.orig_dest = dest; extra_args.dest = dest; extra_args.db = db; rc = cil_tree_walk(orig, __cil_copy_node_helper, NULL, __cil_copy_last_child_helper, &extra_args); if (rc != SEPOL_OK) { - cil_tree_log(dest, CIL_ERR, "Failed to copy %s to %s", cil_node_to_string(orig), cil_node_to_string(dest)); + cil_log(CIL_INFO, "cil_tree_walk failed, rc: %d\n", rc); goto exit; } diff --git a/libsepol/cil/src/cil_find.c b/libsepol/cil/src/cil_find.c index 3898725f..41342424 100644 --- a/libsepol/cil/src/cil_find.c +++ b/libsepol/cil/src/cil_find.c @@ -30,7 +30,6 @@ #include #include "cil_internal.h" -#include "cil_find.h" #include "cil_flavor.h" #include "cil_list.h" #include "cil_log.h" @@ -45,8 +44,8 @@ struct cil_args_find { static int cil_type_match_any(struct cil_symtab_datum *d1, struct cil_symtab_datum *d2) { - enum cil_flavor f1 = FLAVOR(d1); - enum cil_flavor f2 = FLAVOR(d2); + enum cil_flavor f1 = ((struct cil_tree_node*)d1->nodes->head->data)->flavor; + enum cil_flavor f2 = ((struct cil_tree_node*)d2->nodes->head->data)->flavor; if (f1 != CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) { struct cil_type *t1 = (struct cil_type *)d1; @@ -82,8 +81,8 @@ static int cil_type_match_any(struct cil_symtab_datum *d1, struct cil_symtab_dat static int cil_type_matches(ebitmap_t *matches, struct cil_symtab_datum *d1, struct cil_symtab_datum *d2) { int rc = SEPOL_OK; - enum cil_flavor f1 = FLAVOR(d1); - enum cil_flavor f2 = FLAVOR(d2); + enum cil_flavor f1 = ((struct cil_tree_node*)d1->nodes->head->data)->flavor; + enum cil_flavor f2 = ((struct cil_tree_node*)d2->nodes->head->data)->flavor; if (f1 != CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) { struct cil_type *t1 = (struct cil_type *)d1; @@ -119,7 +118,7 @@ static int cil_type_matches(ebitmap_t *matches, struct cil_symtab_datum *d1, str static int cil_self_match_any(struct cil_symtab_datum *s1, struct cil_symtab_datum *s2, struct cil_symtab_datum *t2) { int rc; - struct cil_tree_node *n1 = NODE(s1); + struct cil_tree_node *n1 = s1->nodes->head->data; if (n1->flavor != CIL_TYPEATTRIBUTE) { rc = cil_type_match_any(s1, t2); } else { diff --git a/libsepol/cil/src/cil_fqn.c b/libsepol/cil/src/cil_fqn.c index 46db069b..2e76f873 100644 --- a/libsepol/cil/src/cil_fqn.c +++ b/libsepol/cil/src/cil_fqn.c @@ -31,7 +31,6 @@ #include #include -#include "cil_fqn.h" #include "cil_internal.h" #include "cil_log.h" #include "cil_strpool.h" @@ -78,13 +77,12 @@ static int __cil_fqn_qualify_blocks(__attribute__((unused)) hashtab_key_t k, has struct cil_tree_node *node = NODE(datum); int i; int rc = SEPOL_OK; - int newlen; if (node->flavor != CIL_BLOCK) { goto exit; } - newlen = fqn_args->len + strlen(datum->name) + 1; + int newlen = fqn_args->len + strlen(datum->name) + 1; if (newlen >= CIL_MAX_NAME_LENGTH) { cil_log(CIL_INFO, "Fully qualified name for block %s is too long\n", datum->name); rc = SEPOL_ERR; diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h index 6f1d3cb5..9bdcbdd0 100644 --- a/libsepol/cil/src/cil_internal.h +++ b/libsepol/cil/src/cil_internal.h @@ -48,19 +48,16 @@ #define CIL_MAX_NAME_LENGTH 2048 -#define CIL_DEGENERATE_INHERITANCE_DEPTH 10UL -#define CIL_DEGENERATE_INHERITANCE_MINIMUM (0x01 << CIL_DEGENERATE_INHERITANCE_DEPTH) -#define CIL_DEGENERATE_INHERITANCE_GROWTH 10UL enum cil_pass { CIL_PASS_INIT = 0, CIL_PASS_TIF, - CIL_PASS_IN_BEFORE, + CIL_PASS_IN, CIL_PASS_BLKIN_LINK, CIL_PASS_BLKIN_COPY, CIL_PASS_BLKABS, - CIL_PASS_IN_AFTER, + CIL_PASS_MACRO, CIL_PASS_CALL1, CIL_PASS_CALL2, CIL_PASS_ALIAS1, @@ -159,8 +156,6 @@ extern char *CIL_KEY_HANDLEUNKNOWN_DENY; extern char *CIL_KEY_HANDLEUNKNOWN_REJECT; extern char *CIL_KEY_MACRO; extern char *CIL_KEY_IN; -extern char *CIL_KEY_IN_BEFORE; -extern char *CIL_KEY_IN_AFTER; extern char *CIL_KEY_MLS; extern char *CIL_KEY_DEFAULTRANGE; extern char *CIL_KEY_BLOCKINHERIT; @@ -239,9 +234,7 @@ extern char *CIL_KEY_IOCTL; extern char *CIL_KEY_UNORDERED; extern char *CIL_KEY_SRC_INFO; extern char *CIL_KEY_SRC_CIL; -extern char *CIL_KEY_SRC_HLL_LMS; -extern char *CIL_KEY_SRC_HLL_LMX; -extern char *CIL_KEY_SRC_HLL_LME; +extern char *CIL_KEY_SRC_HLL; /* Symbol Table Array Indices @@ -280,7 +273,7 @@ enum cil_sym_array { CIL_SYM_ARRAY_NUM }; -extern const int cil_sym_sizes[CIL_SYM_ARRAY_NUM][CIL_SYM_NUM]; +extern int cil_sym_sizes[CIL_SYM_ARRAY_NUM][CIL_SYM_NUM]; #define CIL_CLASS_SYM_SIZE 256 #define CIL_PERMS_PER_CLASS (sizeof(sepol_access_vector_t) * 8) @@ -326,7 +319,6 @@ struct cil_db { int handle_unknown; int mls; int multiple_decls; - int qualified_names; int target_platform; int policy_version; }; @@ -360,12 +352,12 @@ struct cil_blockabstract { struct cil_in { symtab_t symtab[CIL_SYM_NUM]; - int is_after; char *block_str; }; struct cil_optional { struct cil_symtab_datum datum; + int enabled; }; struct cil_perm { @@ -969,8 +961,7 @@ struct cil_mls { }; struct cil_src_info { - char *kind; - uint32_t hll_line; + int is_cil; char *path; }; @@ -989,12 +980,10 @@ int cil_userprefixes_to_string(struct cil_db *db, char **out, size_t *size); int cil_selinuxusers_to_string(struct cil_db *db, char **out, size_t *size); int cil_filecons_to_string(struct cil_db *db, char **out, size_t *size); -void cil_symtab_array_init(symtab_t symtab[], const int symtab_sizes[CIL_SYM_NUM]); +void cil_symtab_array_init(symtab_t symtab[], int symtab_sizes[CIL_SYM_NUM]); void cil_symtab_array_destroy(symtab_t symtab[]); void cil_destroy_ast_symtabs(struct cil_tree_node *root); int cil_get_symtab(struct cil_tree_node *ast_node, symtab_t **symtab, enum cil_sym_index sym_index); -int cil_string_to_uint32(const char *string, uint32_t *value, int base); -int cil_string_to_uint64(const char *string, uint64_t *value, int base); void cil_sort_init(struct cil_sort **sort); void cil_sort_destroy(struct cil_sort **sort); diff --git a/libsepol/cil/src/cil_lexer.l b/libsepol/cil/src/cil_lexer.l index 8bf2b6e7..e28c33ec 100644 --- a/libsepol/cil/src/cil_lexer.l +++ b/libsepol/cil/src/cil_lexer.l @@ -49,7 +49,7 @@ spec_char [\[\]\.\@\=\/\*\-\_\$\%\+\-\!\|\&\^\:\~\`\#\{\}\'\<\>\?\,] symbol ({digit}|{alpha}|{spec_char})+ white [ \t] newline [\n\r] -qstring \"[^"\n\0]*\" +qstring \"[^"\n]*\" hll_lm ^;;\* comment ; diff --git a/libsepol/cil/src/cil_list.c b/libsepol/cil/src/cil_list.c index 8a426f1f..4e7843cb 100644 --- a/libsepol/cil/src/cil_list.c +++ b/libsepol/cil/src/cil_list.c @@ -55,16 +55,15 @@ void cil_list_init(struct cil_list **list, enum cil_flavor flavor) void cil_list_destroy(struct cil_list **list, unsigned destroy_data) { - struct cil_list_item *item; - if (*list == NULL) { return; } - item = (*list)->head; + struct cil_list_item *item = (*list)->head; + struct cil_list_item *next = NULL; while (item != NULL) { - struct cil_list_item *next = item->next; + next = item->next; if (item->flavor == CIL_LIST) { cil_list_destroy((struct cil_list**)&(item->data), destroy_data); free(item); diff --git a/libsepol/cil/src/cil_log.c b/libsepol/cil/src/cil_log.c index a8e4d2e9..b222b155 100644 --- a/libsepol/cil/src/cil_log.c +++ b/libsepol/cil/src/cil_log.c @@ -37,14 +37,14 @@ static enum cil_log_level cil_log_level = CIL_ERR; -void cil_default_log_handler(__attribute__((unused)) int lvl, const char *msg) +void cil_default_log_handler(__attribute__((unused)) int lvl, char *msg) { fprintf(stderr, "%s", msg); } -void (*cil_log_handler)(int lvl, const char *msg) = &cil_default_log_handler; +void (*cil_log_handler)(int lvl, char *msg) = &cil_default_log_handler; -void cil_set_log_handler(void (*handler)(int lvl, const char *msg)) +void cil_set_log_handler(void (*handler)(int lvl, char *msg)) { cil_log_handler = handler; } diff --git a/libsepol/cil/src/cil_mem.c b/libsepol/cil/src/cil_mem.c index 8e4a1d24..f73021b5 100644 --- a/libsepol/cil/src/cil_mem.c +++ b/libsepol/cil/src/cil_mem.c @@ -33,7 +33,6 @@ #include #include "cil_log.h" -#include "cil_mem.h" void *cil_malloc(size_t size) { diff --git a/libsepol/cil/src/cil_parser.c b/libsepol/cil/src/cil_parser.c index 5375d49a..585ea770 100644 --- a/libsepol/cil/src/cil_parser.c +++ b/libsepol/cil/src/cil_parser.c @@ -38,48 +38,53 @@ #include "cil_mem.h" #include "cil_tree.h" #include "cil_lexer.h" -#include "cil_parser.h" #include "cil_strpool.h" #include "cil_stack.h" -#define CIL_PARSER_MAX_EXPR_DEPTH (0x1 << 12) +char *CIL_KEY_HLL_LMS; +char *CIL_KEY_HLL_LMX; +char *CIL_KEY_HLL_LME; struct hll_info { - uint32_t hll_offset; - uint32_t hll_expand; + int hll_lineno; + int hll_expand; }; -static void push_hll_info(struct cil_stack *stack, uint32_t hll_offset, uint32_t hll_expand) +static void push_hll_info(struct cil_stack *stack, int hll_lineno, int hll_expand) { struct hll_info *new = cil_malloc(sizeof(*new)); - new->hll_offset = hll_offset; + new->hll_lineno = hll_lineno; new->hll_expand = hll_expand; cil_stack_push(stack, CIL_NONE, new); } -static void pop_hll_info(struct cil_stack *stack, uint32_t *hll_offset, uint32_t *hll_expand) +static void pop_hll_info(struct cil_stack *stack, int *hll_lineno, int *hll_expand) { struct cil_stack_item *curr = cil_stack_pop(stack); - struct hll_info *info; + struct cil_stack_item *prev = cil_stack_peek(stack); + struct hll_info *old; - if (!curr) { - return; - } - info = curr->data; - *hll_expand = info->hll_expand; - *hll_offset = info->hll_offset; free(curr->data); + + if (!prev) { + *hll_lineno = -1; + *hll_expand = -1; + } else { + old = prev->data; + *hll_lineno = old->hll_lineno; + *hll_expand = old->hll_expand; + } } -static void create_node(struct cil_tree_node **node, struct cil_tree_node *current, uint32_t line, uint32_t hll_offset, void *value) +static void create_node(struct cil_tree_node **node, struct cil_tree_node *current, int line, int hll_line, void *value) { cil_tree_node_init(node); (*node)->parent = current; (*node)->flavor = CIL_NODE; (*node)->line = line; - (*node)->hll_offset = hll_offset; + (*node)->hll_line = hll_line; (*node)->data = value; } @@ -93,67 +98,55 @@ static void insert_node(struct cil_tree_node *node, struct cil_tree_node *curren current->cl_tail = node; } -static int add_hll_linemark(struct cil_tree_node **current, uint32_t *hll_offset, uint32_t *hll_expand, struct cil_stack *stack, char *path) +static int add_hll_linemark(struct cil_tree_node **current, int *hll_lineno, int *hll_expand, struct cil_stack *stack, char *path) { char *hll_type; struct cil_tree_node *node; struct token tok; - uint32_t prev_hll_expand, prev_hll_offset; + char *hll_file; + char *end = NULL; cil_lexer_next(&tok); - if (tok.type != SYMBOL) { - cil_log(CIL_ERR, "Invalid line mark syntax\n"); - goto exit; - } hll_type = cil_strpool_add(tok.value); - if (hll_type != CIL_KEY_SRC_HLL_LME && hll_type != CIL_KEY_SRC_HLL_LMS && hll_type != CIL_KEY_SRC_HLL_LMX) { - cil_log(CIL_ERR, "Invalid line mark syntax\n"); - goto exit; - } - if (hll_type == CIL_KEY_SRC_HLL_LME) { + if (hll_type == CIL_KEY_HLL_LME) { if (cil_stack_is_empty(stack)) { cil_log(CIL_ERR, "Line mark end without start\n"); goto exit; } - prev_hll_expand = *hll_expand; - prev_hll_offset = *hll_offset; - pop_hll_info(stack, hll_offset, hll_expand); - if (!*hll_expand) { - /* This is needed if not going back to an lmx section. */ - *hll_offset = prev_hll_offset; - } - if (prev_hll_expand && !*hll_expand) { - /* This is needed to count the lme at the end of an lmx section - * within an lms section (or within no hll section). - */ - (*hll_offset)++; - } + pop_hll_info(stack, hll_lineno, hll_expand); *current = (*current)->parent; } else { - push_hll_info(stack, *hll_offset, *hll_expand); - if (cil_stack_number_of_items(stack) > CIL_PARSER_MAX_EXPR_DEPTH) { - cil_log(CIL_ERR, "Number of active line marks exceeds limit of %d\n", CIL_PARSER_MAX_EXPR_DEPTH); - goto exit; - } - - create_node(&node, *current, tok.line, *hll_offset, NULL); + create_node(&node, *current, tok.line, *hll_lineno, NULL); insert_node(node, *current); *current = node; - create_node(&node, *current, tok.line, *hll_offset, CIL_KEY_SRC_INFO); + create_node(&node, *current, tok.line, *hll_lineno, CIL_KEY_SRC_INFO); insert_node(node, *current); - create_node(&node, *current, tok.line, *hll_offset, hll_type); + create_node(&node, *current, tok.line, *hll_lineno, CIL_KEY_SRC_HLL); insert_node(node, *current); + if (hll_type == CIL_KEY_HLL_LMS) { + *hll_expand = 0; + } else if (hll_type == CIL_KEY_HLL_LMX) { + *hll_expand = 1; + } else { + cil_log(CIL_ERR, "Invalid line mark syntax\n"); + goto exit; + } + cil_lexer_next(&tok); if (tok.type != SYMBOL) { cil_log(CIL_ERR, "Invalid line mark syntax\n"); goto exit; } + *hll_lineno = strtol(tok.value, &end, 10); + if (errno == ERANGE || *end != '\0') { + cil_log(CIL_ERR, "Problem parsing line number for line mark\n"); + goto exit; + } - create_node(&node, *current, tok.line, *hll_offset, cil_strpool_add(tok.value)); - insert_node(node, *current); + push_hll_info(stack, *hll_lineno, *hll_expand); cil_lexer_next(&tok); if (tok.type != SYMBOL && tok.type != QSTRING) { @@ -166,10 +159,10 @@ static int add_hll_linemark(struct cil_tree_node **current, uint32_t *hll_offset tok.value = tok.value+1; } - create_node(&node, *current, tok.line, *hll_offset, cil_strpool_add(tok.value)); - insert_node(node, *current); + hll_file = cil_strpool_add(tok.value); - *hll_expand = (hll_type == CIL_KEY_SRC_HLL_LMX) ? 1 : 0; + create_node(&node, *current, tok.line, *hll_lineno, hll_file); + insert_node(node, *current); } cil_lexer_next(&tok); @@ -178,15 +171,10 @@ static int add_hll_linemark(struct cil_tree_node **current, uint32_t *hll_offset goto exit; } - if (!*hll_expand) { - /* Need to increment because of the NEWLINE */ - (*hll_offset)++; - } - return SEPOL_OK; exit: - cil_log(CIL_ERR, "Problem with high-level line mark at line %u of %s\n", tok.line, path); + cil_log(CIL_ERR, "Problem with high-level line mark at line %d of %s\n", tok.line, path); return SEPOL_ERR; } @@ -204,14 +192,11 @@ static void add_cil_path(struct cil_tree_node **current, char *path) create_node(&node, *current, 0, 0, CIL_KEY_SRC_CIL); insert_node(node, *current); - create_node(&node, *current, 0, 0, cil_strpool_add("1")); - insert_node(node, *current); - create_node(&node, *current, 0, 0, path); insert_node(node, *current); } -int cil_parser(const char *_path, char *buffer, uint32_t size, struct cil_tree **parse_tree) +int cil_parser(char *_path, char *buffer, uint32_t size, struct cil_tree **parse_tree) { int paren_count = 0; @@ -221,11 +206,15 @@ int cil_parser(const char *_path, char *buffer, uint32_t size, struct cil_tree * struct cil_tree_node *current = NULL; char *path = cil_strpool_add(_path); struct cil_stack *stack; - uint32_t hll_offset = 1; - uint32_t hll_expand = 0; + int hll_lineno = -1; + int hll_expand = -1; struct token tok; int rc = SEPOL_OK; + CIL_KEY_HLL_LMS = cil_strpool_add("lms"); + CIL_KEY_HLL_LMX = cil_strpool_add("lmx"); + CIL_KEY_HLL_LME = cil_strpool_add("lme"); + cil_stack_init(&stack); cil_lexer_setup(buffer, size); @@ -239,18 +228,15 @@ int cil_parser(const char *_path, char *buffer, uint32_t size, struct cil_tree * cil_lexer_next(&tok); switch (tok.type) { case HLL_LINEMARK: - rc = add_hll_linemark(¤t, &hll_offset, &hll_expand, stack, path); + rc = add_hll_linemark(¤t, &hll_lineno, &hll_expand, stack, path); if (rc != SEPOL_OK) { goto exit; } break; case OPAREN: paren_count++; - if (paren_count > CIL_PARSER_MAX_EXPR_DEPTH) { - cil_log(CIL_ERR, "Number of open parenthesis exceeds limit of %d at line %d of %s\n", CIL_PARSER_MAX_EXPR_DEPTH, tok.line, path); - goto exit; - } - create_node(&node, current, tok.line, hll_offset, NULL); + + create_node(&node, current, tok.line, hll_lineno, NULL); insert_node(node, current); current = node; break; @@ -272,12 +258,12 @@ int cil_parser(const char *_path, char *buffer, uint32_t size, struct cil_tree * goto exit; } - create_node(&node, current, tok.line, hll_offset, cil_strpool_add(tok.value)); + create_node(&node, current, tok.line, hll_lineno, cil_strpool_add(tok.value)); insert_node(node, current); break; case NEWLINE : if (!hll_expand) { - hll_offset++; + hll_lineno++; } break; case COMMENT: @@ -285,7 +271,7 @@ int cil_parser(const char *_path, char *buffer, uint32_t size, struct cil_tree * cil_lexer_next(&tok); } if (!hll_expand) { - hll_offset++; + hll_lineno++; } if (tok.type != END_OF_FILE) { break; @@ -322,9 +308,8 @@ int cil_parser(const char *_path, char *buffer, uint32_t size, struct cil_tree * exit: while (!cil_stack_is_empty(stack)) { - pop_hll_info(stack, &hll_offset, &hll_expand); + pop_hll_info(stack, &hll_lineno, &hll_expand); } - cil_lexer_destroy(); cil_stack_destroy(&stack); return SEPOL_ERR; diff --git a/libsepol/cil/src/cil_parser.h b/libsepol/cil/src/cil_parser.h index 1cec6394..02ecb784 100644 --- a/libsepol/cil/src/cil_parser.h +++ b/libsepol/cil/src/cil_parser.h @@ -32,6 +32,6 @@ #include "cil_tree.h" -int cil_parser(const char *path, char *buffer, uint32_t size, struct cil_tree **parse_tree); +int cil_parser(char *path, char *buffer, uint32_t size, struct cil_tree **parse_tree); #endif /* CIL_PARSER_H_ */ diff --git a/libsepol/cil/src/cil_policy.c b/libsepol/cil/src/cil_policy.c index 7c543c47..06d7d74e 100644 --- a/libsepol/cil/src/cil_policy.c +++ b/libsepol/cil/src/cil_policy.c @@ -41,7 +41,6 @@ #include "cil_flavor.h" #include "cil_find.h" #include "cil_mem.h" -#include "cil_policy.h" #include "cil_tree.h" #include "cil_list.h" #include "cil_symtab.h" @@ -285,7 +284,7 @@ static void cil_cond_expr_to_policy(FILE *out, struct cil_list *expr, int first) struct cil_list_item *i1 = expr->head; if (i1->flavor == CIL_OP) { - enum cil_flavor op = (enum cil_flavor)(uintptr_t)i1->data; + enum cil_flavor op = (enum cil_flavor)i1->data; fprintf(out, "("); switch (op) { case CIL_NOT: @@ -385,7 +384,7 @@ static size_t __cil_cons_leaf_operand_len(struct cil_db *db, struct cil_list_ite static size_t __cil_cons_leaf_op_len(struct cil_list_item *op) { - enum cil_flavor flavor = (enum cil_flavor)(uintptr_t)op->data; + enum cil_flavor flavor = (enum cil_flavor)op->data; size_t len; switch (flavor) { @@ -420,7 +419,7 @@ static size_t cil_cons_expr_len(struct cil_db *db, struct cil_list *cons_expr) i1 = cons_expr->head; - op = (enum cil_flavor)(uintptr_t)i1->data; + op = (enum cil_flavor)i1->data; switch (op) { case CIL_NOT: len = 6; /* "(not )" */ @@ -472,7 +471,7 @@ static char *__cil_cons_leaf_operand_to_string(struct cil_db *db, struct cil_lis size_t o_len; if (flavor == CIL_CONS_OPERAND) { - enum cil_flavor o_flavor = (enum cil_flavor)(uintptr_t)operand->data; + enum cil_flavor o_flavor = (enum cil_flavor)operand->data; switch (o_flavor) { case CIL_CONS_U1: o_str = "u1"; @@ -555,7 +554,7 @@ static char *__cil_cons_leaf_operand_to_string(struct cil_db *db, struct cil_lis static char *__cil_cons_leaf_op_to_string(struct cil_list_item *op, char *new) { - enum cil_flavor flavor = (enum cil_flavor)(uintptr_t)op->data; + enum cil_flavor flavor = (enum cil_flavor)op->data; const char *op_str; size_t len; @@ -599,7 +598,7 @@ static char *__cil_cons_expr_to_string(struct cil_db *db, struct cil_list *cons_ i1 = cons_expr->head; - op = (enum cil_flavor)(uintptr_t)i1->data; + op = (enum cil_flavor)i1->data; switch (op) { case CIL_NOT: *new++ = '('; @@ -1660,11 +1659,9 @@ static void cil_sid_contexts_to_policy(FILE *out, struct cil_list *sids, int mls cil_list_for_each(i1, sids) { sid = i1->data; - if (sid->context) { - fprintf(out, "sid %s ", sid->datum.fqn); - cil_context_to_policy(out, sid->context, mls); - fprintf(out,"\n"); - } + fprintf(out, "sid %s ", sid->datum.fqn); + cil_context_to_policy(out, sid->context, mls); + fprintf(out,"\n"); } } diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c index 7e2c2b9a..a0cadfde 100644 --- a/libsepol/cil/src/cil_post.c +++ b/libsepol/cil/src/cil_post.c @@ -27,7 +27,6 @@ * either expressed or implied, of Tresys Technology, LLC. */ -#include #include #include #include @@ -51,12 +50,6 @@ #define GEN_REQUIRE_ATTR "cil_gen_require" /* Also in libsepol/src/module_to_cil.c */ #define TYPEATTR_INFIX "_typeattr_" /* Also in libsepol/src/module_to_cil.c */ -struct fc_data { - unsigned int meta; - size_t stem_len; - size_t str_len; -}; - static int __cil_expr_to_bitmap(struct cil_list *expr, ebitmap_t *out, int max, struct cil_db *db); static int __cil_expr_list_to_bitmap(struct cil_list *expr_list, ebitmap_t *out, int max, struct cil_db *db); @@ -163,9 +156,9 @@ static int cil_verify_is_list(struct cil_list *list, enum cil_flavor flavor) return CIL_TRUE; } -static void cil_post_fc_fill_data(struct fc_data *fc, const char *path) +void cil_post_fc_fill_data(struct fc_data *fc, char *path) { - size_t c = 0; + int c = 0; fc->meta = 0; fc->stem_len = 0; fc->str_len = 0; @@ -186,13 +179,6 @@ static void cil_post_fc_fill_data(struct fc_data *fc, const char *path) break; case '\\': c++; - if (path[c] == '\0') { - if (!fc->meta) { - fc->stem_len++; - } - fc->str_len++; - return; - } /* FALLTHRU */ default: if (!fc->meta) { @@ -213,8 +199,8 @@ int cil_post_filecon_compare(const void *a, const void *b) struct fc_data *a_data = cil_malloc(sizeof(*a_data)); struct fc_data *b_data = cil_malloc(sizeof(*b_data)); char *a_path = cil_malloc(strlen(a_filecon->path_str) + 1); - char *b_path = cil_malloc(strlen(b_filecon->path_str) + 1); a_path[0] = '\0'; + char *b_path = cil_malloc(strlen(b_filecon->path_str) + 1); b_path[0] = '\0'; strcat(a_path, a_filecon->path_str); strcat(b_path, b_filecon->path_str); @@ -1315,7 +1301,7 @@ static int __cil_expr_to_bitmap(struct cil_list *expr, ebitmap_t *out, int max, flavor = expr->flavor; if (curr->flavor == CIL_OP) { - enum cil_flavor op = (enum cil_flavor)(uintptr_t)curr->data; + enum cil_flavor op = (enum cil_flavor)curr->data; if (op == CIL_ALL) { ebitmap_init(&b1); /* all zeros */ @@ -1494,13 +1480,9 @@ static void __mark_neverallow_attrs(struct cil_list *expr_list) { struct cil_list_item *curr; - if (!expr_list) { - return; - } - cil_list_for_each(curr, expr_list) { if (curr->flavor == CIL_DATUM) { - if (FLAVOR(curr->data) == CIL_TYPEATTRIBUTE) { + if (NODE(curr->data)->flavor == CIL_TYPEATTRIBUTE) { struct cil_typeattribute *attr = curr->data; if (strstr(DATUM(attr)->name, TYPEATTR_INFIX)) { __mark_neverallow_attrs(attr->expr_list); @@ -2141,10 +2123,6 @@ static int __evaluate_classperms_list(struct cil_list *classperms, struct cil_db } } else { /* MAP */ struct cil_list_item *i = NULL; - rc = __evaluate_classperms(cp, db); - if (rc != SEPOL_OK) { - goto exit; - } cil_list_for_each(i, cp->perms) { struct cil_perm *cmp = i->data; rc = __evaluate_classperms_list(cmp->classperms, db); diff --git a/libsepol/cil/src/cil_post.h b/libsepol/cil/src/cil_post.h index b1d2206f..3d541548 100644 --- a/libsepol/cil/src/cil_post.h +++ b/libsepol/cil/src/cil_post.h @@ -30,6 +30,13 @@ #ifndef CIL_POST_H_ #define CIL_POST_H_ +struct fc_data { + int meta; + int stem_len; + int str_len; +}; + +void cil_post_fc_fill_data(struct fc_data *fc, char *path); int cil_post_filecon_compare(const void *a, const void *b); int cil_post_ibpkeycon_compare(const void *a, const void *b); int cil_post_portcon_compare(const void *a, const void *b); diff --git a/libsepol/cil/src/cil_reset_ast.c b/libsepol/cil/src/cil_reset_ast.c index 0ba075c8..43e6b88e 100644 --- a/libsepol/cil/src/cil_reset_ast.c +++ b/libsepol/cil/src/cil_reset_ast.c @@ -2,7 +2,6 @@ #include "cil_internal.h" #include "cil_log.h" #include "cil_list.h" -#include "cil_reset_ast.h" #include "cil_symtab.h" static inline void cil_reset_classperms_list(struct cil_list *cp_list); @@ -23,12 +22,11 @@ static int __class_reset_perm_values(__attribute__((unused)) hashtab_key_t k, ha static void cil_reset_class(struct cil_class *class) { if (class->common != NULL) { - /* Must assume that the common has been destroyed */ - int num_common_perms = class->num_perms - class->perms.nprim; - cil_symtab_map(&class->perms, __class_reset_perm_values, &num_common_perms); + struct cil_class *common = class->common; + cil_symtab_map(&class->perms, __class_reset_perm_values, &common->num_perms); /* during a re-resolve, we need to reset the common, so a classcommon * statement isn't seen as a duplicate */ - class->num_perms = class->perms.nprim; + class->num_perms -= common->num_perms; class->common = NULL; /* Must make this NULL or there will be an error when re-resolving */ } class->ordered = CIL_FALSE; @@ -36,7 +34,7 @@ static void cil_reset_class(struct cil_class *class) static void cil_reset_perm(struct cil_perm *perm) { - cil_list_destroy(&perm->classperms, CIL_FALSE); + cil_reset_classperms_list(perm->classperms); } static inline void cil_reset_classperms(struct cil_classperms *cp) @@ -45,7 +43,6 @@ static inline void cil_reset_classperms(struct cil_classperms *cp) return; } - cp->class = NULL; cil_list_destroy(&cp->perms, CIL_FALSE); } @@ -55,20 +52,12 @@ static void cil_reset_classpermission(struct cil_classpermission *cp) return; } - cil_list_destroy(&cp->classperms, CIL_FALSE); + cil_reset_classperms_list(cp->classperms); } static void cil_reset_classperms_set(struct cil_classperms_set *cp_set) { - if (cp_set == NULL || cp_set->set == NULL) { - return; - } - - if (cp_set->set->datum.name == NULL) { - cil_reset_classperms_list(cp_set->set->classperms); - } - - cp_set->set = NULL; + cil_reset_classpermission(cp_set->set); } static inline void cil_reset_classperms_list(struct cil_list *cp_list) @@ -140,11 +129,8 @@ static void cil_reset_userattributeset(struct cil_userattributeset *uas) static void cil_reset_selinuxuser(struct cil_selinuxuser *selinuxuser) { - selinuxuser->user = NULL; if (selinuxuser->range_str == NULL) { cil_reset_levelrange(selinuxuser->range); - } else { - selinuxuser->range = NULL; } } @@ -208,11 +194,6 @@ static void cil_reset_typeattributeset(struct cil_typeattributeset *tas) cil_list_destroy(&tas->datum_expr, CIL_FALSE); } -static void cil_reset_expandtypeattribute(struct cil_expandtypeattribute *expandattr) -{ - cil_list_destroy(&expandattr->attr_datums, CIL_FALSE); -} - static void cil_reset_avrule(struct cil_avrule *rule) { cil_reset_classperms_list(rule->perms.classperms); @@ -222,8 +203,6 @@ static void cil_reset_rangetransition(struct cil_rangetransition *rangetrans) { if (rangetrans->range_str == NULL) { cil_reset_levelrange(rangetrans->range); - } else { - rangetrans->range = NULL; } } @@ -261,7 +240,6 @@ static void cil_reset_catset(struct cil_catset *catset) static inline void cil_reset_level(struct cil_level *level) { - level->sens = NULL; cil_reset_cats(level->cats); } @@ -269,14 +247,10 @@ static inline void cil_reset_levelrange(struct cil_levelrange *levelrange) { if (levelrange->low_str == NULL) { cil_reset_level(levelrange->low); - } else { - levelrange->low = NULL; } if (levelrange->high_str == NULL) { cil_reset_level(levelrange->high); - } else { - levelrange->high = NULL; } } @@ -284,8 +258,6 @@ static inline void cil_reset_userlevel(struct cil_userlevel *userlevel) { if (userlevel->level_str == NULL) { cil_reset_level(userlevel->level); - } else { - userlevel->level = NULL; } } @@ -293,20 +265,13 @@ static inline void cil_reset_userrange(struct cil_userrange *userrange) { if (userrange->range_str == NULL) { cil_reset_levelrange(userrange->range); - } else { - userrange->range = NULL; } } static inline void cil_reset_context(struct cil_context *context) { - if (!context) { - return; - } if (context->range_str == NULL) { cil_reset_levelrange(context->range); - } else { - context->range = NULL; } } @@ -314,35 +279,26 @@ static void cil_reset_sidcontext(struct cil_sidcontext *sidcontext) { if (sidcontext->context_str == NULL) { cil_reset_context(sidcontext->context); - } else { - sidcontext->context = NULL; } } static void cil_reset_filecon(struct cil_filecon *filecon) { - if (filecon->context_str == NULL) { + if (filecon->context_str == NULL && filecon->context != NULL) { cil_reset_context(filecon->context); - } else { - filecon->context = NULL; } } static void cil_reset_ibpkeycon(struct cil_ibpkeycon *ibpkeycon) { - if (ibpkeycon->context_str == NULL) { + if (!ibpkeycon->context_str) cil_reset_context(ibpkeycon->context); - } else { - ibpkeycon->context = NULL; - } } static void cil_reset_portcon(struct cil_portcon *portcon) { if (portcon->context_str == NULL) { cil_reset_context(portcon->context); - } else { - portcon->context = NULL; } } @@ -350,8 +306,6 @@ static void cil_reset_nodecon(struct cil_nodecon *nodecon) { if (nodecon->context_str == NULL) { cil_reset_context(nodecon->context); - } else { - nodecon->context = NULL; } } @@ -359,8 +313,6 @@ static void cil_reset_genfscon(struct cil_genfscon *genfscon) { if (genfscon->context_str == NULL) { cil_reset_context(genfscon->context); - } else { - genfscon->context = NULL; } } @@ -368,23 +320,17 @@ static void cil_reset_netifcon(struct cil_netifcon *netifcon) { if (netifcon->if_context_str == NULL) { cil_reset_context(netifcon->if_context); - } else { - netifcon->if_context = NULL; } if (netifcon->packet_context_str == NULL) { cil_reset_context(netifcon->packet_context); - } else { - netifcon->packet_context = NULL; } } static void cil_reset_ibendportcon(struct cil_ibendportcon *ibendportcon) { - if (ibendportcon->context_str == NULL) { + if (!ibendportcon->context_str) { cil_reset_context(ibendportcon->context); - } else { - ibendportcon->context = NULL; } } @@ -392,8 +338,6 @@ static void cil_reset_pirqcon(struct cil_pirqcon *pirqcon) { if (pirqcon->context_str == NULL) { cil_reset_context(pirqcon->context); - } else { - pirqcon->context = NULL; } } @@ -401,8 +345,6 @@ static void cil_reset_iomemcon(struct cil_iomemcon *iomemcon) { if (iomemcon->context_str == NULL) { cil_reset_context(iomemcon->context); - } else { - iomemcon->context = NULL; } } @@ -410,8 +352,6 @@ static void cil_reset_ioportcon(struct cil_ioportcon *ioportcon) { if (ioportcon->context_str == NULL) { cil_reset_context(ioportcon->context); - } else { - ioportcon->context = NULL; } } @@ -419,8 +359,6 @@ static void cil_reset_pcidevicecon(struct cil_pcidevicecon *pcidevicecon) { if (pcidevicecon->context_str == NULL) { cil_reset_context(pcidevicecon->context); - } else { - pcidevicecon->context = NULL; } } @@ -428,8 +366,6 @@ static void cil_reset_devicetreecon(struct cil_devicetreecon *devicetreecon) { if (devicetreecon->context_str == NULL) { cil_reset_context(devicetreecon->context); - } else { - devicetreecon->context = NULL; } } @@ -437,8 +373,6 @@ static void cil_reset_fsuse(struct cil_fsuse *fsuse) { if (fsuse->context_str == NULL) { cil_reset_context(fsuse->context); - } else { - fsuse->context = NULL; } } @@ -536,9 +470,6 @@ int __cil_reset_node(struct cil_tree_node *node, __attribute__((unused)) uint32 case CIL_TYPEATTRIBUTESET: cil_reset_typeattributeset(node->data); break; - case CIL_EXPANDTYPEATTRIBUTE: - cil_reset_expandtypeattribute(node->data); - break; case CIL_RANGETRANSITION: cil_reset_rangetransition(node->data); break; @@ -638,6 +569,7 @@ int __cil_reset_node(struct cil_tree_node *node, __attribute__((unused)) uint32 case CIL_CLASSORDER: case CIL_CATORDER: case CIL_SENSITIVITYORDER: + case CIL_EXPANDTYPEATTRIBUTE: break; /* Nothing to reset */ default: break; diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c index 2cf94368..87575860 100644 --- a/libsepol/cil/src/cil_resolve_ast.c +++ b/libsepol/cil/src/cil_resolve_ast.c @@ -46,25 +46,22 @@ #include "cil_verify.h" #include "cil_strpool.h" #include "cil_symtab.h" -#include "cil_stack.h" struct cil_args_resolve { struct cil_db *db; enum cil_pass pass; uint32_t *changed; - struct cil_list *to_destroy; - struct cil_tree_node *block; - struct cil_tree_node *macro; - struct cil_tree_node *optional; - struct cil_tree_node *disabled_optional; + char *last_resolved_name; + struct cil_tree_node *optstack; struct cil_tree_node *boolif; + struct cil_tree_node *macro; + struct cil_tree_node *blockstack; struct cil_list *sidorder_lists; struct cil_list *classorder_lists; struct cil_list *unordered_classorder_lists; struct cil_list *catorder_lists; struct cil_list *sensitivityorder_lists; - struct cil_list *in_list_before; - struct cil_list *in_list_after; + struct cil_list *in_list; }; static struct cil_name * __cil_insert_name(struct cil_db *db, hashtab_key_t key, struct cil_tree_node *ast_node) @@ -79,22 +76,6 @@ static struct cil_name * __cil_insert_name(struct cil_db *db, hashtab_key_t key, enum cil_sym_index sym_index; struct cil_symtab_datum *datum = NULL; - if (parent->flavor == CIL_CALL) { - struct cil_call *call = parent->data; - macro = call->macro; - } else if (parent->flavor == CIL_MACRO) { - macro = parent->data; - } - if (macro != NULL && macro->params != NULL) { - struct cil_list_item *item; - cil_list_for_each(item, macro->params) { - struct cil_param *param = item->data; - if (param->flavor == CIL_NAME && param->str == key) { - return NULL; - } - } - } - cil_flavor_to_symtab_index(CIL_NAME, &sym_index); symtab = &((struct cil_root *)db->ast->root->data)->symtab[sym_index]; @@ -103,6 +84,21 @@ static struct cil_name * __cil_insert_name(struct cil_db *db, hashtab_key_t key, return (struct cil_name *)datum; } + if (parent->flavor == CIL_CALL) { + struct cil_call *call = parent->data; + macro = call->macro; + } else if (parent->flavor == CIL_MACRO) { + macro = parent->data; + } + if (macro != NULL) { + struct cil_list_item *item; + cil_list_for_each(item, macro->params) { + if (((struct cil_param*)item->data)->str == key) { + return NULL; + } + } + } + cil_name_init(&name); cil_symtab_insert(symtab, key, (struct cil_symtab_datum *)name, ast_node); cil_list_append(db->names, CIL_NAME, name); @@ -151,7 +147,6 @@ static int __cil_resolve_perms(symtab_t *class_symtab, symtab_t *common_symtab, return SEPOL_OK; exit: - cil_list_destroy(perm_datums, CIL_FALSE); return rc; } @@ -162,10 +157,6 @@ int cil_resolve_classperms(struct cil_tree_node *current, struct cil_classperms symtab_t *common_symtab = NULL; struct cil_class *class; - if (cp->class) { - return SEPOL_OK; - } - rc = cil_resolve_name(current, cp->class_str, CIL_SYM_CLASSES, extra_args, &datum); if (rc != SEPOL_OK) { goto exit; @@ -403,7 +394,7 @@ int cil_resolve_type_rule(struct cil_tree_node *current, void *extra_args) goto exit; } - result_node = NODE(result_datum); + result_node = result_datum->nodes->head->data; if (result_node->flavor != CIL_TYPE) { cil_log(CIL_ERR, "Type rule result must be a type [%d]\n",result_node->flavor); @@ -431,7 +422,7 @@ int cil_resolve_typeattributeset(struct cil_tree_node *current, void *extra_args goto exit; } - attr_node = NODE(attr_datum); + attr_node = attr_datum->nodes->head->data; if (attr_node->flavor != CIL_TYPEATTRIBUTE) { rc = SEPOL_ERR; @@ -446,6 +437,11 @@ int cil_resolve_typeattributeset(struct cil_tree_node *current, void *extra_args goto exit; } + rc = cil_verify_no_self_reference(attr_datum, attrtypes->datum_expr); + if (rc != SEPOL_OK) { + goto exit; + } + if (attr->expr_list == NULL) { cil_list_init(&attr->expr_list, CIL_TYPEATTRIBUTE); } @@ -475,7 +471,7 @@ int cil_resolve_expandtypeattribute(struct cil_tree_node *current, void *extra_a goto exit; } - attr_node = NODE(attr_datum); + attr_node = attr_datum->nodes->head->data; if (attr_node->flavor != CIL_TYPEATTRIBUTE) { rc = SEPOL_ERR; @@ -510,7 +506,7 @@ int cil_resolve_aliasactual(struct cil_tree_node *current, void *extra_args, enu if (rc != SEPOL_OK) { goto exit; } - if (FLAVOR(alias_datum) != alias_flavor) { + if (NODE(alias_datum)->flavor != alias_flavor) { cil_log(CIL_ERR, "%s is not an alias\n",alias_datum->name); rc = SEPOL_ERR; goto exit; @@ -521,7 +517,7 @@ int cil_resolve_aliasactual(struct cil_tree_node *current, void *extra_args, enu goto exit; } - if (FLAVOR(actual_datum) != flavor && FLAVOR(actual_datum) != alias_flavor) { + if (NODE(actual_datum)->flavor != flavor && NODE(actual_datum)->flavor != alias_flavor) { cil_log(CIL_ERR, "%s is a %s, but aliases a %s\n", alias_datum->name, cil_node_to_string(NODE(alias_datum)), cil_node_to_string(NODE(actual_datum))); rc = SEPOL_ERR; goto exit; @@ -560,10 +556,6 @@ int cil_resolve_alias_to_actual(struct cil_tree_node *current, enum cil_flavor f a1_node = a1->datum.nodes->head->data; while (flavor != a1_node->flavor) { - if (a1->actual == NULL) { - cil_tree_log(current, CIL_ERR, "Alias %s references an unused alias %s", alias->datum.name, a1->datum.name); - return SEPOL_ERR; - } a1 = a1->actual; a1_node = a1->datum.nodes->head->data; steps += 1; @@ -603,7 +595,7 @@ int cil_resolve_typepermissive(struct cil_tree_node *current, void *extra_args) goto exit; } - type_node = NODE(type_datum); + type_node = type_datum->nodes->head->data; if (type_node->flavor != CIL_TYPE && type_node->flavor != CIL_TYPEALIAS) { cil_log(CIL_ERR, "Typepermissive must be a type or type alias\n"); @@ -663,7 +655,7 @@ int cil_resolve_nametypetransition(struct cil_tree_node *current, void *extra_ar goto exit; } - result_node = NODE(result_datum); + result_node = result_datum->nodes->head->data; if (result_node->flavor != CIL_TYPE && result_node->flavor != CIL_TYPEALIAS) { cil_log(CIL_ERR, "typetransition result is not a type or type alias\n"); @@ -775,7 +767,6 @@ int cil_resolve_classcommon(struct cil_tree_node *current, void *extra_args) class->num_perms += common->num_perms; if (class->num_perms > CIL_PERMS_PER_CLASS) { cil_tree_log(current, CIL_ERR, "Too many permissions in class '%s' when including common permissions", class->datum.name); - rc = SEPOL_ERR; goto exit; } @@ -865,7 +856,7 @@ int cil_resolve_userlevel(struct cil_tree_node *current, void *extra_args) goto exit; } - user_node = NODE(user_datum); + user_node = user_datum->nodes->head->data; if (user_node->flavor != CIL_USER) { cil_log(CIL_ERR, "Userlevel must be a user\n"); @@ -918,7 +909,7 @@ int cil_resolve_userrange(struct cil_tree_node *current, void *extra_args) goto exit; } - user_node = NODE(user_datum); + user_node = user_datum->nodes->head->data; if (user_node->flavor != CIL_USER) { cil_log(CIL_ERR, "Userrange must be a user: %s\n", user_datum->fqn); @@ -969,7 +960,7 @@ int cil_resolve_userprefix(struct cil_tree_node *current, void *extra_args) goto exit; } - user_node = NODE(user_datum); + user_node = user_datum->nodes->head->data; if (user_node->flavor != CIL_USER) { cil_log(CIL_ERR, "Userprefix must be a user: %s\n", user_datum->fqn); @@ -996,7 +987,7 @@ int cil_resolve_selinuxuser(struct cil_tree_node *current, void *extra_args) goto exit; } - user_node = NODE(user_datum); + user_node = user_datum->nodes->head->data; if (user_node->flavor != CIL_USER) { cil_log(CIL_ERR, "Selinuxuser must be a user: %s\n", user_datum->fqn); @@ -1089,9 +1080,10 @@ int cil_resolve_roletransition(struct cil_tree_node *current, void *extra_args) if (rc != SEPOL_OK) { goto exit; } - node = NODE(result_datum); + node = result_datum->nodes->head->data; if (node->flavor != CIL_ROLE) { rc = SEPOL_ERR; + printf("%i\n", node->flavor); cil_log(CIL_ERR, "roletransition must result in a role, but %s is a %s\n", roletrans->result_str, cil_node_to_string(node)); goto exit; } @@ -1140,7 +1132,7 @@ int cil_resolve_roleattributeset(struct cil_tree_node *current, void *extra_args if (rc != SEPOL_OK) { goto exit; } - attr_node = NODE(attr_datum); + attr_node = attr_datum->nodes->head->data; if (attr_node->flavor != CIL_ROLEATTRIBUTE) { rc = SEPOL_ERR; @@ -1154,6 +1146,11 @@ int cil_resolve_roleattributeset(struct cil_tree_node *current, void *extra_args goto exit; } + rc = cil_verify_no_self_reference(attr_datum, attrroles->datum_expr); + if (rc != SEPOL_OK) { + goto exit; + } + if (attr->expr_list == NULL) { cil_list_init(&attr->expr_list, CIL_ROLEATTRIBUTE); } @@ -1483,12 +1480,6 @@ int cil_resolve_classorder(struct cil_tree_node *current, void *extra_args) rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CLASSES, extra_args, &datum); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Failed to resolve class %s in classorder\n", (char *)curr->data); - rc = SEPOL_ERR; - goto exit; - } - if (FLAVOR(datum) != CIL_CLASS) { - cil_log(CIL_ERR, "%s is not a class. Only classes are allowed in classorder statements\n", datum->name); - rc = SEPOL_ERR; goto exit; } cil_list_append(new, CIL_CLASS, datum); @@ -1529,12 +1520,6 @@ int cil_resolve_sidorder(struct cil_tree_node *current, void *extra_args) cil_log(CIL_ERR, "Failed to resolve sid %s in sidorder\n", (char *)curr->data); goto exit; } - if (FLAVOR(datum) != CIL_SID) { - cil_log(CIL_ERR, "%s is not a sid. Only sids are allowed in sidorder statements\n", datum->name); - rc = SEPOL_ERR; - goto exit; - } - cil_list_append(new, CIL_SID, datum); } @@ -1585,7 +1570,7 @@ int cil_resolve_catorder(struct cil_tree_node *current, void *extra_args) cil_log(CIL_ERR, "Failed to resolve category %s in categoryorder\n", (char *)curr->data); goto exit; } - node = NODE(cat_datum); + node = cat_datum->nodes->head->data; if (node->flavor != CIL_CAT) { cil_log(CIL_ERR, "%s is not a category. Only categories are allowed in categoryorder statements\n", cat_datum->name); rc = SEPOL_ERR; @@ -1623,12 +1608,7 @@ int cil_resolve_sensitivityorder(struct cil_tree_node *current, void *extra_args cil_list_for_each(curr, sensorder->sens_list_str) { rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_SENS, extra_args, &datum); if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Failed to resolve sensitivity %s in sensitivityorder\n", (char *)curr->data); - goto exit; - } - if (FLAVOR(datum) != CIL_SENS) { - cil_log(CIL_ERR, "%s is not a sensitivity. Only sensitivities are allowed in sensitivityorder statements\n", datum->name); - rc = SEPOL_ERR; + cil_log(CIL_ERR, "Failed to resolve sensitivty %s in sensitivityorder\n", (char *)curr->data); goto exit; } cil_list_append(new, CIL_SENS, datum); @@ -1664,7 +1644,21 @@ exit: int cil_resolve_catset(struct cil_tree_node *current, struct cil_catset *catset, void *extra_args) { - return cil_resolve_cats(current, catset->cats, extra_args); + int rc = SEPOL_ERR; + + rc = cil_resolve_cats(current, catset->cats, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_verify_no_self_reference((struct cil_symtab_datum *)catset, catset->cats->datum_expr); + if (rc != SEPOL_OK) { + cil_list_destroy(&catset->cats->datum_expr, CIL_FALSE); + goto exit; + } + +exit: + return rc; } int cil_resolve_senscat(struct cil_tree_node *current, void *extra_args) @@ -1704,10 +1698,6 @@ int cil_resolve_level(struct cil_tree_node *current, struct cil_level *level, vo struct cil_symtab_datum *sens_datum = NULL; int rc = SEPOL_ERR; - if (level->sens) { - return SEPOL_OK; - } - rc = cil_resolve_name(current, (char*)level->sens_str, CIL_SYM_SENS, extra_args, &sens_datum); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Failed to find sensitivity\n"); @@ -1843,7 +1833,7 @@ int cil_resolve_context(struct cil_tree_node *current, struct cil_context *conte goto exit; } - node = NODE(user_datum); + node = user_datum->nodes->head->data; if (node->flavor != CIL_USER) { cil_log(CIL_ERR, "Context user must be a user: %s\n", user_datum->fqn); @@ -1858,7 +1848,7 @@ int cil_resolve_context(struct cil_tree_node *current, struct cil_context *conte goto exit; } - node = NODE(role_datum); + node = role_datum->nodes->head->data; if (node->flavor != CIL_ROLE) { rc = SEPOL_ERR; cil_log(CIL_ERR, "Context role not a role: %s\n", role_datum->fqn); @@ -1872,7 +1862,7 @@ int cil_resolve_context(struct cil_tree_node *current, struct cil_context *conte goto exit; } - node = NODE(type_datum); + node = type_datum->nodes->head->data; if (node->flavor != CIL_TYPE && node->flavor != CIL_TYPEALIAS) { rc = SEPOL_ERR; @@ -2322,7 +2312,7 @@ int cil_resolve_blockinherit_link(struct cil_tree_node *current, void *extra_arg goto exit; } - node = NODE(block_datum); + node = block_datum->nodes->head->data; if (node->flavor != CIL_BLOCK) { cil_log(CIL_ERR, "%s is not a block\n", cil_node_to_string(node)); @@ -2343,6 +2333,71 @@ exit: return rc; } +void cil_print_recursive_blockinherit(struct cil_tree_node *bi_node, struct cil_tree_node *terminating_node) +{ + struct cil_list *trace = NULL; + struct cil_list_item *item = NULL; + struct cil_tree_node *curr = NULL; + + cil_list_init(&trace, CIL_NODE); + + for (curr = bi_node; curr != terminating_node; curr = curr->parent) { + if (curr->flavor == CIL_BLOCK) { + cil_list_prepend(trace, CIL_NODE, curr); + } else { + if (curr != bi_node) { + cil_list_prepend(trace, CIL_NODE, NODE(((struct cil_blockinherit *)curr->data)->block)); + } + cil_list_prepend(trace, CIL_NODE, curr); + } + } + cil_list_prepend(trace, CIL_NODE, terminating_node); + + cil_list_for_each(item, trace) { + curr = item->data; + if (curr->flavor == CIL_BLOCK) { + cil_tree_log(curr, CIL_ERR, "block %s", DATUM(curr->data)->name); + } else { + cil_tree_log(curr, CIL_ERR, "blockinherit %s", ((struct cil_blockinherit *)curr->data)->block_str); + } + } + + cil_list_destroy(&trace, CIL_FALSE); +} + +int cil_check_recursive_blockinherit(struct cil_tree_node *bi_node) +{ + struct cil_tree_node *curr = NULL; + struct cil_blockinherit *bi = NULL; + struct cil_block *block = NULL; + int rc = SEPOL_ERR; + + bi = bi_node->data; + + for (curr = bi_node->parent; curr != NULL; curr = curr->parent) { + if (curr->flavor != CIL_BLOCK) { + continue; + } + + block = curr->data; + + if (block != bi->block) { + continue; + } + + cil_log(CIL_ERR, "Recursive blockinherit found:\n"); + cil_print_recursive_blockinherit(bi_node, curr); + + rc = SEPOL_ERR; + goto exit; + } + + rc = SEPOL_OK; + +exit: + return rc; +} + int cil_resolve_blockinherit_copy(struct cil_tree_node *current, void *extra_args) { struct cil_block *block = current->data; @@ -2366,6 +2421,11 @@ int cil_resolve_blockinherit_copy(struct cil_tree_node *current, void *extra_arg } cil_list_for_each(item, block->bi_nodes) { + rc = cil_check_recursive_blockinherit(item->data); + if (rc != SEPOL_OK) { + goto exit; + } + rc = cil_copy_ast(db, current, item->data); if (rc != SEPOL_OK) { cil_log(CIL_ERR, "Failed to copy block contents into blockinherit\n"); @@ -2391,10 +2451,9 @@ int cil_resolve_blockabstract(struct cil_tree_node *current, void *extra_args) goto exit; } - block_node = NODE(block_datum); + block_node = block_datum->nodes->head->data; if (block_node->flavor != CIL_BLOCK) { cil_log(CIL_ERR, "Failed to resolve blockabstract to a block, rc: %d\n", rc); - rc = SEPOL_ERR; goto exit; } @@ -2424,24 +2483,17 @@ int cil_resolve_in(struct cil_tree_node *current, void *extra_args) goto exit; } - block_node = NODE(block_datum); - - if (block_node->flavor == CIL_OPTIONAL) { - if (block_datum->nodes && block_datum->nodes->head != block_datum->nodes->tail) { - cil_tree_log(current, CIL_ERR, "Multiple optional blocks referred to by in-statement"); - cil_tree_log(block_node, CIL_ERR, "First optional block"); - rc = SEPOL_ERR; - goto exit; - } - } + block_node = block_datum->nodes->head->data; rc = cil_copy_ast(db, current, block_node); if (rc != SEPOL_OK) { - cil_tree_log(current, CIL_ERR, "Failed to copy in-statement"); + printf("Failed to copy in, rc: %d\n", rc); goto exit; } cil_tree_children_destroy(current); + current->cl_head = NULL; + current->cl_tail = NULL; return SEPOL_OK; @@ -2449,8 +2501,10 @@ exit: return rc; } -int cil_resolve_in_list(struct cil_list *in_list, void *extra_args) +int cil_resolve_in_list(void *extra_args) { + struct cil_args_resolve *args = extra_args; + struct cil_list *ins = args->in_list; struct cil_list_item *curr = NULL; struct cil_tree_node *node = NULL; struct cil_tree_node *last_failed_node = NULL; @@ -2464,7 +2518,7 @@ int cil_resolve_in_list(struct cil_list *in_list, void *extra_args) resolved = 0; unresolved = 0; - cil_list_for_each(curr, in_list) { + cil_list_for_each(curr, ins) { if (curr->flavor != CIL_NODE) { continue; } @@ -2520,7 +2574,7 @@ int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil if (rc != SEPOL_OK) { goto exit; } - if (FLAVOR(parent_datum) == attr_flavor) { + if (NODE(parent_datum)->flavor == attr_flavor) { cil_log(CIL_ERR, "Bounds parent %s is an attribute\n", bounds->parent_str); rc = SEPOL_ERR; goto exit; @@ -2531,7 +2585,7 @@ int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil if (rc != SEPOL_OK) { goto exit; } - if (FLAVOR(child_datum) == attr_flavor) { + if (NODE(child_datum)->flavor == attr_flavor) { cil_log(CIL_ERR, "Bounds child %s is an attribute\n", bounds->child_str); rc = SEPOL_ERR; goto exit; @@ -2703,348 +2757,260 @@ exit: return rc; } -static int cil_build_call_args(struct cil_tree_node *call_node, struct cil_call *call, struct cil_macro *macro, void *extra_args) +int cil_resolve_call1(struct cil_tree_node *current, void *extra_args) { + struct cil_call *new_call = current->data; struct cil_args_resolve *args = extra_args; - struct cil_list_item *item; - struct cil_args *arg = NULL; - struct cil_tree_node *arg_node = NULL; - int rc = SEPOL_ERR; - - if (macro->params == NULL) { - if (call->args_tree == NULL) { - return SEPOL_OK; - } else { - cil_tree_log(call_node, CIL_ERR, "Unexpected arguments"); - return SEPOL_ERR; - } - } - if (call->args_tree == NULL) { - cil_tree_log(call_node, CIL_ERR, "Missing arguments"); - return SEPOL_ERR; - } - - arg_node = call->args_tree->root->cl_head; - - cil_list_init(&call->args, CIL_LIST_ITEM); - - cil_list_for_each(item, macro->params) { - enum cil_flavor flavor = ((struct cil_param*)item->data)->flavor; - - if (arg_node == NULL) { - cil_tree_log(call_node, CIL_ERR, "Missing arguments"); - rc = SEPOL_ERR; - goto exit; - } - if (item->flavor != CIL_PARAM) { - rc = SEPOL_ERR; - goto exit; - } - - cil_args_init(&arg); - - switch (flavor) { - case CIL_NAME: { - struct cil_name *name; - if (arg_node->data == NULL) { - cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); - cil_destroy_args(arg); - rc = SEPOL_ERR; - goto exit; - } - name = __cil_insert_name(args->db, arg_node->data, call_node); - if (name != NULL) { - arg->arg = (struct cil_symtab_datum *)name; - } else { - arg->arg_str = arg_node->data; - } - } - break; - case CIL_TYPE: - if (arg_node->data == NULL) { - cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); - cil_destroy_args(arg); - rc = SEPOL_ERR; - goto exit; - } - arg->arg_str = arg_node->data; - break; - case CIL_ROLE: - if (arg_node->data == NULL) { - cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); - cil_destroy_args(arg); - rc = SEPOL_ERR; - goto exit; - } - arg->arg_str = arg_node->data; - break; - case CIL_USER: - if (arg_node->data == NULL) { - cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); - cil_destroy_args(arg); - rc = SEPOL_ERR; - goto exit; - } - arg->arg_str = arg_node->data; - break; - case CIL_SENS: - if (arg_node->data == NULL) { - cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); - cil_destroy_args(arg); - rc = SEPOL_ERR; - goto exit; - } - arg->arg_str = arg_node->data; - break; - case CIL_CAT: - if (arg_node->data == NULL) { - cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); - cil_destroy_args(arg); - rc = SEPOL_ERR; - goto exit; - } - arg->arg_str = arg_node->data; - break; - case CIL_BOOL: - if (arg_node->data == NULL) { - cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); - cil_destroy_args(arg); - rc = SEPOL_ERR; - goto exit; - } - arg->arg_str = arg_node->data; - break; - case CIL_CATSET: { - if (arg_node->cl_head != NULL) { - struct cil_catset *catset = NULL; - struct cil_tree_node *cat_node = NULL; - cil_catset_init(&catset); - rc = cil_fill_cats(arg_node, &catset->cats); - if (rc != SEPOL_OK) { - cil_destroy_catset(catset); - cil_destroy_args(arg); - goto exit; - } - cil_tree_node_init(&cat_node); - cat_node->flavor = CIL_CATSET; - cat_node->data = catset; - cil_list_append(((struct cil_symtab_datum*)catset)->nodes, - CIL_LIST_ITEM, cat_node); - arg->arg = (struct cil_symtab_datum*)catset; - } else if (arg_node->data == NULL) { - cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); - cil_destroy_args(arg); - rc = SEPOL_ERR; - goto exit; - } else { - arg->arg_str = arg_node->data; - } - - break; - } - case CIL_LEVEL: { - if (arg_node->cl_head != NULL) { - struct cil_level *level = NULL; - struct cil_tree_node *lvl_node = NULL; - cil_level_init(&level); - - rc = cil_fill_level(arg_node->cl_head, level); - if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Failed to create anonymous level, rc: %d\n", rc); - cil_destroy_level(level); - cil_destroy_args(arg); - goto exit; - } - cil_tree_node_init(&lvl_node); - lvl_node->flavor = CIL_LEVEL; - lvl_node->data = level; - cil_list_append(((struct cil_symtab_datum*)level)->nodes, - CIL_LIST_ITEM, lvl_node); - arg->arg = (struct cil_symtab_datum*)level; - } else if (arg_node->data == NULL) { - cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); - cil_destroy_args(arg); - rc = SEPOL_ERR; - goto exit; - } else { - arg->arg_str = arg_node->data; - } - - break; - } - case CIL_LEVELRANGE: { - if (arg_node->cl_head != NULL) { - struct cil_levelrange *range = NULL; - struct cil_tree_node *range_node = NULL; - cil_levelrange_init(&range); - - rc = cil_fill_levelrange(arg_node->cl_head, range); - if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Failed to create anonymous levelrange, rc: %d\n", rc); - cil_destroy_levelrange(range); - cil_destroy_args(arg); - goto exit; - } - cil_tree_node_init(&range_node); - range_node->flavor = CIL_LEVELRANGE; - range_node->data = range; - cil_list_append(((struct cil_symtab_datum*)range)->nodes, - CIL_LIST_ITEM, range_node); - arg->arg = (struct cil_symtab_datum*)range; - } else if (arg_node->data == NULL) { - cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); - cil_destroy_args(arg); - rc = SEPOL_ERR; - goto exit; - } else { - arg->arg_str = arg_node->data; - } - - break; - } - case CIL_IPADDR: { - if (arg_node->data == NULL) { - cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); - cil_destroy_args(arg); - rc = SEPOL_ERR; - goto exit; - } else if (strchr(arg_node->data, '.') || strchr(arg_node->data, ':')) { - struct cil_ipaddr *ipaddr = NULL; - struct cil_tree_node *addr_node = NULL; - cil_ipaddr_init(&ipaddr); - rc = cil_fill_ipaddr(arg_node, ipaddr); - if (rc != SEPOL_OK) { - cil_tree_log(call_node, CIL_ERR, "Failed to create anonymous ip address"); - cil_destroy_ipaddr(ipaddr); - cil_destroy_args(arg); - goto exit; - } - cil_tree_node_init(&addr_node); - addr_node->flavor = CIL_IPADDR; - addr_node->data = ipaddr; - cil_list_append(DATUM(ipaddr)->nodes, CIL_LIST_ITEM, addr_node); - arg->arg = DATUM(ipaddr); - } else { - arg->arg_str = arg_node->data; - } - break; - } - case CIL_CLASS: - if (arg_node->data == NULL) { - cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); - cil_destroy_args(arg); - rc = SEPOL_ERR; - goto exit; - } - arg->arg_str = arg_node->data; - break; - case CIL_MAP_CLASS: - if (arg_node->data == NULL) { - cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); - cil_destroy_args(arg); - rc = SEPOL_ERR; - goto exit; - } - arg->arg_str = arg_node->data; - break; - case CIL_CLASSPERMISSION: { - if (arg_node->cl_head != NULL) { - struct cil_classpermission *cp = NULL; - struct cil_tree_node *cp_node = NULL; - - cil_classpermission_init(&cp); - rc = cil_fill_classperms_list(arg_node, &cp->classperms); - if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Failed to create anonymous classpermission\n"); - cil_destroy_classpermission(cp); - cil_destroy_args(arg); - goto exit; - } - cil_tree_node_init(&cp_node); - cp_node->flavor = CIL_CLASSPERMISSION; - cp_node->data = cp; - cil_list_append(cp->datum.nodes, CIL_LIST_ITEM, cp_node); - arg->arg = (struct cil_symtab_datum*)cp; - } else if (arg_node->data == NULL) { - cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter"); - cil_destroy_args(arg); - rc = SEPOL_ERR; - goto exit; - } else { - arg->arg_str = arg_node->data; - } - break; - } - default: - cil_log(CIL_ERR, "Unexpected flavor: %d\n", - (((struct cil_param*)item->data)->flavor)); - cil_destroy_args(arg); - rc = SEPOL_ERR; - goto exit; - } - arg->param_str = ((struct cil_param*)item->data)->str; - arg->flavor = flavor; - - cil_list_append(call->args, CIL_ARGS, arg); - - arg_node = arg_node->next; - } - - if (arg_node != NULL) { - cil_tree_log(call_node, CIL_ERR, "Unexpected arguments"); - rc = SEPOL_ERR; - goto exit; - } - - return SEPOL_OK; - -exit: - return rc; -} - -int cil_resolve_call(struct cil_tree_node *current, void *extra_args) -{ - struct cil_call *call = current->data; - struct cil_args_resolve *args = extra_args; + struct cil_db *db = NULL; struct cil_tree_node *macro_node = NULL; struct cil_symtab_datum *macro_datum = NULL; int rc = SEPOL_ERR; - if (call->copied) { - return SEPOL_OK; + if (args != NULL) { + db = args->db; } - rc = cil_resolve_name(current, call->macro_str, CIL_SYM_BLOCKS, extra_args, ¯o_datum); + rc = cil_resolve_name(current, new_call->macro_str, CIL_SYM_BLOCKS, extra_args, ¯o_datum); if (rc != SEPOL_OK) { goto exit; } - macro_node = NODE(macro_datum); + macro_node = macro_datum->nodes->head->data; if (macro_node->flavor != CIL_MACRO) { - cil_tree_log(current, CIL_ERR, "Failed to resolve %s to a macro", call->macro_str); + printf("Failed to resolve %s to a macro\n", new_call->macro_str); rc = SEPOL_ERR; goto exit; } - call->macro = (struct cil_macro*)macro_datum; + new_call->macro = (struct cil_macro*)macro_datum; - rc = cil_build_call_args(current, call, call->macro, extra_args); - if (rc != SEPOL_OK) { + if (new_call->macro->params != NULL ) { + + struct cil_list_item *item; + struct cil_args *new_arg = NULL; + struct cil_tree_node *pc = NULL; + + if (new_call->args_tree == NULL) { + cil_tree_log(current, CIL_ERR, "Missing arguments"); + rc = SEPOL_ERR; + goto exit; + } + + pc = new_call->args_tree->root->cl_head; + + cil_list_init(&new_call->args, CIL_LIST_ITEM); + + cil_list_for_each(item, new_call->macro->params) { + enum cil_flavor flavor = ((struct cil_param*)item->data)->flavor; + + if (pc == NULL) { + cil_tree_log(current, CIL_ERR, "Missing arguments"); + rc = SEPOL_ERR; + goto exit; + } + if (item->flavor != CIL_PARAM) { + rc = SEPOL_ERR; + goto exit; + } + + cil_args_init(&new_arg); + + switch (flavor) { + case CIL_NAME: { + struct cil_name *name; + name = __cil_insert_name(args->db, pc->data, current); + if (name != NULL) { + new_arg->arg = (struct cil_symtab_datum *)name; + } else { + new_arg->arg_str = pc->data; + } + } + break; + case CIL_TYPE: + new_arg->arg_str = pc->data; + break; + case CIL_ROLE: + new_arg->arg_str = pc->data; + break; + case CIL_USER: + new_arg->arg_str = pc->data; + break; + case CIL_SENS: + new_arg->arg_str = pc->data; + break; + case CIL_CAT: + new_arg->arg_str = pc->data; + break; + case CIL_BOOL: + new_arg->arg_str = pc->data; + break; + case CIL_CATSET: { + if (pc->cl_head != NULL) { + struct cil_catset *catset = NULL; + struct cil_tree_node *cat_node = NULL; + cil_catset_init(&catset); + rc = cil_fill_cats(pc, &catset->cats); + if (rc != SEPOL_OK) { + cil_destroy_catset(catset); + cil_destroy_args(new_arg); + goto exit; + } + cil_tree_node_init(&cat_node); + cat_node->flavor = CIL_CATSET; + cat_node->data = catset; + cil_list_append(((struct cil_symtab_datum*)catset)->nodes, + CIL_LIST_ITEM, cat_node); + new_arg->arg = (struct cil_symtab_datum*)catset; + } else { + new_arg->arg_str = pc->data; + } + + break; + } + case CIL_LEVEL: { + if (pc->cl_head != NULL) { + struct cil_level *level = NULL; + struct cil_tree_node *lvl_node = NULL; + cil_level_init(&level); + + rc = cil_fill_level(pc->cl_head, level); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to create anonymous level, rc: %d\n", rc); + cil_destroy_level(level); + cil_destroy_args(new_arg); + goto exit; + } + cil_tree_node_init(&lvl_node); + lvl_node->flavor = CIL_LEVEL; + lvl_node->data = level; + cil_list_append(((struct cil_symtab_datum*)level)->nodes, + CIL_LIST_ITEM, lvl_node); + new_arg->arg = (struct cil_symtab_datum*)level; + } else { + new_arg->arg_str = pc->data; + } + + break; + } + case CIL_LEVELRANGE: { + if (pc->cl_head != NULL) { + struct cil_levelrange *range = NULL; + struct cil_tree_node *range_node = NULL; + cil_levelrange_init(&range); + + rc = cil_fill_levelrange(pc->cl_head, range); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to create anonymous levelrange, rc: %d\n", rc); + cil_destroy_levelrange(range); + cil_destroy_args(new_arg); + goto exit; + } + cil_tree_node_init(&range_node); + range_node->flavor = CIL_LEVELRANGE; + range_node->data = range; + cil_list_append(((struct cil_symtab_datum*)range)->nodes, + CIL_LIST_ITEM, range_node); + new_arg->arg = (struct cil_symtab_datum*)range; + } else { + new_arg->arg_str = pc->data; + } + + break; + } + case CIL_IPADDR: { + if (pc->cl_head != NULL) { + struct cil_ipaddr *ipaddr = NULL; + struct cil_tree_node *addr_node = NULL; + cil_ipaddr_init(&ipaddr); + + rc = cil_fill_ipaddr(pc->cl_head, ipaddr); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to create anonymous ip address, rc: %d\n", rc); + cil_destroy_ipaddr(ipaddr); + cil_destroy_args(new_arg); + goto exit; + } + cil_tree_node_init(&addr_node); + addr_node->flavor = CIL_IPADDR; + addr_node->data = ipaddr; + cil_list_append(((struct cil_symtab_datum*)ipaddr)->nodes, + CIL_LIST_ITEM, addr_node); + new_arg->arg = (struct cil_symtab_datum*)ipaddr; + } else { + new_arg->arg_str = pc->data; + } + + break; + } + case CIL_CLASS: + new_arg->arg_str = pc->data; + break; + case CIL_MAP_CLASS: + new_arg->arg_str = pc->data; + break; + case CIL_CLASSPERMISSION: { + if (pc->cl_head != NULL) { + struct cil_classpermission *cp = NULL; + struct cil_tree_node *cp_node = NULL; + + cil_classpermission_init(&cp); + rc = cil_fill_classperms_list(pc, &cp->classperms); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to create anonymous classpermission\n"); + cil_destroy_classpermission(cp); + cil_destroy_args(new_arg); + goto exit; + } + cil_tree_node_init(&cp_node); + cp_node->flavor = CIL_CLASSPERMISSION; + cp_node->data = cp; + cil_list_append(cp->datum.nodes, CIL_LIST_ITEM, cp_node); + new_arg->arg = (struct cil_symtab_datum*)cp; + } else { + new_arg->arg_str = pc->data; + } + break; + } + default: + cil_log(CIL_ERR, "Unexpected flavor: %d\n", + (((struct cil_param*)item->data)->flavor)); + cil_destroy_args(new_arg); + rc = SEPOL_ERR; + goto exit; + } + new_arg->param_str = ((struct cil_param*)item->data)->str; + new_arg->flavor = flavor; + + cil_list_append(new_call->args, CIL_ARGS, new_arg); + + pc = pc->next; + } + + if (pc != NULL) { + cil_tree_log(current, CIL_ERR, "Unexpected arguments"); + rc = SEPOL_ERR; + goto exit; + } + } else if (new_call->args_tree != NULL) { + cil_tree_log(current, CIL_ERR, "Unexpected arguments"); + rc = SEPOL_ERR; goto exit; } - rc = cil_check_recursive_call(current, macro_node); - if (rc != SEPOL_OK) { - goto exit; - } + if (new_call->copied == 0) { + new_call->copied = 1; - rc = cil_copy_ast(args->db, macro_node, current); - if (rc != SEPOL_OK) { - cil_tree_log(current, CIL_ERR, "Failed to copy macro %s to call", macro_datum->name); - goto exit; - } + rc = cil_check_recursive_call(current, macro_node); + if (rc != SEPOL_OK) { + goto exit; + } - call->copied = 1; + rc = cil_copy_ast(db, macro_node, current); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to copy macro, rc: %d\n", rc); + goto exit; + } + } return SEPOL_OK; @@ -3052,19 +3018,19 @@ exit: return rc; } -int cil_resolve_call_args(struct cil_tree_node *current, void *extra_args) +int cil_resolve_call2(struct cil_tree_node *current, void *extra_args) { - struct cil_call *call = current->data; + struct cil_call *new_call = current->data; int rc = SEPOL_ERR; enum cil_sym_index sym_index = CIL_SYM_UNKNOWN; struct cil_list_item *item; - if (call->args == NULL) { + if (new_call->args == NULL) { rc = SEPOL_OK; goto exit; } - cil_list_for_each(item, call->args) { + cil_list_for_each(item, new_call->args) { struct cil_args *arg = item->data; if (arg->arg == NULL && arg->arg_str == NULL) { cil_log(CIL_ERR, "Arguments not created correctly\n"); @@ -3147,37 +3113,10 @@ int cil_resolve_call_args(struct cil_tree_node *current, void *extra_args) } if (sym_index != CIL_SYM_UNKNOWN) { - struct cil_symtab_datum *datum; - struct cil_tree_node *n; - rc = cil_resolve_name(current, arg->arg_str, sym_index, extra_args, &datum); + rc = cil_resolve_name(current, arg->arg_str, sym_index, extra_args, &(arg->arg)); if (rc != SEPOL_OK) { - cil_tree_log(current, CIL_ERR, "Failed to resolve %s in call argument list", arg->arg_str); goto exit; } - arg->arg = datum; - n = NODE(datum); - while (n && n->flavor != CIL_ROOT) { - if (n == current) { - symtab_t *s = datum->symtab; - /* Call arg should not resolve to declaration in the call - * Need to remove datum temporarily to resolve to a datum outside - * the call. - */ - cil_symtab_remove_datum(datum); - rc = cil_resolve_name(current, arg->arg_str, sym_index, extra_args, &(arg->arg)); - if (rc != SEPOL_OK) { - cil_tree_log(current, CIL_ERR, "Failed to resolve %s in call argument list", arg->arg_str); - goto exit; - } - rc = cil_symtab_insert(s, datum->name, datum, NULL); - if (rc != SEPOL_OK) { - cil_tree_log(current, CIL_ERR, "Failed to re-insert datum while resolving %s in call argument list", arg->arg_str); - goto exit; - } - break; - } - n = n->parent; - } } } @@ -3207,7 +3146,7 @@ int cil_resolve_name_call_args(struct cil_call *call, char *name, enum cil_sym_i if (param_index == sym_index) { if (name == arg->param_str) { *datum = arg->arg; - rc = *datum ? SEPOL_OK : SEPOL_ERR; + rc = SEPOL_OK; goto exit; } } @@ -3225,8 +3164,6 @@ int cil_resolve_expr(enum cil_flavor expr_type, struct cil_list *str_expr, struc struct cil_list_item *curr; struct cil_symtab_datum *res_datum = NULL; enum cil_sym_index sym_index = CIL_SYM_UNKNOWN; - struct cil_list *datum_sub_expr; - enum cil_flavor op = CIL_NONE; switch (str_expr->flavor) { case CIL_BOOL: @@ -3260,53 +3197,31 @@ int cil_resolve_expr(enum cil_flavor expr_type, struct cil_list *str_expr, struc if (rc != SEPOL_OK) { goto exit; } - if (sym_index == CIL_SYM_CATS && NODE(res_datum)->flavor == CIL_CATSET) { - struct cil_catset *catset = (struct cil_catset *)res_datum; - if (op == CIL_RANGE) { - cil_tree_log(parent, CIL_ERR, "Category set not allowed in category range"); - rc = SEPOL_ERR; - goto exit; - } - if (!res_datum->name) { - /* Anonymous category sets need to be resolved when encountered */ - if (!catset->cats->datum_expr) { - rc = cil_resolve_expr(expr_type, catset->cats->str_expr, &catset->cats->datum_expr, parent, extra_args); - if (rc != SEPOL_OK) { - goto exit; - } - } - cil_copy_list(catset->cats->datum_expr, &datum_sub_expr); - cil_list_append(*datum_expr, CIL_LIST, datum_sub_expr); - } else { - cil_list_append(*datum_expr, CIL_DATUM, res_datum); - } - } else { - if (sym_index == CIL_SYM_TYPES && (expr_type == CIL_CONSTRAIN || expr_type == CIL_VALIDATETRANS)) { - cil_type_used(res_datum, CIL_ATTR_CONSTRAINT); - } - cil_list_append(*datum_expr, CIL_DATUM, res_datum); + + if (sym_index == CIL_SYM_TYPES && (expr_type == CIL_CONSTRAIN || expr_type == CIL_VALIDATETRANS)) { + cil_type_used(res_datum, CIL_ATTR_CONSTRAINT); } + + cil_list_append(*datum_expr, CIL_DATUM, res_datum); break; case CIL_LIST: { + struct cil_list *datum_sub_expr; rc = cil_resolve_expr(expr_type, curr->data, &datum_sub_expr, parent, extra_args); if (rc != SEPOL_OK) { + cil_list_destroy(&datum_sub_expr, CIL_TRUE); goto exit; } cil_list_append(*datum_expr, CIL_LIST, datum_sub_expr); break; } default: - if (curr->flavor == CIL_OP) { - op = (enum cil_flavor)(uintptr_t)curr->data; - } cil_list_append(*datum_expr, curr->flavor, curr->data); break; - } + } } return SEPOL_OK; exit: - cil_list_destroy(datum_expr, CIL_FALSE); return rc; } @@ -3351,7 +3266,7 @@ static int __cil_evaluate_tunable_expr(struct cil_list_item *curr) return CIL_FALSE; } else if (curr->flavor == CIL_OP) { uint16_t v1, v2; - enum cil_flavor op_flavor = (enum cil_flavor)(uintptr_t)curr->data; + enum cil_flavor op_flavor = (enum cil_flavor)curr->data; v1 = __cil_evaluate_tunable_expr_helper(curr->next); @@ -3453,7 +3368,7 @@ int cil_resolve_userattributeset(struct cil_tree_node *current, void *extra_args if (rc != SEPOL_OK) { goto exit; } - attr_node = NODE(attr_datum); + attr_node = attr_datum->nodes->head->data; if (attr_node->flavor != CIL_USERATTRIBUTE) { rc = SEPOL_ERR; @@ -3467,6 +3382,11 @@ int cil_resolve_userattributeset(struct cil_tree_node *current, void *extra_args goto exit; } + rc = cil_verify_no_self_reference(attr_datum, attrusers->datum_expr); + if (rc != SEPOL_OK) { + goto exit; + } + if (attr->expr_list == NULL) { cil_list_init(&attr->expr_list, CIL_USERATTRIBUTE); } @@ -3479,119 +3399,17 @@ exit: return rc; } -/* - * Degenerate inheritance leads to exponential growth of the policy - * It can take many forms, but here is one example. - * ... - * (blockinherit ba) - * (block b0 - * (block b1 - * (block b2 - * (block b3 - * ... - * ) - * (blockinherit b3) - * ) - * (blockinherit b2) - * ) - * (blockinherit b1) - * ) - * (blockinherit b0) - * ... - * This leads to 2^4 copies of the content of block b3, 2^3 copies of the - * contents of block b2, etc. - */ -static unsigned cil_count_actual(struct cil_tree_node *node) -{ - unsigned count = 0; - - if (node->flavor == CIL_BLOCKINHERIT) { - count += 1; - } - - for (node = node->cl_head; node; node = node->next) { - count += cil_count_actual(node); - } - - return count; -} - -static int cil_check_inheritances(struct cil_tree_node *node, unsigned max, unsigned *count, struct cil_stack *stack, unsigned *loop) -{ - int rc; - - if (node->flavor == CIL_BLOCKINHERIT) { - struct cil_blockinherit *bi = node->data; - *count += 1; - if (*count > max) { - cil_tree_log(node, CIL_ERR, "Degenerate inheritance detected"); - return SEPOL_ERR; - } - if (bi->block) { - struct cil_tree_node *block_node = NODE(bi->block); - struct cil_stack_item *item; - int i = 0; - cil_stack_for_each(stack, i, item) { - if (block_node == (struct cil_tree_node *)item->data) { - *loop = CIL_TRUE; - cil_tree_log(block_node, CIL_ERR, "Block inheritance loop found"); - cil_tree_log(node, CIL_ERR, " blockinherit"); - return SEPOL_ERR; - } - } - cil_stack_push(stack, CIL_BLOCK, block_node); - rc = cil_check_inheritances(block_node, max, count, stack, loop); - cil_stack_pop(stack); - if (rc != SEPOL_OK) { - if (*loop == CIL_TRUE) { - cil_tree_log(node, CIL_ERR, " blockinherit"); - } - return SEPOL_ERR; - } - } - } - - for (node = node->cl_head; node; node = node->next) { - rc = cil_check_inheritances(node, max, count, stack, loop); - if (rc != SEPOL_OK) { - return SEPOL_ERR; - } - } - - return SEPOL_OK; -} - -static int cil_check_for_bad_inheritance(struct cil_tree_node *node) -{ - unsigned num_actual, max; - unsigned num_potential = 0; - unsigned loop = CIL_FALSE; - struct cil_stack *stack; - int rc; - - num_actual = cil_count_actual(node); - - max = num_actual * CIL_DEGENERATE_INHERITANCE_GROWTH; - if (max < CIL_DEGENERATE_INHERITANCE_MINIMUM) { - max = CIL_DEGENERATE_INHERITANCE_MINIMUM; - } - - cil_stack_init(&stack); - rc = cil_check_inheritances(node, max, &num_potential, stack, &loop); - cil_stack_destroy(&stack); - - return rc; -} - int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args) { int rc = SEPOL_OK; struct cil_args_resolve *args = extra_args; enum cil_pass pass = 0; + struct cil_list *ins; if (node == NULL || args == NULL) { goto exit; } + ins = args->in_list; pass = args->pass; switch (pass) { @@ -3600,14 +3418,11 @@ int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args) rc = cil_resolve_tunif(node, args); } break; - case CIL_PASS_IN_BEFORE: + case CIL_PASS_IN: if (node->flavor == CIL_IN) { // due to ordering issues, in statements are just gathered here and // resolved together in cil_resolve_in_list once all are found - struct cil_in *in = node->data; - if (in->is_after == CIL_FALSE) { - cil_list_prepend(args->in_list_before, CIL_NODE, node); - } + cil_list_prepend(ins, CIL_NODE, node); } break; case CIL_PASS_BLKIN_LINK: @@ -3625,24 +3440,19 @@ int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args) rc = cil_resolve_blockabstract(node, args); } break; - case CIL_PASS_IN_AFTER: - if (node->flavor == CIL_IN) { - // due to ordering issues, in statements are just gathered here and - // resolved together in cil_resolve_in_list once all are found - struct cil_in *in = node->data; - if (in->is_after == CIL_TRUE) { - cil_list_prepend(args->in_list_after, CIL_NODE, node); - } + case CIL_PASS_MACRO: + if (node->flavor == CIL_CALL && args->macro != NULL) { + rc = cil_resolve_call1(node, args); } break; case CIL_PASS_CALL1: - if (node->flavor == CIL_CALL && args->macro == NULL) { - rc = cil_resolve_call(node, args); + if (node->flavor == CIL_CALL) { + rc = cil_resolve_call1(node, args); } break; case CIL_PASS_CALL2: - if (node->flavor == CIL_CALL && args->macro == NULL) { - rc = cil_resolve_call_args(node, args); + if (node->flavor == CIL_CALL) { + rc = cil_resolve_call2(node, args); } break; case CIL_PASS_ALIAS1: @@ -3875,78 +3685,65 @@ exit: int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) { - int rc = SEPOL_OK; + int rc = SEPOL_ERR; struct cil_args_resolve *args = extra_args; enum cil_pass pass = args->pass; - struct cil_tree_node *block = args->block; - struct cil_tree_node *macro = args->macro; - struct cil_tree_node *optional = args->optional; + struct cil_tree_node *optstack = args->optstack; struct cil_tree_node *boolif = args->boolif; + struct cil_tree_node *blockstack = args->blockstack; + struct cil_tree_node *macro = args->macro; if (node == NULL) { goto exit; } - if (block != NULL) { - if (node->flavor == CIL_CAT || - node->flavor == CIL_SENS) { - cil_tree_log(node, CIL_ERR, "%s is not allowed in block", cil_node_to_string(node)); + if (optstack != NULL) { + if (node->flavor == CIL_TUNABLE || node->flavor == CIL_MACRO) { + /* tuanbles and macros are not allowed in optionals*/ + cil_tree_log(node, CIL_ERR, "%s statement is not allowed in optionals", cil_node_to_string(node)); + rc = SEPOL_ERR; + goto exit; + } + } + + if (blockstack != NULL) { + if (node->flavor == CIL_CAT || node->flavor == CIL_SENS) { + cil_tree_log(node, CIL_ERR, "%s statement is not allowed in blocks", cil_node_to_string(node)); rc = SEPOL_ERR; goto exit; } } if (macro != NULL) { - if (node->flavor == CIL_TUNABLE || - node->flavor == CIL_IN || - node->flavor == CIL_BLOCK || - node->flavor == CIL_BLOCKINHERIT || - node->flavor == CIL_BLOCKABSTRACT || - node->flavor == CIL_MACRO) { - cil_tree_log(node, CIL_ERR, "%s is not allowed in macro", cil_node_to_string(node)); - rc = SEPOL_ERR; - goto exit; - } - } - - if (optional != NULL) { - if (node->flavor == CIL_TUNABLE || - node->flavor == CIL_IN || + if (node->flavor == CIL_BLOCKINHERIT || node->flavor == CIL_BLOCK || node->flavor == CIL_BLOCKABSTRACT || - node->flavor == CIL_MACRO) { - cil_tree_log(node, CIL_ERR, "%s is not allowed in optional", cil_node_to_string(node)); + node->flavor == CIL_MACRO) { + cil_tree_log(node, CIL_ERR, "%s statement is not allowed in macros", cil_node_to_string(node)); rc = SEPOL_ERR; goto exit; } } if (boolif != NULL) { - if (node->flavor != CIL_TUNABLEIF && - node->flavor != CIL_CALL && - node->flavor != CIL_CONDBLOCK && - node->flavor != CIL_AVRULE && - node->flavor != CIL_TYPE_RULE && - node->flavor != CIL_NAMETYPETRANSITION) { - rc = SEPOL_ERR; - } else if (node->flavor == CIL_AVRULE) { - struct cil_avrule *rule = node->data; - if (rule->rule_kind == CIL_AVRULE_NEVERALLOW) { - rc = SEPOL_ERR; - } - } - if (rc == SEPOL_ERR) { + if (!(node->flavor == CIL_CONDBLOCK || + node->flavor == CIL_AVRULE || + node->flavor == CIL_TYPE_RULE || + node->flavor == CIL_CALL || + node->flavor == CIL_TUNABLEIF || + node->flavor == CIL_NAMETYPETRANSITION)) { if (((struct cil_booleanif*)boolif->data)->preserved_tunable) { - cil_tree_log(node, CIL_ERR, "%s is not allowed in tunableif being treated as a booleanif", cil_node_to_string(node)); + cil_tree_log(node, CIL_ERR, "%s statement is not allowed in booleanifs (tunableif treated as a booleanif)", cil_node_to_string(node)); } else { - cil_tree_log(node, CIL_ERR, "%s is not allowed in booleanif", cil_node_to_string(node)); + cil_tree_log(node, CIL_ERR, "%s statement is not allowed in booleanifs", cil_node_to_string(node)); } + rc = SEPOL_ERR; goto exit; } } if (node->flavor == CIL_MACRO) { - if (pass != CIL_PASS_TIF) { + if (pass != CIL_PASS_TIF && pass != CIL_PASS_MACRO) { *finished = CIL_TREE_SKIP_HEAD; rc = SEPOL_OK; goto exit; @@ -3961,16 +3758,22 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished rc = __cil_resolve_ast_node(node, extra_args); if (rc == SEPOL_ENOENT) { - if (optional == NULL) { - cil_tree_log(node, CIL_ERR, "Failed to resolve %s statement", cil_node_to_string(node)); - } else { - if (!args->disabled_optional) { - args->disabled_optional = optional; - } - cil_tree_log(node, CIL_INFO, "Failed to resolve %s statement", cil_node_to_string(node)); - cil_tree_log(optional, CIL_INFO, "Disabling optional '%s'", DATUM(optional->data)->name); + enum cil_log_level lvl = CIL_ERR; + + if (optstack != NULL) { + lvl = CIL_INFO; + + struct cil_optional *opt = (struct cil_optional *)optstack->data; + struct cil_tree_node *opt_node = opt->datum.nodes->head->data; + /* disable an optional if something failed to resolve */ + opt->enabled = CIL_FALSE; + cil_tree_log(node, lvl, "Failed to resolve %s statement", cil_node_to_string(node)); + cil_tree_log(opt_node, lvl, "Disabling optional '%s'", opt->datum.name); rc = SEPOL_OK; + goto exit; } + + cil_tree_log(node, lvl, "Failed to resolve %s statement", cil_node_to_string(node)); goto exit; } @@ -3984,22 +3787,43 @@ int __cil_resolve_ast_first_child_helper(struct cil_tree_node *current, void *ex { int rc = SEPOL_ERR; struct cil_args_resolve *args = extra_args; + struct cil_tree_node *optstack = NULL; struct cil_tree_node *parent = NULL; + struct cil_tree_node *blockstack = NULL; + struct cil_tree_node *new = NULL; if (current == NULL || extra_args == NULL) { goto exit; } + optstack = args->optstack; parent = current->parent; + blockstack = args->blockstack; - if (parent->flavor == CIL_BLOCK) { - args->block = parent; - } else if (parent->flavor == CIL_MACRO) { - args->macro = parent; - } else if (parent->flavor == CIL_OPTIONAL) { - args->optional = parent; + if (parent->flavor == CIL_OPTIONAL || parent->flavor == CIL_BLOCK) { + /* push this node onto a stack */ + cil_tree_node_init(&new); + + new->data = parent->data; + new->flavor = parent->flavor; + + if (parent->flavor == CIL_OPTIONAL) { + if (optstack != NULL) { + optstack->parent = new; + new->cl_head = optstack; + } + args->optstack = new; + } else if (parent->flavor == CIL_BLOCK) { + if (blockstack != NULL) { + blockstack->parent = new; + new->cl_head = blockstack; + } + args->blockstack = new; + } } else if (parent->flavor == CIL_BOOLEANIF) { args->boolif = parent; + } else if (parent->flavor == CIL_MACRO) { + args->macro = parent; } return SEPOL_OK; @@ -4014,6 +3838,7 @@ int __cil_resolve_ast_last_child_helper(struct cil_tree_node *current, void *ext int rc = SEPOL_ERR; struct cil_args_resolve *args = extra_args; struct cil_tree_node *parent = NULL; + struct cil_tree_node *blockstack = NULL; if (current == NULL || extra_args == NULL) { goto exit; @@ -4021,35 +3846,33 @@ int __cil_resolve_ast_last_child_helper(struct cil_tree_node *current, void *ext parent = current->parent; - if (parent->flavor == CIL_BLOCK) { - struct cil_tree_node *n = parent->parent; - args->block = NULL; - while (n && n->flavor != CIL_ROOT) { - if (n->flavor == CIL_BLOCK) { - args->block = n; - break; - } - n = n->parent; - } - } else if (parent->flavor == CIL_MACRO) { + if (parent->flavor == CIL_MACRO) { args->macro = NULL; } else if (parent->flavor == CIL_OPTIONAL) { - struct cil_tree_node *n = parent->parent; - if (args->disabled_optional == parent) { + struct cil_tree_node *optstack; + + if (((struct cil_optional *)parent->data)->enabled == CIL_FALSE) { *(args->changed) = CIL_TRUE; - cil_list_append(args->to_destroy, CIL_NODE, parent); - args->disabled_optional = NULL; + cil_tree_children_destroy(parent); } - args->optional = NULL; - while (n && n->flavor != CIL_ROOT) { - if (n->flavor == CIL_OPTIONAL) { - args->optional = n; - break; - } - n = n->parent; + + /* pop off the stack */ + optstack = args->optstack; + args->optstack = optstack->cl_head; + if (optstack->cl_head) { + optstack->cl_head->parent = NULL; } + free(optstack); } else if (parent->flavor == CIL_BOOLEANIF) { args->boolif = NULL; + } else if (parent->flavor == CIL_BLOCK) { + /* pop off the stack */ + blockstack = args->blockstack; + args->blockstack = blockstack->cl_head; + if (blockstack->cl_head) { + blockstack->cl_head->parent = NULL; + } + free(blockstack); } return SEPOL_OK; @@ -4058,6 +3881,16 @@ exit: return rc; } +static void cil_destroy_tree_node_stack(struct cil_tree_node *curr) +{ + struct cil_tree_node *next; + while (curr != NULL) { + next = curr->cl_head; + free(curr); + curr = next; + } +} + int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current) { int rc = SEPOL_ERR; @@ -4072,28 +3905,24 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current) extra_args.db = db; extra_args.pass = pass; extra_args.changed = &changed; - extra_args.block = NULL; - extra_args.macro = NULL; - extra_args.optional = NULL; - extra_args.disabled_optional = NULL; + extra_args.last_resolved_name = NULL; + extra_args.optstack = NULL; extra_args.boolif= NULL; + extra_args.macro = NULL; extra_args.sidorder_lists = NULL; extra_args.classorder_lists = NULL; extra_args.unordered_classorder_lists = NULL; extra_args.catorder_lists = NULL; extra_args.sensitivityorder_lists = NULL; - extra_args.in_list_before = NULL; - extra_args.in_list_after = NULL; + extra_args.in_list = NULL; + extra_args.blockstack = NULL; - cil_list_init(&extra_args.to_destroy, CIL_NODE); cil_list_init(&extra_args.sidorder_lists, CIL_LIST_ITEM); cil_list_init(&extra_args.classorder_lists, CIL_LIST_ITEM); cil_list_init(&extra_args.unordered_classorder_lists, CIL_LIST_ITEM); cil_list_init(&extra_args.catorder_lists, CIL_LIST_ITEM); cil_list_init(&extra_args.sensitivityorder_lists, CIL_LIST_ITEM); - cil_list_init(&extra_args.in_list_before, CIL_IN); - cil_list_init(&extra_args.in_list_after, CIL_IN); - + cil_list_init(&extra_args.in_list, CIL_IN); for (pass = CIL_PASS_TIF; pass < CIL_PASS_NUM; pass++) { extra_args.pass = pass; rc = cil_tree_walk(current, __cil_resolve_ast_node_helper, __cil_resolve_ast_first_child_helper, __cil_resolve_ast_last_child_helper, &extra_args); @@ -4102,26 +3931,12 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current) goto exit; } - if (pass == CIL_PASS_IN_BEFORE) { - rc = cil_resolve_in_list(extra_args.in_list_before, &extra_args); + if (pass == CIL_PASS_IN) { + rc = cil_resolve_in_list(&extra_args); if (rc != SEPOL_OK) { goto exit; } - cil_list_destroy(&extra_args.in_list_before, CIL_FALSE); - } else if (pass == CIL_PASS_IN_AFTER) { - rc = cil_resolve_in_list(extra_args.in_list_after, &extra_args); - if (rc != SEPOL_OK) { - goto exit; - } - cil_list_destroy(&extra_args.in_list_after, CIL_FALSE); - } - - if (pass == CIL_PASS_BLKIN_LINK) { - rc = cil_check_for_bad_inheritance(current); - if (rc != SEPOL_OK) { - rc = SEPOL_ERR; - goto exit; - } + cil_list_destroy(&extra_args.in_list, CIL_FALSE); } if (pass == CIL_PASS_MISC1) { @@ -4168,54 +3983,46 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current) } } - if (changed) { - struct cil_list_item *item; - if (pass > CIL_PASS_CALL1) { - int has_decls = CIL_FALSE; + if (changed && (pass > CIL_PASS_CALL1)) { + /* Need to re-resolve because an optional was disabled that contained + * one or more declarations. We only need to reset to the call1 pass + * because things done in the preceding passes aren't allowed in + * optionals, and thus can't be disabled. + * Note: set pass to CIL_PASS_CALL1 because the pass++ will increment + * it to CIL_PASS_CALL2 + */ + cil_log(CIL_INFO, "Resetting declarations\n"); - cil_list_for_each(item, extra_args.to_destroy) { - has_decls = cil_tree_subtree_has_decl(item->data); - if (has_decls) { - break; - } - } - - if (has_decls) { - /* Need to re-resolve because an optional was disabled that - * contained one or more declarations. - * Everything that needs to be reset comes after the - * CIL_PASS_CALL2 pass. We set pass to CIL_PASS_CALL1 because - * the pass++ will increment it to CIL_PASS_CALL2 - */ - cil_log(CIL_INFO, "Resetting declarations\n"); - - if (pass >= CIL_PASS_MISC1) { - __cil_ordered_lists_reset(&extra_args.sidorder_lists); - __cil_ordered_lists_reset(&extra_args.classorder_lists); - __cil_ordered_lists_reset(&extra_args.unordered_classorder_lists); - __cil_ordered_lists_reset(&extra_args.catorder_lists); - __cil_ordered_lists_reset(&extra_args.sensitivityorder_lists); - cil_list_destroy(&db->sidorder, CIL_FALSE); - cil_list_destroy(&db->classorder, CIL_FALSE); - cil_list_destroy(&db->catorder, CIL_FALSE); - cil_list_destroy(&db->sensitivityorder, CIL_FALSE); - } - - pass = CIL_PASS_CALL1; - - rc = cil_reset_ast(current); - if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Failed to reset declarations\n"); - goto exit; - } - } + if (pass >= CIL_PASS_MISC1) { + __cil_ordered_lists_reset(&extra_args.sidorder_lists); + __cil_ordered_lists_reset(&extra_args.classorder_lists); + __cil_ordered_lists_reset(&extra_args.unordered_classorder_lists); + __cil_ordered_lists_reset(&extra_args.catorder_lists); + __cil_ordered_lists_reset(&extra_args.sensitivityorder_lists); + cil_list_destroy(&db->sidorder, CIL_FALSE); + cil_list_destroy(&db->classorder, CIL_FALSE); + cil_list_destroy(&db->catorder, CIL_FALSE); + cil_list_destroy(&db->sensitivityorder, CIL_FALSE); } - cil_list_for_each(item, extra_args.to_destroy) { - cil_tree_children_destroy(item->data); + + pass = CIL_PASS_CALL1; + + rc = cil_reset_ast(current); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Failed to reset declarations\n"); + goto exit; } - cil_list_destroy(&extra_args.to_destroy, CIL_FALSE); - cil_list_init(&extra_args.to_destroy, CIL_NODE); - changed = 0; + } + + /* reset the arguments */ + changed = 0; + while (extra_args.optstack != NULL) { + cil_destroy_tree_node_stack(extra_args.optstack); + extra_args.optstack = NULL; + } + while (extra_args.blockstack!= NULL) { + cil_destroy_tree_node_stack(extra_args.blockstack); + extra_args.blockstack = NULL; } } @@ -4226,14 +4033,14 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current) rc = SEPOL_OK; exit: + cil_destroy_tree_node_stack(extra_args.optstack); + cil_destroy_tree_node_stack(extra_args.blockstack); __cil_ordered_lists_destroy(&extra_args.sidorder_lists); __cil_ordered_lists_destroy(&extra_args.classorder_lists); __cil_ordered_lists_destroy(&extra_args.catorder_lists); __cil_ordered_lists_destroy(&extra_args.sensitivityorder_lists); __cil_ordered_lists_destroy(&extra_args.unordered_classorder_lists); - cil_list_destroy(&extra_args.to_destroy, CIL_FALSE); - cil_list_destroy(&extra_args.in_list_before, CIL_FALSE); - cil_list_destroy(&extra_args.in_list_after, CIL_FALSE); + cil_list_destroy(&extra_args.in_list, CIL_FALSE); return rc; } @@ -4264,7 +4071,7 @@ static int __cil_resolve_name_with_parents(struct cil_tree_node *node, char *nam rc = __cil_resolve_name_with_parents(node->parent, name, sym_index, datum); if (rc != SEPOL_OK) { /* Continue search in original block's parent */ - rc = __cil_resolve_name_with_parents(NODE(inherit->block)->parent, name, sym_index, datum); + rc = __cil_resolve_name_with_parents(NODE(inherit->block), name, sym_index, datum); goto exit; } } @@ -4277,18 +4084,10 @@ static int __cil_resolve_name_with_parents(struct cil_tree_node *node, char *nam break; case CIL_CALL: { struct cil_call *call = node->data; - struct cil_macro *macro = call->macro; - symtab = ¯o->symtab[sym_index]; - rc = cil_symtab_get_datum(symtab, name, datum); - if (rc == SEPOL_OK) { - /* If the name was declared in the macro, just look on the call side */ - rc = SEPOL_ERR; - } else { - rc = cil_resolve_name_call_args(call, name, sym_index, datum); - if (rc != SEPOL_OK) { - /* Continue search in macro's parent */ - rc = __cil_resolve_name_with_parents(NODE(call->macro)->parent, name, sym_index, datum); - } + rc = cil_resolve_name_call_args(call, name, sym_index, datum); + if (rc != SEPOL_OK) { + /* Continue search in macro's parent */ + rc = __cil_resolve_name_with_parents(NODE(call->macro)->parent, name, sym_index, datum); } } break; @@ -4360,8 +4159,8 @@ int cil_resolve_name_keep_aliases(struct cil_tree_node *ast_node, char *name, en *datum = NULL; - if (db->qualified_names || strchr(name,'.') == NULL) { - /* Using qualified names or No '.' in name */ + if (strchr(name,'.') == NULL) { + /* No '.' in name */ rc = __cil_resolve_name_helper(db, ast_node->parent, name, sym_index, datum); if (rc != SEPOL_OK) { goto exit; @@ -4412,6 +4211,9 @@ int cil_resolve_name_keep_aliases(struct cil_tree_node *ast_node, char *name, en if (node->flavor == CIL_MACRO) { struct cil_macro *macro = node->data; symtab = ¯o->symtab[sym_index]; + } else { + /* optional */ + symtab = (*datum)->symtab; } } current = next; @@ -4432,5 +4234,7 @@ exit: *datum = NULL; } + args->last_resolved_name = name; + return rc; } diff --git a/libsepol/cil/src/cil_stack.c b/libsepol/cil/src/cil_stack.c index 70a77bc1..bbfb961a 100644 --- a/libsepol/cil/src/cil_stack.c +++ b/libsepol/cil/src/cil_stack.c @@ -67,11 +67,6 @@ int cil_stack_is_empty(struct cil_stack *stack) return (stack->pos == -1); } -int cil_stack_number_of_items(struct cil_stack *stack) -{ - return stack->pos + 1; -} - void cil_stack_push(struct cil_stack *stack, enum cil_flavor flavor, void *data) { stack->pos++; diff --git a/libsepol/cil/src/cil_stack.h b/libsepol/cil/src/cil_stack.h index 0e3eff66..b78535ac 100644 --- a/libsepol/cil/src/cil_stack.h +++ b/libsepol/cil/src/cil_stack.h @@ -52,7 +52,6 @@ void cil_stack_destroy(struct cil_stack **stack); void cil_stack_empty(struct cil_stack *stack); int cil_stack_is_empty(struct cil_stack *stack); -int cil_stack_number_of_items(struct cil_stack *stack); void cil_stack_push(struct cil_stack *stack, enum cil_flavor flavor, void *data); struct cil_stack_item *cil_stack_pop(struct cil_stack *stack); diff --git a/libsepol/cil/src/cil_strpool.c b/libsepol/cil/src/cil_strpool.c index e32ee4e9..2598bbf3 100644 --- a/libsepol/cil/src/cil_strpool.c +++ b/libsepol/cil/src/cil_strpool.c @@ -47,13 +47,14 @@ static hashtab_t cil_strpool_tab = NULL; static unsigned int cil_strpool_hash(hashtab_t h, const_hashtab_key_t key) { - const char *p; + const char *p, *keyp; size_t size; unsigned int val; val = 0; - size = strlen(key); - for (p = key; ((size_t) (p - key)) < size; p++) + keyp = (const char*)key; + size = strlen(keyp); + for (p = keyp; ((size_t) (p - keyp)) < size; p++) val = (val << 4 | (val >> (8 * sizeof(unsigned int) - 4))) ^ (*p); return val & (h->size - 1); @@ -61,7 +62,9 @@ static unsigned int cil_strpool_hash(hashtab_t h, const_hashtab_key_t key) static int cil_strpool_compare(hashtab_t h __attribute__ ((unused)), const_hashtab_key_t key1, const_hashtab_key_t key2) { - return strcmp(key1, key2); + const char *keyp1 = (const char*)key1; + const char *keyp2 = (const char*)key2; + return strcmp(keyp1, keyp2); } char *cil_strpool_add(const char *str) @@ -70,12 +73,11 @@ char *cil_strpool_add(const char *str) pthread_mutex_lock(&cil_strpool_mutex); - strpool_ref = hashtab_search(cil_strpool_tab, str); + strpool_ref = hashtab_search(cil_strpool_tab, (hashtab_key_t)str); if (strpool_ref == NULL) { - int rc; strpool_ref = cil_malloc(sizeof(*strpool_ref)); strpool_ref->str = cil_strdup(str); - rc = hashtab_insert(cil_strpool_tab, strpool_ref->str, strpool_ref); + int rc = hashtab_insert(cil_strpool_tab, (hashtab_key_t)strpool_ref->str, strpool_ref); if (rc != SEPOL_OK) { pthread_mutex_unlock(&cil_strpool_mutex); cil_log(CIL_ERR, "Failed to allocate memory\n"); diff --git a/libsepol/cil/src/cil_symtab.c b/libsepol/cil/src/cil_symtab.c index c1951560..2970b863 100644 --- a/libsepol/cil/src/cil_symtab.c +++ b/libsepol/cil/src/cil_symtab.c @@ -92,11 +92,10 @@ int cil_symtab_insert(symtab_t *symtab, hashtab_key_t key, struct cil_symtab_dat datum->name = key; datum->fqn = key; datum->symtab = symtab; - symtab->nprim++; - if (node) { - cil_list_append(datum->nodes, CIL_NODE, node); - } - } else if (rc != SEPOL_EEXIST) { + cil_list_append(datum->nodes, CIL_NODE, node); + } else if (rc == SEPOL_EEXIST) { + cil_list_append(datum->nodes, CIL_NODE, node); + } else { cil_symtab_error("Failed to insert datum into hashtab\n"); } @@ -112,7 +111,6 @@ void cil_symtab_remove_datum(struct cil_symtab_datum *datum) } hashtab_remove(symtab->table, datum->name, NULL, NULL); - symtab->nprim--; datum->symtab = NULL; } diff --git a/libsepol/cil/src/cil_tree.c b/libsepol/cil/src/cil_tree.c index aafc9dee..b1cbda91 100644 --- a/libsepol/cil/src/cil_tree.c +++ b/libsepol/cil/src/cil_tree.c @@ -41,6 +41,15 @@ #include "cil_parser.h" #include "cil_strpool.h" +void cil_tree_print_perms_list(struct cil_tree_node *current_perm); +void cil_tree_print_classperms(struct cil_classperms *cp); +void cil_tree_print_level(struct cil_level *level); +void cil_tree_print_levelrange(struct cil_levelrange *lvlrange); +void cil_tree_print_context(struct cil_context *context); +void cil_tree_print_expr_tree(struct cil_tree_node *expr_root); +void cil_tree_print_constrain(struct cil_constrain *cons); +void cil_tree_print_node(struct cil_tree_node *node); + __attribute__((noreturn)) __attribute__((format (printf, 1, 2))) void cil_tree_error(const char* msg, ...) { va_list ap; @@ -50,38 +59,28 @@ __attribute__((noreturn)) __attribute__((format (printf, 1, 2))) void cil_tree_e exit(1); } -struct cil_tree_node *cil_tree_get_next_path(struct cil_tree_node *node, char **info_kind, uint32_t *hll_line, char **path) +struct cil_tree_node *cil_tree_get_next_path(struct cil_tree_node *node, char **path, int* is_cil) { - int rc; - if (!node) { - goto exit; + return NULL; } node = node->parent; while (node) { if (node->flavor == CIL_NODE && node->data == NULL) { - if (node->cl_head && node->cl_head->data == CIL_KEY_SRC_INFO) { - if (!node->cl_head->next || !node->cl_head->next->next || !node->cl_head->next->next->next) { - goto exit; - } + if (node->cl_head->data == CIL_KEY_SRC_INFO) { /* Parse Tree */ - *info_kind = node->cl_head->next->data; - rc = cil_string_to_uint32(node->cl_head->next->next->data, hll_line, 10); - if (rc != SEPOL_OK) { - goto exit; - } - *path = node->cl_head->next->next->next->data; + *path = node->cl_head->next->next->data; + *is_cil = (node->cl_head->next->data == CIL_KEY_SRC_CIL); return node; } node = node->parent; } else if (node->flavor == CIL_SRC_INFO) { /* AST */ struct cil_src_info *info = node->data; - *info_kind = info->kind; - *hll_line = info->hll_line; *path = info->path; + *is_cil = info->is_cil; return node; } else { if (node->flavor == CIL_CALL) { @@ -96,22 +95,17 @@ struct cil_tree_node *cil_tree_get_next_path(struct cil_tree_node *node, char ** } } -exit: - *info_kind = NULL; - *hll_line = 0; - *path = NULL; return NULL; } char *cil_tree_get_cil_path(struct cil_tree_node *node) { - char *info_kind; - uint32_t hll_line; - char *path; + char *path = NULL; + int is_cil; while (node) { - node = cil_tree_get_next_path(node, &info_kind, &hll_line, &path); - if (node && info_kind == CIL_KEY_SRC_CIL) { + node = cil_tree_get_next_path(node, &path, &is_cil); + if (node && is_cil) { return path; } } @@ -129,51 +123,28 @@ __attribute__((format (printf, 3, 4))) void cil_tree_log(struct cil_tree_node *n if (node) { char *path = NULL; - uint32_t hll_offset = node->hll_offset; + int is_cil; + unsigned hll_line = node->hll_line; path = cil_tree_get_cil_path(node); if (path != NULL) { - cil_log(lvl, " at %s:%u", path, node->line); + cil_log(lvl, " at %s:%d", path, node->line); } while (node) { - do { - char *info_kind; - uint32_t hll_line; - - node = cil_tree_get_next_path(node, &info_kind, &hll_line, &path); - if (!node || info_kind == CIL_KEY_SRC_CIL) { - break; - } - if (info_kind == CIL_KEY_SRC_HLL_LMS) { - hll_line += hll_offset - node->hll_offset - 1; - } - - cil_log(lvl," from %s:%u", path, hll_line); - } while (1); + node = cil_tree_get_next_path(node, &path, &is_cil); + if (node && !is_cil) { + cil_log(lvl," from %s:%d", path, hll_line); + path = NULL; + hll_line = node->hll_line; + } } } cil_log(lvl,"\n"); } -int cil_tree_subtree_has_decl(struct cil_tree_node *node) -{ - while (node) { - if (node->flavor >= CIL_MIN_DECLARATIVE) { - return CIL_TRUE; - } - if (node->cl_head != NULL) { - if (cil_tree_subtree_has_decl(node->cl_head)) - return CIL_TRUE; - } - node = node->next; - } - - return CIL_FALSE; -} - int cil_tree_init(struct cil_tree **tree) { struct cil_tree *new_tree = cil_malloc(sizeof(*new_tree)); @@ -204,21 +175,34 @@ void cil_tree_subtree_destroy(struct cil_tree_node *node) void cil_tree_children_destroy(struct cil_tree_node *node) { - struct cil_tree_node *curr, *next; + struct cil_tree_node *start_node = node; + struct cil_tree_node *next = NULL; - if (!node) { + if (node == NULL) { return; } - curr = node->cl_head; - while (curr) { - next = curr->next; - cil_tree_children_destroy(curr); - cil_tree_node_destroy(&curr); - curr = next; + if (node->cl_head != NULL) { + node = node->cl_head; + } + + while (node != start_node) { + if (node->cl_head != NULL){ + next = node->cl_head; + } else { + if (node->next == NULL) { + next = node->parent; + if (node->parent != NULL) { + node->parent->cl_head = NULL; + } + cil_tree_node_destroy(&node); + } else { + next = node->next; + cil_tree_node_destroy(&node); + } + } + node = next; } - node->cl_head = NULL; - node->cl_tail = NULL; } void cil_tree_node_init(struct cil_tree_node **node) @@ -231,7 +215,7 @@ void cil_tree_node_init(struct cil_tree_node **node) new_node->next = NULL; new_node->flavor = CIL_ROOT; new_node->line = 0; - new_node->hll_offset = 0; + new_node->hll_line = 0; *node = new_node; } @@ -344,3 +328,1466 @@ int cil_tree_walk(struct cil_tree_node *node, return SEPOL_OK; } + + +/* Copied from cil_policy.c, but changed to prefix -- Need to refactor */ +static int cil_expr_to_string(struct cil_list *expr, char **out) +{ + int rc = SEPOL_ERR; + struct cil_list_item *curr; + char *stack[COND_EXPR_MAXDEPTH] = {}; + int pos = 0; + + cil_list_for_each(curr, expr) { + if (pos >= COND_EXPR_MAXDEPTH) { + rc = SEPOL_ERR; + goto exit; + } + switch (curr->flavor) { + case CIL_LIST: + rc = cil_expr_to_string(curr->data, &stack[pos]); + if (rc != SEPOL_OK) { + goto exit; + } + pos++; + break; + case CIL_STRING: + stack[pos] = curr->data; + pos++; + break; + case CIL_DATUM: + stack[pos] = ((struct cil_symtab_datum *)curr->data)->name; + pos++; + break; + case CIL_OP: { + int len; + char *expr_str; + enum cil_flavor op_flavor = *((enum cil_flavor *)curr->data); + char *op_str = NULL; + + if (pos == 0) { + rc = SEPOL_ERR; + goto exit; + } + switch (op_flavor) { + case CIL_AND: + op_str = CIL_KEY_AND; + break; + case CIL_OR: + op_str = CIL_KEY_OR; + break; + case CIL_NOT: + op_str = CIL_KEY_NOT; + break; + case CIL_ALL: + op_str = CIL_KEY_ALL; + break; + case CIL_EQ: + op_str = CIL_KEY_EQ; + break; + case CIL_NEQ: + op_str = CIL_KEY_NEQ; + break; + case CIL_XOR: + op_str = CIL_KEY_XOR; + break; + case CIL_RANGE: + op_str = CIL_KEY_RANGE; + break; + case CIL_CONS_DOM: + op_str = CIL_KEY_CONS_DOM; + break; + case CIL_CONS_DOMBY: + op_str = CIL_KEY_CONS_DOMBY; + break; + case CIL_CONS_INCOMP: + op_str = CIL_KEY_CONS_INCOMP; + break; + default: + cil_log(CIL_ERR, "Unknown operator in expression\n"); + goto exit; + break; + } + if (op_flavor == CIL_NOT) { + len = strlen(stack[pos-1]) + strlen(op_str) + 4; + expr_str = cil_malloc(len); + snprintf(expr_str, len, "(%s %s)", op_str, stack[pos-1]); + free(stack[pos-1]); + stack[pos-1] = NULL; + pos--; + } else { + if (pos < 2) { + rc = SEPOL_ERR; + goto exit; + } + len = strlen(stack[pos-1]) + strlen(stack[pos-2]) + strlen(op_str) + 5; + expr_str = cil_malloc(len); + snprintf(expr_str, len, "(%s %s %s)", op_str, stack[pos-1], stack[pos-2]); + free(stack[pos-2]); + free(stack[pos-1]); + stack[pos-2] = NULL; + stack[pos-1] = NULL; + pos -= 2; + } + stack[pos] = expr_str; + pos++; + break; + } + case CIL_CONS_OPERAND: { + enum cil_flavor operand_flavor = *((enum cil_flavor *)curr->data); + char *operand_str = NULL; + switch (operand_flavor) { + case CIL_CONS_U1: + operand_str = CIL_KEY_CONS_U1; + break; + case CIL_CONS_U2: + operand_str = CIL_KEY_CONS_U2; + break; + case CIL_CONS_U3: + operand_str = CIL_KEY_CONS_U3; + break; + case CIL_CONS_T1: + operand_str = CIL_KEY_CONS_T1; + break; + case CIL_CONS_T2: + operand_str = CIL_KEY_CONS_T2; + break; + case CIL_CONS_T3: + operand_str = CIL_KEY_CONS_T3; + break; + case CIL_CONS_R1: + operand_str = CIL_KEY_CONS_R1; + break; + case CIL_CONS_R2: + operand_str = CIL_KEY_CONS_R2; + break; + case CIL_CONS_R3: + operand_str = CIL_KEY_CONS_R3; + break; + case CIL_CONS_L1: + operand_str = CIL_KEY_CONS_L1; + break; + case CIL_CONS_L2: + operand_str = CIL_KEY_CONS_L2; + break; + case CIL_CONS_H1: + operand_str = CIL_KEY_CONS_H1; + break; + case CIL_CONS_H2: + operand_str = CIL_KEY_CONS_H2; + break; + default: + cil_log(CIL_ERR, "Unknown operand in expression\n"); + goto exit; + break; + } + stack[pos] = operand_str; + pos++; + break; + } + default: + cil_log(CIL_ERR, "Unknown flavor in expression\n"); + goto exit; + break; + } + } + + *out = stack[0]; + + return SEPOL_OK; + +exit: + return rc; +} + +void cil_tree_print_expr(struct cil_list *datum_expr, struct cil_list *str_expr) +{ + char *expr_str; + int rc; + + cil_log(CIL_INFO, "("); + + if (datum_expr != NULL) { + rc = cil_expr_to_string(datum_expr, &expr_str); + } else { + rc = cil_expr_to_string(str_expr, &expr_str); + } + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "ERROR)"); + return; + } + cil_log(CIL_INFO, "%s)", expr_str); + free(expr_str); +} + +void cil_tree_print_perms_list(struct cil_tree_node *current_perm) +{ + while (current_perm != NULL) { + if (current_perm->flavor == CIL_PERM) { + cil_log(CIL_INFO, " %s", ((struct cil_perm *)current_perm->data)->datum.name); + } else if (current_perm->flavor == CIL_MAP_PERM) { + cil_log(CIL_INFO, " %s", ((struct cil_perm*)current_perm->data)->datum.name); + } else { + cil_log(CIL_INFO, "\n\n perms list contained unexpected data type: %d\n", current_perm->flavor); + break; + } + current_perm = current_perm->next; + } +} + +void cil_tree_print_cats(struct cil_cats *cats) +{ + cil_tree_print_expr(cats->datum_expr, cats->str_expr); +} + +void cil_tree_print_perm_strs(struct cil_list *perm_strs) +{ + struct cil_list_item *curr; + + if (perm_strs == NULL) { + return; + } + + cil_log(CIL_INFO, " ("); + + cil_list_for_each(curr, perm_strs) { + cil_log(CIL_INFO, " %s", (char*)curr->data); + } + + cil_log(CIL_INFO, " )"); +} + + +void cil_tree_print_classperms(struct cil_classperms *cp) +{ + if (cp == NULL) { + return; + } + + cil_log(CIL_INFO, " class: %s", cp->class_str); + cil_log(CIL_INFO, ", perm_strs:"); + cil_tree_print_perm_strs(cp->perm_strs); +} + +void cil_tree_print_classperms_set(struct cil_classperms_set *cp_set) +{ + if (cp_set == NULL) { + return; + } + + cil_log(CIL_INFO, " %s", cp_set->set_str); +} + +void cil_tree_print_classperms_list(struct cil_list *cp_list) +{ + struct cil_list_item *i; + + if (cp_list == NULL) { + return; + } + + cil_list_for_each(i, cp_list) { + if (i->flavor == CIL_CLASSPERMS) { + cil_tree_print_classperms(i->data); + } else { + cil_tree_print_classperms_set(i->data); + } + } +} + +void cil_tree_print_level(struct cil_level *level) +{ + if (level->sens != NULL) { + cil_log(CIL_INFO, " %s", level->sens->datum.name); + } else if (level->sens_str != NULL) { + cil_log(CIL_INFO, " %s", level->sens_str); + } + + cil_tree_print_cats(level->cats); + + return; +} + +void cil_tree_print_levelrange(struct cil_levelrange *lvlrange) +{ + cil_log(CIL_INFO, " ("); + if (lvlrange->low != NULL) { + cil_log(CIL_INFO, " ("); + cil_tree_print_level(lvlrange->low); + cil_log(CIL_INFO, " )"); + } else if (lvlrange->low_str != NULL) { + cil_log(CIL_INFO, " %s", lvlrange->low_str); + } + + if (lvlrange->high != NULL) { + cil_log(CIL_INFO, " ("); + cil_tree_print_level(lvlrange->high); + cil_log(CIL_INFO, " )"); + } else if (lvlrange->high_str != NULL) { + cil_log(CIL_INFO, " %s", lvlrange->high_str); + } + cil_log(CIL_INFO, " )"); +} + +void cil_tree_print_context(struct cil_context *context) +{ + cil_log(CIL_INFO, " ("); + if (context->user != NULL) { + cil_log(CIL_INFO, " %s", context->user->datum.name); + } else if (context->user_str != NULL) { + cil_log(CIL_INFO, " %s", context->user_str); + } + + if (context->role != NULL) { + cil_log(CIL_INFO, " %s", context->role->datum.name); + } else if (context->role_str != NULL) { + cil_log(CIL_INFO, " %s", context->role_str); + } + + if (context->type != NULL) { + cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)context->type)->name); + } else if (context->type_str != NULL) { + cil_log(CIL_INFO, " %s", context->type_str); + } + + if (context->range != NULL) { + cil_tree_print_levelrange(context->range); + } else if (context->range_str != NULL) { + cil_log(CIL_INFO, " %s", context->range_str); + } + + cil_log(CIL_INFO, " )"); + + return; +} + +void cil_tree_print_constrain(struct cil_constrain *cons) +{ + cil_tree_print_classperms_list(cons->classperms); + + cil_tree_print_expr(cons->datum_expr, cons->str_expr); + + cil_log(CIL_INFO, "\n"); +} + +void cil_tree_print_node(struct cil_tree_node *node) +{ + if (node->data == NULL) { + cil_log(CIL_INFO, "FLAVOR: %d", node->flavor); + return; + } else { + switch( node->flavor ) { + case CIL_BLOCK: { + struct cil_block *block = node->data; + cil_log(CIL_INFO, "BLOCK: %s\n", block->datum.name); + return; + } + case CIL_BLOCKINHERIT: { + struct cil_blockinherit *inherit = node->data; + cil_log(CIL_INFO, "BLOCKINHERIT: %s\n", inherit->block_str); + return; + } + case CIL_BLOCKABSTRACT: { + struct cil_blockabstract *abstract = node->data; + cil_log(CIL_INFO, "BLOCKABSTRACT: %s\n", abstract->block_str); + return; + } + case CIL_IN: { + struct cil_in *in = node->data; + cil_log(CIL_INFO, "IN: %s\n", in->block_str); + return; + } + case CIL_USER: { + struct cil_user *user = node->data; + cil_log(CIL_INFO, "USER: %s\n", user->datum.name); + return; + } + case CIL_TYPE: { + struct cil_type *type = node->data; + cil_log(CIL_INFO, "TYPE: %s\n", type->datum.name); + return; + } + case CIL_EXPANDTYPEATTRIBUTE: { + struct cil_expandtypeattribute *attr = node->data; + + fprintf(stderr, "%s %u\n", __func__, __LINE__); + cil_log(CIL_INFO, "(EXPANDTYPEATTRIBUTE "); + cil_tree_print_expr(attr->attr_datums, attr->attr_strs); + cil_log(CIL_INFO, "%s)\n",attr->expand ? + CIL_KEY_CONDTRUE : CIL_KEY_CONDFALSE); + + return; + } + case CIL_TYPEATTRIBUTESET: { + struct cil_typeattributeset *attr = node->data; + + cil_log(CIL_INFO, "(TYPEATTRIBUTESET %s ", attr->attr_str); + + cil_tree_print_expr(attr->datum_expr, attr->str_expr); + + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_TYPEATTRIBUTE: { + struct cil_typeattribute *attr = node->data; + cil_log(CIL_INFO, "TYPEATTRIBUTE: %s\n", attr->datum.name); + return; + } + case CIL_ROLE: { + struct cil_role *role = node->data; + cil_log(CIL_INFO, "ROLE: %s\n", role->datum.name); + return; + } + case CIL_USERROLE: { + struct cil_userrole *userrole = node->data; + cil_log(CIL_INFO, "USERROLE:"); + struct cil_symtab_datum *datum = NULL; + + if (userrole->user != NULL) { + datum = userrole->user; + cil_log(CIL_INFO, " %s", datum->name); + } else if (userrole->user_str != NULL) { + cil_log(CIL_INFO, " %s", userrole->user_str); + } + + if (userrole->role != NULL) { + datum = userrole->role; + cil_log(CIL_INFO, " %s", datum->name); + } else if (userrole->role_str != NULL) { + cil_log(CIL_INFO, " %s", userrole->role_str); + } + + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_USERLEVEL: { + struct cil_userlevel *usrlvl = node->data; + cil_log(CIL_INFO, "USERLEVEL:"); + + if (usrlvl->user_str != NULL) { + cil_log(CIL_INFO, " %s", usrlvl->user_str); + } + + if (usrlvl->level != NULL) { + cil_log(CIL_INFO, " ("); + cil_tree_print_level(usrlvl->level); + cil_log(CIL_INFO, " )"); + } else if (usrlvl->level_str != NULL) { + cil_log(CIL_INFO, " %s", usrlvl->level_str); + } + + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_USERRANGE: { + struct cil_userrange *userrange = node->data; + cil_log(CIL_INFO, "USERRANGE:"); + + if (userrange->user_str != NULL) { + cil_log(CIL_INFO, " %s", userrange->user_str); + } + + if (userrange->range != NULL) { + cil_log(CIL_INFO, " ("); + cil_tree_print_levelrange(userrange->range); + cil_log(CIL_INFO, " )"); + } else if (userrange->range_str != NULL) { + cil_log(CIL_INFO, " %s", userrange->range_str); + } + + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_USERBOUNDS: { + struct cil_bounds *bnds = node->data; + cil_log(CIL_INFO, "USERBOUNDS: user: %s, bounds: %s\n", bnds->parent_str, bnds->child_str); + return; + } + case CIL_ROLETYPE: { + struct cil_roletype *roletype = node->data; + struct cil_symtab_datum *datum = NULL; + cil_log(CIL_INFO, "ROLETYPE:"); + + if (roletype->role != NULL) { + datum = roletype->role; + cil_log(CIL_INFO, " %s", datum->name); + } else if (roletype->role_str != NULL) { + cil_log(CIL_INFO, " %s", roletype->role_str); + } + + if (roletype->type != NULL) { + datum = roletype->type; + cil_log(CIL_INFO, " %s", datum->name); + } else if (roletype->type_str != NULL) { + cil_log(CIL_INFO, " %s", roletype->type_str); + } + + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_ROLETRANSITION: { + struct cil_roletransition *roletrans = node->data; + cil_log(CIL_INFO, "ROLETRANSITION:"); + + if (roletrans->src != NULL) { + cil_log(CIL_INFO, " %s", roletrans->src->datum.name); + } else { + cil_log(CIL_INFO, " %s", roletrans->src_str); + } + + if (roletrans->tgt != NULL) { + cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)roletrans->tgt)->name); + } else { + cil_log(CIL_INFO, " %s", roletrans->tgt_str); + } + + if (roletrans->obj != NULL) { + cil_log(CIL_INFO, " %s", roletrans->obj->datum.name); + } else { + cil_log(CIL_INFO, " %s", roletrans->obj_str); + } + + if (roletrans->result != NULL) { + cil_log(CIL_INFO, " %s\n", roletrans->result->datum.name); + } else { + cil_log(CIL_INFO, " %s\n", roletrans->result_str); + } + + return; + } + case CIL_ROLEALLOW: { + struct cil_roleallow *roleallow = node->data; + cil_log(CIL_INFO, "ROLEALLOW:"); + + if (roleallow->src != NULL) { + cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum*)roleallow->src)->name); + } else { + cil_log(CIL_INFO, " %s", roleallow->src_str); + } + + if (roleallow->tgt != NULL) { + cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum*)roleallow->tgt)->name); + } else { + cil_log(CIL_INFO, " %s", roleallow->tgt_str); + } + + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_ROLEATTRIBUTESET: { + struct cil_roleattributeset *attr = node->data; + + cil_log(CIL_INFO, "(ROLEATTRIBUTESET %s ", attr->attr_str); + + cil_tree_print_expr(attr->datum_expr, attr->str_expr); + + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_ROLEATTRIBUTE: { + struct cil_roleattribute *attr = node->data; + cil_log(CIL_INFO, "ROLEATTRIBUTE: %s\n", attr->datum.name); + return; + } + case CIL_USERATTRIBUTESET: { + struct cil_userattributeset *attr = node->data; + + cil_log(CIL_INFO, "(USERATTRIBUTESET %s ", attr->attr_str); + + cil_tree_print_expr(attr->datum_expr, attr->str_expr); + + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_USERATTRIBUTE: { + struct cil_userattribute *attr = node->data; + cil_log(CIL_INFO, "USERATTRIBUTE: %s\n", attr->datum.name); + return; + } + case CIL_ROLEBOUNDS: { + struct cil_bounds *bnds = node->data; + cil_log(CIL_INFO, "ROLEBOUNDS: role: %s, bounds: %s\n", bnds->parent_str, bnds->child_str); + return; + } + case CIL_CLASS: { + struct cil_class *cls = node->data; + cil_log(CIL_INFO, "CLASS: %s ", cls->datum.name); + + if (cls->common != NULL) { + cil_log(CIL_INFO, "inherits: %s ", cls->common->datum.name); + } + cil_log(CIL_INFO, "("); + + cil_tree_print_perms_list(node->cl_head); + + cil_log(CIL_INFO, " )"); + return; + } + case CIL_CLASSORDER: { + struct cil_classorder *classorder = node->data; + struct cil_list_item *class; + + if (classorder->class_list_str == NULL) { + cil_log(CIL_INFO, "CLASSORDER: ()\n"); + return; + } + + cil_log(CIL_INFO, "CLASSORDER: ("); + cil_list_for_each(class, classorder->class_list_str) { + cil_log(CIL_INFO, " %s", (char*)class->data); + } + cil_log(CIL_INFO, " )\n"); + return; + } + case CIL_COMMON: { + struct cil_class *common = node->data; + cil_log(CIL_INFO, "COMMON: %s (", common->datum.name); + + cil_tree_print_perms_list(node->cl_head); + + cil_log(CIL_INFO, " )"); + return; + } + case CIL_CLASSCOMMON: { + struct cil_classcommon *clscom = node->data; + + cil_log(CIL_INFO, "CLASSCOMMON: class: %s, common: %s\n", clscom->class_str, clscom->common_str); + + return; + } + case CIL_CLASSPERMISSION: { + struct cil_classpermission *cp = node->data; + + cil_log(CIL_INFO, "CLASSPERMISSION: %s", cp->datum.name); + + cil_log(CIL_INFO, "\n"); + + return; + } + case CIL_CLASSPERMISSIONSET: { + struct cil_classpermissionset *cps = node->data; + + cil_log(CIL_INFO, "CLASSPERMISSIONSET: %s", cps->set_str); + + cil_tree_print_classperms_list(cps->classperms); + + cil_log(CIL_INFO, "\n"); + + return; + } + case CIL_MAP_CLASS: { + struct cil_class *cm = node->data; + cil_log(CIL_INFO, "MAP_CLASS: %s", cm->datum.name); + + cil_log(CIL_INFO, " ("); + cil_tree_print_perms_list(node->cl_head); + cil_log(CIL_INFO, " )\n"); + + return; + } + case CIL_MAP_PERM: { + struct cil_perm *cmp = node->data; + + cil_log(CIL_INFO, "MAP_PERM: %s", cmp->datum.name); + + if (cmp->classperms == NULL) { + cil_log(CIL_INFO, " perms: ()"); + return; + } + + cil_log(CIL_INFO, " kernel class perms: ("); + + cil_tree_print_classperms_list(cmp->classperms); + + cil_log(CIL_INFO, " )\n"); + + return; + } + case CIL_CLASSMAPPING: { + struct cil_classmapping *mapping = node->data; + + cil_log(CIL_INFO, "CLASSMAPPING: map class: %s, map perm: %s,", mapping->map_class_str, mapping->map_perm_str); + + cil_log(CIL_INFO, " ("); + + cil_tree_print_classperms_list(mapping->classperms); + + cil_log(CIL_INFO, " )\n"); + return; + } + case CIL_BOOL: { + struct cil_bool *boolean = node->data; + cil_log(CIL_INFO, "BOOL: %s, value: %d\n", boolean->datum.name, boolean->value); + return; + } + case CIL_TUNABLE: { + struct cil_tunable *tunable = node->data; + cil_log(CIL_INFO, "TUNABLE: %s, value: %d\n", tunable->datum.name, tunable->value); + return; + } + case CIL_BOOLEANIF: { + struct cil_booleanif *bif = node->data; + + cil_log(CIL_INFO, "(BOOLEANIF "); + + cil_tree_print_expr(bif->datum_expr, bif->str_expr); + + cil_log(CIL_INFO, " )\n"); + return; + } + case CIL_TUNABLEIF: { + struct cil_tunableif *tif = node->data; + + cil_log(CIL_INFO, "(TUNABLEIF "); + + cil_tree_print_expr(tif->datum_expr, tif->str_expr); + + cil_log(CIL_INFO, " )\n"); + return; + } + case CIL_CONDBLOCK: { + struct cil_condblock *cb = node->data; + if (cb->flavor == CIL_CONDTRUE) { + cil_log(CIL_INFO, "true\n"); + } else if (cb->flavor == CIL_CONDFALSE) { + cil_log(CIL_INFO, "false\n"); + } + return; + } + case CIL_ALL: + cil_log(CIL_INFO, "all"); + return; + case CIL_AND: + cil_log(CIL_INFO, "&&"); + return; + case CIL_OR: + cil_log(CIL_INFO, "|| "); + return; + case CIL_NOT: + cil_log(CIL_INFO, "!"); + return; + case CIL_EQ: + cil_log(CIL_INFO, "=="); + return; + case CIL_NEQ: + cil_log(CIL_INFO, "!="); + return; + case CIL_TYPEALIAS: { + struct cil_alias *alias = node->data; + cil_log(CIL_INFO, "TYPEALIAS: %s\n", alias->datum.name); + return; + } + case CIL_TYPEALIASACTUAL: { + struct cil_aliasactual *aliasactual = node->data; + cil_log(CIL_INFO, "TYPEALIASACTUAL: type: %s, alias: %s\n", aliasactual->alias_str, aliasactual->actual_str); + return; + } + case CIL_TYPEBOUNDS: { + struct cil_bounds *bnds = node->data; + cil_log(CIL_INFO, "TYPEBOUNDS: type: %s, bounds: %s\n", bnds->parent_str, bnds->child_str); + return; + } + case CIL_TYPEPERMISSIVE: { + struct cil_typepermissive *typeperm = node->data; + + if (typeperm->type != NULL) { + cil_log(CIL_INFO, "TYPEPERMISSIVE: %s\n", ((struct cil_symtab_datum *)typeperm->type)->name); + } else { + cil_log(CIL_INFO, "TYPEPERMISSIVE: %s\n", typeperm->type_str); + } + + return; + } + case CIL_NAMETYPETRANSITION: { + struct cil_nametypetransition *nametypetrans = node->data; + cil_log(CIL_INFO, "TYPETRANSITION:"); + + if (nametypetrans->src != NULL) { + cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)nametypetrans->src)->name); + } else { + cil_log(CIL_INFO, " %s", nametypetrans->src_str); + } + + if (nametypetrans->tgt != NULL) { + cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)nametypetrans->tgt)->name); + } else { + cil_log(CIL_INFO, " %s", nametypetrans->tgt_str); + } + + if (nametypetrans->obj != NULL) { + cil_log(CIL_INFO, " %s", nametypetrans->obj->datum.name); + } else { + cil_log(CIL_INFO, " %s", nametypetrans->obj_str); + } + + cil_log(CIL_INFO, " %s\n", nametypetrans->name_str); + + if (nametypetrans->result != NULL) { + cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)nametypetrans->result)->name); + } else { + cil_log(CIL_INFO, " %s", nametypetrans->result_str); + } + + return; + } + case CIL_RANGETRANSITION: { + struct cil_rangetransition *rangetrans = node->data; + cil_log(CIL_INFO, "RANGETRANSITION:"); + + if (rangetrans->src != NULL) { + cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)rangetrans->src)->name); + } else { + cil_log(CIL_INFO, " %s", rangetrans->src_str); + } + + if (rangetrans->exec != NULL) { + cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)rangetrans->exec)->name); + } else { + cil_log(CIL_INFO, " %s", rangetrans->exec_str); + } + + if (rangetrans->obj != NULL) { + cil_log(CIL_INFO, " %s", rangetrans->obj->datum.name); + } else { + cil_log(CIL_INFO, " %s", rangetrans->obj_str); + } + + if (rangetrans->range != NULL) { + cil_log(CIL_INFO, " ("); + cil_tree_print_levelrange(rangetrans->range); + cil_log(CIL_INFO, " )"); + } else { + cil_log(CIL_INFO, " %s", rangetrans->range_str); + } + + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_AVRULE: { + struct cil_avrule *rule = node->data; + switch (rule->rule_kind) { + case CIL_AVRULE_ALLOWED: + cil_log(CIL_INFO, "ALLOW:"); + break; + case CIL_AVRULE_AUDITALLOW: + cil_log(CIL_INFO, "AUDITALLOW:"); + break; + case CIL_AVRULE_DONTAUDIT: + cil_log(CIL_INFO, "DONTAUDIT:"); + break; + case CIL_AVRULE_NEVERALLOW: + cil_log(CIL_INFO, "NEVERALLOW:"); + break; + } + + if (rule->src != NULL) { + cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum*)rule->src)->name); + } else { + cil_log(CIL_INFO, " %s", rule->src_str); + } + + if (rule->tgt != NULL) { + cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum*)rule->tgt)->name); + } else { + cil_log(CIL_INFO, " %s", rule->tgt_str); + } + + cil_tree_print_classperms_list(rule->perms.classperms); + + cil_log(CIL_INFO, "\n"); + + return; + } + case CIL_TYPE_RULE: { + struct cil_type_rule *rule = node->data; + switch (rule->rule_kind) { + case CIL_TYPE_TRANSITION: + cil_log(CIL_INFO, "TYPETRANSITION:"); + break; + case CIL_TYPE_MEMBER: + cil_log(CIL_INFO, "TYPEMEMBER:"); + break; + case CIL_TYPE_CHANGE: + cil_log(CIL_INFO, "TYPECHANGE:"); + break; + } + + if (rule->src != NULL) { + cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)rule->src)->name); + } else { + cil_log(CIL_INFO, " %s", rule->src_str); + } + + if (rule->tgt != NULL) { + cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)rule->tgt)->name); + } else { + cil_log(CIL_INFO, " %s", rule->tgt_str); + } + + if (rule->obj != NULL) { + cil_log(CIL_INFO, " %s", rule->obj->datum.name); + } else { + cil_log(CIL_INFO, " %s", rule->obj_str); + } + + if (rule->result != NULL) { + cil_log(CIL_INFO, " %s\n", ((struct cil_symtab_datum *)rule->result)->name); + } else { + cil_log(CIL_INFO, " %s\n", rule->result_str); + } + + return; + } + case CIL_SENS: { + struct cil_sens *sens = node->data; + cil_log(CIL_INFO, "SENSITIVITY: %s\n", sens->datum.name); + return; + } + case CIL_SENSALIAS: { + struct cil_alias *alias = node->data; + cil_log(CIL_INFO, "SENSITIVITYALIAS: %s\n", alias->datum.name); + return; + } + case CIL_SENSALIASACTUAL: { + struct cil_aliasactual *aliasactual = node->data; + cil_log(CIL_INFO, "SENSITIVITYALIAS: alias: %s, sensitivity: %s\n", aliasactual->alias_str, aliasactual->actual_str); + + return; + } + case CIL_CAT: { + struct cil_cat *cat = node->data; + cil_log(CIL_INFO, "CATEGORY: %s\n", cat->datum.name); + return; + } + case CIL_CATALIAS: { + struct cil_alias *alias = node->data; + cil_log(CIL_INFO, "CATEGORYALIAS: %s\n", alias->datum.name); + return; + } + case CIL_CATALIASACTUAL: { + struct cil_aliasactual *aliasactual = node->data; + cil_log(CIL_INFO, "CATEGORYALIAS: alias %s, category: %s\n", aliasactual->alias_str, aliasactual->actual_str); + return; + } + case CIL_CATSET: { + struct cil_catset *catset = node->data; + + cil_log(CIL_INFO, "CATSET: %s ",catset->datum.name); + + cil_tree_print_cats(catset->cats); + + return; + } + case CIL_CATORDER: { + struct cil_catorder *catorder = node->data; + struct cil_list_item *cat; + + if (catorder->cat_list_str == NULL) { + cil_log(CIL_INFO, "CATORDER: ()\n"); + return; + } + + cil_log(CIL_INFO, "CATORDER: ("); + cil_list_for_each(cat, catorder->cat_list_str) { + cil_log(CIL_INFO, " %s", (char*)cat->data); + } + cil_log(CIL_INFO, " )\n"); + return; + } + case CIL_SENSCAT: { + struct cil_senscat *senscat = node->data; + + cil_log(CIL_INFO, "SENSCAT: sens:"); + + if (senscat->sens_str != NULL) { + cil_log(CIL_INFO, " %s ", senscat->sens_str); + } else { + cil_log(CIL_INFO, " [processed]"); + } + + cil_tree_print_cats(senscat->cats); + + return; + } + case CIL_SENSITIVITYORDER: { + struct cil_sensorder *sensorder = node->data; + struct cil_list_item *sens; + + cil_log(CIL_INFO, "SENSITIVITYORDER: ("); + + if (sensorder->sens_list_str != NULL) { + cil_list_for_each(sens, sensorder->sens_list_str) { + if (sens->flavor == CIL_LIST) { + struct cil_list_item *sub; + cil_log(CIL_INFO, " ("); + cil_list_for_each(sub, (struct cil_list*)sens->data) { + cil_log(CIL_INFO, " %s", (char*)sub->data); + } + cil_log(CIL_INFO, " )"); + } else { + cil_log(CIL_INFO, " %s", (char*)sens->data); + } + } + } + + cil_log(CIL_INFO, " )\n"); + return; + } + case CIL_LEVEL: { + struct cil_level *level = node->data; + cil_log(CIL_INFO, "LEVEL %s:", level->datum.name); + cil_tree_print_level(level); + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_LEVELRANGE: { + struct cil_levelrange *lvlrange = node->data; + cil_log(CIL_INFO, "LEVELRANGE %s:", lvlrange->datum.name); + cil_tree_print_levelrange(lvlrange); + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_CONSTRAIN: { + struct cil_constrain *cons = node->data; + cil_log(CIL_INFO, "CONSTRAIN: ("); + cil_tree_print_constrain(cons); + return; + } + case CIL_MLSCONSTRAIN: { + struct cil_constrain *cons = node->data; + cil_log(CIL_INFO, "MLSCONSTRAIN: ("); + cil_tree_print_constrain(cons); + return; + } + case CIL_VALIDATETRANS: { + struct cil_validatetrans *vt = node->data; + + cil_log(CIL_INFO, "(VALIDATETRANS "); + + if (vt->class != NULL) { + cil_log(CIL_INFO, "%s ", vt->class->datum.name); + } else if (vt->class_str != NULL) { + cil_log(CIL_INFO, "%s ", vt->class_str); + } + + cil_tree_print_expr(vt->datum_expr, vt->str_expr); + + cil_log(CIL_INFO, ")\n"); + return; + } + case CIL_MLSVALIDATETRANS: { + struct cil_validatetrans *vt = node->data; + + cil_log(CIL_INFO, "(MLSVALIDATETRANS "); + + if (vt->class != NULL) { + cil_log(CIL_INFO, "%s ", vt->class->datum.name); + } else if (vt->class_str != NULL) { + cil_log(CIL_INFO, "%s ", vt->class_str); + } + + cil_tree_print_expr(vt->datum_expr, vt->str_expr); + + cil_log(CIL_INFO, ")\n"); + return; + } + case CIL_CONTEXT: { + struct cil_context *context = node->data; + cil_log(CIL_INFO, "CONTEXT %s:", context->datum.name); + cil_tree_print_context(context); + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_FILECON: { + struct cil_filecon *filecon = node->data; + cil_log(CIL_INFO, "FILECON:"); + cil_log(CIL_INFO, " %s %d", filecon->path_str, filecon->type); + + if (filecon->context != NULL) { + cil_tree_print_context(filecon->context); + } else if (filecon->context_str != NULL) { + cil_log(CIL_INFO, " %s", filecon->context_str); + } + + cil_log(CIL_INFO, "\n"); + return; + + } + case CIL_IBPKEYCON: { + struct cil_ibpkeycon *ibpkeycon = node->data; + + cil_log(CIL_INFO, "IBPKEYCON: %s", ibpkeycon->subnet_prefix_str); + cil_log(CIL_INFO, " (%d %d) ", ibpkeycon->pkey_low, ibpkeycon->pkey_high); + + if (ibpkeycon->context) + cil_tree_print_context(ibpkeycon->context); + else if (ibpkeycon->context_str) + cil_log(CIL_INFO, " %s", ibpkeycon->context_str); + + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_PORTCON: { + struct cil_portcon *portcon = node->data; + cil_log(CIL_INFO, "PORTCON:"); + if (portcon->proto == CIL_PROTOCOL_UDP) { + cil_log(CIL_INFO, " udp"); + } else if (portcon->proto == CIL_PROTOCOL_TCP) { + cil_log(CIL_INFO, " tcp"); + } else if (portcon->proto == CIL_PROTOCOL_DCCP) { + cil_log(CIL_INFO, " dccp"); + } else if (portcon->proto == CIL_PROTOCOL_SCTP) { + cil_log(CIL_INFO, " sctp"); + } + cil_log(CIL_INFO, " (%d %d)", portcon->port_low, portcon->port_high); + + if (portcon->context != NULL) { + cil_tree_print_context(portcon->context); + } else if (portcon->context_str != NULL) { + cil_log(CIL_INFO, " %s", portcon->context_str); + } + + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_NODECON: { + struct cil_nodecon *nodecon = node->data; + char buf[256]; + + cil_log(CIL_INFO, "NODECON:"); + + if (nodecon->addr) { + inet_ntop(nodecon->addr->family, &nodecon->addr->ip, buf, 256); + cil_log(CIL_INFO, " %s", buf); + } else { + cil_log(CIL_INFO, " %s", nodecon->addr_str); + } + + if (nodecon->mask) { + inet_ntop(nodecon->mask->family, &nodecon->mask->ip, buf, 256); + cil_log(CIL_INFO, " %s", buf); + } else { + cil_log(CIL_INFO, " %s", nodecon->mask_str); + } + + if (nodecon->context != NULL) { + cil_tree_print_context(nodecon->context); + } else if (nodecon->context_str != NULL) { + cil_log(CIL_INFO, " %s", nodecon->context_str); + } + + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_GENFSCON: { + struct cil_genfscon *genfscon = node->data; + cil_log(CIL_INFO, "GENFSCON:"); + cil_log(CIL_INFO, " %s %s", genfscon->fs_str, genfscon->path_str); + + if (genfscon->context != NULL) { + cil_tree_print_context(genfscon->context); + } else if (genfscon->context_str != NULL) { + cil_log(CIL_INFO, " %s", genfscon->context_str); + } + + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_NETIFCON: { + struct cil_netifcon *netifcon = node->data; + cil_log(CIL_INFO, "NETIFCON %s", netifcon->interface_str); + + if (netifcon->if_context != NULL) { + cil_tree_print_context(netifcon->if_context); + } else if (netifcon->if_context_str != NULL) { + cil_log(CIL_INFO, " %s", netifcon->if_context_str); + } + + if (netifcon->packet_context != NULL) { + cil_tree_print_context(netifcon->packet_context); + } else if (netifcon->packet_context_str != NULL) { + cil_log(CIL_INFO, " %s", netifcon->packet_context_str); + } + + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_IBENDPORTCON: { + struct cil_ibendportcon *ibendportcon = node->data; + + cil_log(CIL_INFO, "IBENDPORTCON: %s %u ", ibendportcon->dev_name_str, ibendportcon->port); + + if (ibendportcon->context) + cil_tree_print_context(ibendportcon->context); + else if (ibendportcon->context_str) + cil_log(CIL_INFO, " %s", ibendportcon->context_str); + + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_PIRQCON: { + struct cil_pirqcon *pirqcon = node->data; + + cil_log(CIL_INFO, "PIRQCON %d", pirqcon->pirq); + if (pirqcon->context != NULL) { + cil_tree_print_context(pirqcon->context); + } else { + cil_log(CIL_INFO, " %s", pirqcon->context_str); + } + + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_IOMEMCON: { + struct cil_iomemcon *iomemcon = node->data; + + cil_log(CIL_INFO, "IOMEMCON ( %"PRId64" %"PRId64" )", iomemcon->iomem_low, iomemcon->iomem_high); + if (iomemcon->context != NULL) { + cil_tree_print_context(iomemcon->context); + } else { + cil_log(CIL_INFO, " %s", iomemcon->context_str); + } + + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_IOPORTCON: { + struct cil_ioportcon *ioportcon = node->data; + + cil_log(CIL_INFO, "IOPORTCON ( %d %d )", ioportcon->ioport_low, ioportcon->ioport_high); + if (ioportcon->context != NULL) { + cil_tree_print_context(ioportcon->context); + } else { + cil_log(CIL_INFO, " %s", ioportcon->context_str); + } + + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_PCIDEVICECON: { + struct cil_pcidevicecon *pcidevicecon = node->data; + + cil_log(CIL_INFO, "PCIDEVICECON %d", pcidevicecon->dev); + if (pcidevicecon->context != NULL) { + cil_tree_print_context(pcidevicecon->context); + } else { + cil_log(CIL_INFO, " %s", pcidevicecon->context_str); + } + + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_DEVICETREECON: { + struct cil_devicetreecon *devicetreecon = node->data; + + cil_log(CIL_INFO, "DEVICETREECON %s", devicetreecon->path); + if (devicetreecon->context != NULL) { + cil_tree_print_context(devicetreecon->context); + } else { + cil_log(CIL_INFO, " %s", devicetreecon->context_str); + } + + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_FSUSE: { + struct cil_fsuse *fsuse = node->data; + cil_log(CIL_INFO, "FSUSE: "); + + if (fsuse->type == CIL_FSUSE_XATTR) { + cil_log(CIL_INFO, "xattr "); + } else if (fsuse->type == CIL_FSUSE_TASK) { + cil_log(CIL_INFO, "task "); + } else if (fsuse->type == CIL_FSUSE_TRANS) { + cil_log(CIL_INFO, "trans "); + } else { + cil_log(CIL_INFO, "unknown "); + } + + cil_log(CIL_INFO, "%s ", fsuse->fs_str); + + if (fsuse->context != NULL) { + cil_tree_print_context(fsuse->context); + } else { + cil_log(CIL_INFO, " %s", fsuse->context_str); + } + + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_SID: { + struct cil_sid *sid = node->data; + cil_log(CIL_INFO, "SID: %s\n", sid->datum.name); + return; + } + case CIL_SIDCONTEXT: { + struct cil_sidcontext *sidcon = node->data; + cil_log(CIL_INFO, "SIDCONTEXT: %s", sidcon->sid_str); + + if (sidcon->context != NULL) { + cil_tree_print_context(sidcon->context); + } else { + cil_log(CIL_INFO, " %s", sidcon->context_str); + } + + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_SIDORDER: { + struct cil_sidorder *sidorder = node->data; + struct cil_list_item *sid; + + if (sidorder->sid_list_str == NULL) { + cil_log(CIL_INFO, "SIDORDER: ()\n"); + return; + } + + cil_log(CIL_INFO, "SIDORDER: ("); + cil_list_for_each(sid, sidorder->sid_list_str) { + cil_log(CIL_INFO, " %s", (char*)sid->data); + } + cil_log(CIL_INFO, " )\n"); + return; + } + case CIL_POLICYCAP: { + struct cil_policycap *polcap = node->data; + cil_log(CIL_INFO, "POLICYCAP: %s\n", polcap->datum.name); + return; + } + case CIL_MACRO: { + struct cil_macro *macro = node->data; + cil_log(CIL_INFO, "MACRO %s:", macro->datum.name); + + if (macro->params != NULL && macro->params->head != NULL) { + struct cil_list_item *curr_param; + cil_log(CIL_INFO, " parameters: ("); + cil_list_for_each(curr_param, macro->params) { + cil_log(CIL_INFO, " flavor: %d, string: %s;", ((struct cil_param*)curr_param->data)->flavor, ((struct cil_param*)curr_param->data)->str); + + } + cil_log(CIL_INFO, " )"); + } + cil_log(CIL_INFO, "\n"); + + return; + } + case CIL_CALL: { + struct cil_call *call = node->data; + cil_log(CIL_INFO, "CALL: macro name:"); + + if (call->macro != NULL) { + cil_log(CIL_INFO, " %s", call->macro->datum.name); + } else { + cil_log(CIL_INFO, " %s", call->macro_str); + } + + if (call->args != NULL) { + cil_log(CIL_INFO, ", args: ( "); + struct cil_list_item *item; + cil_list_for_each(item, call->args) { + struct cil_symtab_datum *datum = ((struct cil_args*)item->data)->arg; + if (datum != NULL) { + if (datum->nodes != NULL && datum->nodes->head != NULL) { + cil_tree_print_node((struct cil_tree_node*)datum->nodes->head->data); + } + } else if (((struct cil_args*)item->data)->arg_str != NULL) { + switch (item->flavor) { + case CIL_TYPE: cil_log(CIL_INFO, "type:"); break; + case CIL_USER: cil_log(CIL_INFO, "user:"); break; + case CIL_ROLE: cil_log(CIL_INFO, "role:"); break; + case CIL_SENS: cil_log(CIL_INFO, "sensitivity:"); break; + case CIL_CAT: cil_log(CIL_INFO, "category:"); break; + case CIL_CATSET: cil_log(CIL_INFO, "categoryset:"); break; + case CIL_LEVEL: cil_log(CIL_INFO, "level:"); break; + case CIL_CLASS: cil_log(CIL_INFO, "class:"); break; + default: break; + } + cil_log(CIL_INFO, "%s ", ((struct cil_args*)item->data)->arg_str); + } + } + cil_log(CIL_INFO, ")"); + } + + cil_log(CIL_INFO, "\n"); + return; + } + case CIL_OPTIONAL: { + struct cil_optional *optional = node->data; + cil_log(CIL_INFO, "OPTIONAL: %s\n", optional->datum.name); + return; + } + case CIL_IPADDR: { + struct cil_ipaddr *ipaddr = node->data; + char buf[256]; + + inet_ntop(ipaddr->family, &ipaddr->ip, buf, 256); + cil_log(CIL_INFO, "IPADDR %s: %s\n", ipaddr->datum.name, buf); + + break; + } + default : { + cil_log(CIL_INFO, "CIL FLAVOR: %d\n", node->flavor); + return; + } + } + } +} + +void cil_tree_print(struct cil_tree_node *tree, uint32_t depth) +{ + struct cil_tree_node *current = NULL; + current = tree; + uint32_t x = 0; + + if (current != NULL) { + if (current->cl_head == NULL) { + if (current->flavor == CIL_NODE) { + if (current->parent->cl_head == current) { + cil_log(CIL_INFO, "%s", (char*)current->data); + } else { + cil_log(CIL_INFO, " %s", (char*)current->data); + } + } else if (current->flavor != CIL_PERM) { + for (x = 0; xparent != NULL) { + cil_log(CIL_INFO, "\n"); + for (x = 0; xflavor != CIL_NODE) { + cil_tree_print_node(current); + } + } + cil_tree_print(current->cl_head, depth + 1); + } + + if (current->next == NULL) { + if ((current->parent != NULL) && (current->parent->cl_tail == current) && (current->parent->parent != NULL)) { + if (current->flavor == CIL_PERM) { + cil_log(CIL_INFO, ")\n"); + } else if (current->flavor != CIL_NODE) { + for (x = 0; xparent != NULL) && (current->parent->parent == NULL)) + cil_log(CIL_INFO, "\n\n"); + } else { + cil_tree_print(current->next, depth); + } + } else { + cil_log(CIL_INFO, "Tree is NULL\n"); + } +} diff --git a/libsepol/cil/src/cil_tree.h b/libsepol/cil/src/cil_tree.h index 5a98da55..aeded560 100644 --- a/libsepol/cil/src/cil_tree.h +++ b/libsepol/cil/src/cil_tree.h @@ -46,16 +46,14 @@ struct cil_tree_node { struct cil_tree_node *next; //Each element in the list points to the next element enum cil_flavor flavor; uint32_t line; - uint32_t hll_offset; + uint32_t hll_line; void *data; }; -struct cil_tree_node *cil_tree_get_next_path(struct cil_tree_node *node, char **info_kind, uint32_t *hll_line, char **path); +struct cil_tree_node *cil_tree_get_next_path(struct cil_tree_node *node, char **path, int* is_cil); char *cil_tree_get_cil_path(struct cil_tree_node *node); __attribute__((format (printf, 3, 4))) void cil_tree_log(struct cil_tree_node *node, enum cil_log_level lvl, const char* msg, ...); -int cil_tree_subtree_has_decl(struct cil_tree_node *node); - int cil_tree_init(struct cil_tree **tree); void cil_tree_destroy(struct cil_tree **tree); void cil_tree_subtree_destroy(struct cil_tree_node *node); @@ -64,6 +62,8 @@ void cil_tree_children_destroy(struct cil_tree_node *node); void cil_tree_node_init(struct cil_tree_node **node); void cil_tree_node_destroy(struct cil_tree_node **node); +void cil_tree_print(struct cil_tree_node *tree, uint32_t depth); + //finished values #define CIL_TREE_SKIP_NOTHING 0 #define CIL_TREE_SKIP_NEXT 1 diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c index 5502c4d5..c73bbeee 100644 --- a/libsepol/cil/src/cil_verify.c +++ b/libsepol/cil/src/cil_verify.c @@ -44,55 +44,10 @@ #include "cil_tree.h" #include "cil_list.h" #include "cil_find.h" -#include "cil_stack.h" #include "cil_verify.h" -static int __cil_is_reserved_name(const char *name, enum cil_flavor flavor) -{ - switch (flavor) { - case CIL_BOOL: - case CIL_TUNABLE: - if ((name == CIL_KEY_EQ) || (name == CIL_KEY_NEQ)) - return CIL_TRUE; - break; - case CIL_PERM: - case CIL_MAP_PERM: - case CIL_USER: - case CIL_USERATTRIBUTE: - case CIL_ROLE: - case CIL_ROLEATTRIBUTE: - if (name == CIL_KEY_ALL) - return CIL_TRUE; - break; - case CIL_TYPE: - case CIL_TYPEATTRIBUTE: - case CIL_TYPEALIAS: - if ((name == CIL_KEY_ALL) || (name == CIL_KEY_SELF)) - return CIL_TRUE; - break; - case CIL_CAT: - case CIL_CATSET: - case CIL_CATALIAS: - case CIL_PERMISSIONX: - if ((name == CIL_KEY_ALL) || (name == CIL_KEY_RANGE)) - return CIL_TRUE; - break; - default: - /* All of these are not used in expressions */ - return CIL_FALSE; - break; - } - - /* Everything not under the default case is also checked for these */ - if ((name == CIL_KEY_AND) || (name == CIL_KEY_OR) || (name == CIL_KEY_NOT) || (name == CIL_KEY_XOR)) { - return CIL_TRUE; - } - - return CIL_FALSE; -} - -int cil_verify_name(const struct cil_db *db, const char *name, enum cil_flavor flavor) +int __cil_verify_name(const char *name) { int rc = SEPOL_ERR; int len; @@ -116,27 +71,12 @@ int cil_verify_name(const struct cil_db *db, const char *name, enum cil_flavor f goto exit; } - if (db->qualified_names == CIL_FALSE) { - for (i = 1; i < len; i++) { - if (!isalnum(name[i]) && name[i] != '_' && name[i] != '-') { - cil_log(CIL_ERR, "Invalid character \"%c\" in %s\n", name[i], name); - goto exit; - } - } - } else { - for (i = 1; i < len; i++) { - if (!isalnum(name[i]) && name[i] != '_' && name[i] != '-' && name[i] != '.') { - cil_log(CIL_ERR, "Invalid character \"%c\" in %s\n", name[i], name); - goto exit; - } + for (i = 1; i < len; i++) { + if (!isalnum(name[i]) && name[i] != '_' && name[i] != '-') { + cil_log(CIL_ERR, "Invalid character \"%c\" in %s\n", name[i], name); + goto exit; } } - - if (__cil_is_reserved_name(name, flavor)) { - cil_log(CIL_ERR, "Name %s is a reserved word\n", name); - goto exit; - } - return SEPOL_OK; exit: @@ -144,45 +84,70 @@ exit: return rc; } -int __cil_verify_syntax(struct cil_tree_node *parse_current, enum cil_syntax s[], size_t len) +int __cil_verify_syntax(struct cil_tree_node *parse_current, enum cil_syntax s[], int len) { + int rc = SEPOL_ERR; + int num_extras = 0; struct cil_tree_node *c = parse_current; - size_t i = 0; + int i = 0; + while (i < len) { + if ((s[i] & CIL_SYN_END) && c == NULL) { + break; + } - while (i < len && c != NULL) { - if ((s[i] & CIL_SYN_STRING) && c->data != NULL && c->cl_head == NULL) { - c = c->next; - i++; - } else if ((s[i] & CIL_SYN_LIST) && c->data == NULL && c->cl_head != NULL) { - c = c->next; - i++; - } else if ((s[i] & CIL_SYN_EMPTY_LIST) && c->data == NULL && c->cl_head == NULL) { - c = c->next; - i++; - } else if ((s[i] & CIL_SYN_N_LISTS) || (s[i] & CIL_SYN_N_STRINGS)) { - while (c != NULL) { - if ((s[i] & CIL_SYN_N_LISTS) && c->data == NULL && c->cl_head != NULL) { - c = c->next; - } else if ((s[i] & CIL_SYN_N_STRINGS) && c->data != NULL && c->cl_head == NULL) { - c = c->next; + if (s[i] & CIL_SYN_N_LISTS || s[i] & CIL_SYN_N_STRINGS) { + if (c == NULL) { + if (num_extras > 0) { + i++; + continue; } else { goto exit; } + } else if ((s[i] & CIL_SYN_N_LISTS) && (c->data == NULL && c->cl_head != NULL)) { + c = c->next; + num_extras++; + continue; + } else if ((s[i] & CIL_SYN_N_STRINGS) && (c->data != NULL && c->cl_head == NULL)) { + c = c->next; + num_extras++; + continue; } - i++; - break; /* Only CIL_SYN_END allowed after these */ - } else { + } + + if (c == NULL) { goto exit; } - } - if (i < len && (s[i] & CIL_SYN_END) && c == NULL) { - return SEPOL_OK; + if (s[i] & CIL_SYN_STRING) { + if (c->data != NULL && c->cl_head == NULL) { + c = c->next; + i++; + continue; + } + } + + if (s[i] & CIL_SYN_LIST) { + if (c->data == NULL && c->cl_head != NULL) { + c = c->next; + i++; + continue; + } + } + + if (s[i] & CIL_SYN_EMPTY_LIST) { + if (c->data == NULL && c->cl_head == NULL) { + c = c->next; + i++; + continue; + } + } + goto exit; } + return SEPOL_OK; exit: cil_log(CIL_ERR, "Invalid syntax\n"); - return SEPOL_ERR; + return rc; } int cil_verify_expr_syntax(struct cil_tree_node *current, enum cil_flavor op, enum cil_flavor expr_flavor) @@ -260,15 +225,12 @@ int cil_verify_constraint_leaf_expr_syntax(enum cil_flavor l_flavor, enum cil_fl cil_log(CIL_ERR, "u3, r3, and t3 can only be used with (mls)validatetrans rules\n"); goto exit; } + } else if (r_flavor == CIL_LIST) { + cil_log(CIL_ERR, "t1, t2, r1, r2, u1, u2 cannot be used on the left side with a list on the right side\n"); + goto exit; } } else { - if (r_flavor == CIL_CONS_U1 || r_flavor == CIL_CONS_R1 || r_flavor == CIL_CONS_T1) { - cil_log(CIL_ERR, "u1, r1, and t1 are not allowed on the right side\n"); - goto exit; - } else if (r_flavor == CIL_CONS_U3 || r_flavor == CIL_CONS_R3 || r_flavor == CIL_CONS_T3) { - cil_log(CIL_ERR, "u3, r3, and t3 are not allowed on the right side\n"); - goto exit; - } else if (r_flavor == CIL_CONS_U2) { + if (r_flavor == CIL_CONS_U2) { if (op != CIL_EQ && op != CIL_NEQ) { cil_log(CIL_ERR, "u2 on the right side must be used with eq or neq as the operator\n"); goto exit; @@ -362,135 +324,28 @@ exit: return SEPOL_ERR; } -int cil_verify_conditional_blocks(struct cil_tree_node *current) +int cil_verify_no_self_reference(struct cil_symtab_datum *datum, struct cil_list *datum_list) { - int found_true = CIL_FALSE; - int found_false = CIL_FALSE; + struct cil_list_item *i; - if (current->cl_head->data == CIL_KEY_CONDTRUE) { - found_true = CIL_TRUE; - } else if (current->cl_head->data == CIL_KEY_CONDFALSE) { - found_false = CIL_TRUE; - } else { - cil_tree_log(current, CIL_ERR, "Expected true or false block in conditional"); - return SEPOL_ERR; - } - - current = current->next; - if (current != NULL) { - if (current->cl_head->data == CIL_KEY_CONDTRUE) { - if (found_true) { - cil_tree_log(current, CIL_ERR, "More than one true block in conditional"); + cil_list_for_each(i, datum_list) { + if (i->flavor == CIL_DATUM) { + struct cil_symtab_datum *d = i->data; + if (d == datum) { + cil_log(CIL_ERR,"Self-reference found for %s\n",datum->name); return SEPOL_ERR; } - } else if (current->cl_head->data == CIL_KEY_CONDFALSE) { - if (found_false) { - cil_tree_log(current, CIL_ERR, "More than one false block in conditional"); + } else if (i->flavor == CIL_LIST) { + int rc = cil_verify_no_self_reference(datum, i->data); + if (rc != SEPOL_OK) { return SEPOL_ERR; } - } else { - cil_tree_log(current, CIL_ERR, "Expected true or false block in conditional"); - return SEPOL_ERR; } } return SEPOL_OK; } -int cil_verify_decl_does_not_shadow_macro_parameter(struct cil_macro *macro, struct cil_tree_node *node, const char *name) -{ - struct cil_list_item *item; - struct cil_list *param_list = macro->params; - if (param_list != NULL) { - cil_list_for_each(item, param_list) { - struct cil_param *param = item->data; - if (param->flavor == node->flavor) { - if (param->str == name) { - cil_log(CIL_ERR, "%s %s shadows a macro parameter in macro declaration\n", cil_node_to_string(node), name); - return SEPOL_ERR; - } - } - } - } - return SEPOL_OK; -} - -static int cil_verify_no_self_reference(enum cil_flavor flavor, struct cil_symtab_datum *datum, struct cil_stack *stack); - -static int __verify_no_self_reference_in_expr(struct cil_list *expr, struct cil_stack *stack) -{ - struct cil_list_item *item; - int rc = SEPOL_OK; - - if (!expr) { - return SEPOL_OK; - } - - cil_list_for_each(item, expr) { - if (item->flavor == CIL_DATUM) { - struct cil_symtab_datum* datum = item->data; - rc = cil_verify_no_self_reference(FLAVOR(datum), datum, stack); - } else if (item->flavor == CIL_LIST) { - rc = __verify_no_self_reference_in_expr(item->data, stack); - } - if (rc != SEPOL_OK) { - return SEPOL_ERR; - } - } - - return SEPOL_OK; -} - -static int cil_verify_no_self_reference(enum cil_flavor flavor, struct cil_symtab_datum *datum, struct cil_stack *stack) -{ - struct cil_stack_item *item; - int i = 0; - int rc = SEPOL_OK; - - cil_stack_for_each(stack, i, item) { - struct cil_symtab_datum *prev = item->data; - if (datum == prev) { - cil_tree_log(NODE(datum), CIL_ERR, "Self-reference found for %s", datum->name); - return SEPOL_ERR; - } - } - - switch (flavor) { - case CIL_USERATTRIBUTE: { - struct cil_userattribute *attr = (struct cil_userattribute *)datum; - cil_stack_push(stack, CIL_DATUM, datum); - rc = __verify_no_self_reference_in_expr(attr->expr_list, stack); - cil_stack_pop(stack); - break; - } - case CIL_ROLEATTRIBUTE: { - struct cil_roleattribute *attr = (struct cil_roleattribute *)datum; - cil_stack_push(stack, CIL_DATUM, datum); - rc = __verify_no_self_reference_in_expr(attr->expr_list, stack); - cil_stack_pop(stack); - break; - } - case CIL_TYPEATTRIBUTE: { - struct cil_typeattribute *attr = (struct cil_typeattribute *)datum; - cil_stack_push(stack, CIL_DATUM, datum); - rc = __verify_no_self_reference_in_expr(attr->expr_list, stack); - cil_stack_pop(stack); - break; - } - case CIL_CATSET: { - struct cil_catset *set = (struct cil_catset *)datum; - cil_stack_push(stack, CIL_DATUM, datum); - rc = __verify_no_self_reference_in_expr(set->cats->datum_expr, stack); - cil_stack_pop(stack); - break; - } - default: - break; - } - - return rc; -} - int __cil_verify_ranges(struct cil_list *list) { int rc = SEPOL_ERR; @@ -1770,12 +1625,8 @@ static int __verify_map_perm_classperms(__attribute__((unused)) hashtab_key_t k, { struct cil_verify_map_args *map_args = args; struct cil_perm *cmp = (struct cil_perm *)d; - int rc; - rc = __cil_verify_classperms(cmp->classperms, &cmp->datum, &map_args->class->datum, &cmp->datum, CIL_MAP_PERM, 0, 2); - if (rc != SEPOL_OK) { - map_args->rc = rc; - } + map_args->rc = __cil_verify_classperms(cmp->classperms, &cmp->datum, &map_args->class->datum, &cmp->datum, CIL_MAP_PERM, 0, 2); return SEPOL_OK; } @@ -1800,22 +1651,27 @@ static int __cil_verify_map_class(struct cil_tree_node *node) int __cil_pre_verify_helper(struct cil_tree_node *node, uint32_t *finished, __attribute__((unused)) void *extra_args) { - int rc = SEPOL_OK; + int rc = SEPOL_ERR; - switch (node->flavor) { - case CIL_MACRO: { + if (node->flavor == CIL_MACRO) { *finished = CIL_TREE_SKIP_HEAD; - break; - } - case CIL_BLOCK: { + rc = SEPOL_OK; + goto exit; + } else if (node->flavor == CIL_BLOCK) { struct cil_block *blk = node->data; if (blk->is_abstract == CIL_TRUE) { *finished = CIL_TREE_SKIP_HEAD; } - break; + rc = SEPOL_OK; + goto exit; } + + switch (node->flavor) { case CIL_USER: rc = __cil_verify_user_pre_eval(node); + if (rc != SEPOL_OK) { + goto exit; + } break; case CIL_MAP_CLASS: rc = __cil_verify_map_class(node); @@ -1823,20 +1679,11 @@ int __cil_pre_verify_helper(struct cil_tree_node *node, uint32_t *finished, __at case CIL_CLASSPERMISSION: rc = __cil_verify_classpermission(node); break; - case CIL_USERATTRIBUTE: - case CIL_ROLEATTRIBUTE: - case CIL_TYPEATTRIBUTE: - case CIL_CATSET: { - struct cil_stack *stack; - cil_stack_init(&stack); - rc = cil_verify_no_self_reference(node->flavor, node->data, stack); - cil_stack_destroy(&stack); - break; - } default: rc = SEPOL_OK; break; } +exit: return rc; } diff --git a/libsepol/cil/src/cil_verify.h b/libsepol/cil/src/cil_verify.h index bb1a072c..bda1565f 100644 --- a/libsepol/cil/src/cil_verify.h +++ b/libsepol/cil/src/cil_verify.h @@ -56,13 +56,12 @@ struct cil_args_verify { int *pass; }; -int cil_verify_name(const struct cil_db *db, const char *name, enum cil_flavor flavor); -int __cil_verify_syntax(struct cil_tree_node *parse_current, enum cil_syntax s[], size_t len); +int __cil_verify_name(const char *name); +int __cil_verify_syntax(struct cil_tree_node *parse_current, enum cil_syntax s[], int len); int cil_verify_expr_syntax(struct cil_tree_node *current, enum cil_flavor op, enum cil_flavor expr_flavor); int cil_verify_constraint_leaf_expr_syntax(enum cil_flavor l_flavor, enum cil_flavor r_flavor, enum cil_flavor op, enum cil_flavor expr_flavor); int cil_verify_constraint_expr_syntax(struct cil_tree_node *current, enum cil_flavor op); -int cil_verify_conditional_blocks(struct cil_tree_node *current); -int cil_verify_decl_does_not_shadow_macro_parameter(struct cil_macro *macro, struct cil_tree_node *node, const char *name); +int cil_verify_no_self_reference(struct cil_symtab_datum *datum, struct cil_list *datum_list); int __cil_verify_ranges(struct cil_list *list); int __cil_verify_ordered_node_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args); int __cil_verify_ordered(struct cil_tree_node *current, enum cil_flavor flavor); diff --git a/libsepol/cil/src/cil_write_ast.c b/libsepol/cil/src/cil_write_ast.c index d7f00bcc..bcf5f416 100644 --- a/libsepol/cil/src/cil_write_ast.c +++ b/libsepol/cil/src/cil_write_ast.c @@ -1,1590 +1,1509 @@ -/* - * Copyright 2011 Tresys Technology, LLC. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those - * of the authors and should not be interpreted as representing official policies, - * either expressed or implied, of Tresys Technology, LLC. - */ +#include -#include -#include -#include -#include - -#include "cil_internal.h" #include "cil_flavor.h" -#include "cil_list.h" +#include "cil_internal.h" #include "cil_log.h" -#include "cil_symtab.h" #include "cil_tree.h" -#include "cil_write_ast.h" - -static inline const char *datum_or_str(struct cil_symtab_datum *datum, const char *str) -{ - return datum ? datum->fqn : str; -} - -static inline const char *datum_to_str(struct cil_symtab_datum *datum) -{ - return datum ? datum->fqn : ""; -} - -static void write_expr(FILE *out, struct cil_list *expr) -{ - struct cil_list_item *curr; - int notfirst = 0; - - fprintf(out, "("); - cil_list_for_each(curr, expr) { - if (notfirst) - fprintf(out, " "); - else - notfirst = 1; - switch (curr->flavor) { - case CIL_LIST: - write_expr(out, curr->data); - break; - case CIL_STRING: - fprintf(out, "%s", (char *)curr->data); - break; - case CIL_DATUM: - case CIL_TYPE: - case CIL_ROLE: - case CIL_USER: - case CIL_SENS: - case CIL_CAT: - case CIL_BOOL: - case CIL_CLASS: - case CIL_MAP_CLASS: - case CIL_NAME: - fprintf(out, "%s", datum_to_str(curr->data)); - break; - case CIL_OP: { - const char *op_str; - enum cil_flavor op_flavor = (enum cil_flavor)(uintptr_t)curr->data; - switch (op_flavor) { - case CIL_AND: - op_str = CIL_KEY_AND; - break; - case CIL_OR: - op_str = CIL_KEY_OR; - break; - case CIL_NOT: - op_str = CIL_KEY_NOT; - break; - case CIL_ALL: - op_str = CIL_KEY_ALL; - break; - case CIL_EQ: - op_str = CIL_KEY_EQ; - break; - case CIL_NEQ: - op_str = CIL_KEY_NEQ; - break; - case CIL_XOR: - op_str = CIL_KEY_XOR; - break; - case CIL_RANGE: - op_str = CIL_KEY_RANGE; - break; - case CIL_CONS_DOM: - op_str = CIL_KEY_CONS_DOM; - break; - case CIL_CONS_DOMBY: - op_str = CIL_KEY_CONS_DOMBY; - break; - case CIL_CONS_INCOMP: - op_str = CIL_KEY_CONS_INCOMP; - break; - default: - op_str = ""; - break; - } - fprintf(out, "%s", op_str); - break; - } - case CIL_CONS_OPERAND: { - const char *operand_str; - enum cil_flavor operand_flavor = (enum cil_flavor)(uintptr_t)curr->data; - switch (operand_flavor) { - case CIL_CONS_U1: - operand_str = CIL_KEY_CONS_U1; - break; - case CIL_CONS_U2: - operand_str = CIL_KEY_CONS_U2; - break; - case CIL_CONS_U3: - operand_str = CIL_KEY_CONS_U3; - break; - case CIL_CONS_T1: - operand_str = CIL_KEY_CONS_T1; - break; - case CIL_CONS_T2: - operand_str = CIL_KEY_CONS_T2; - break; - case CIL_CONS_T3: - operand_str = CIL_KEY_CONS_T3; - break; - case CIL_CONS_R1: - operand_str = CIL_KEY_CONS_R1; - break; - case CIL_CONS_R2: - operand_str = CIL_KEY_CONS_R2; - break; - case CIL_CONS_R3: - operand_str = CIL_KEY_CONS_R3; - break; - case CIL_CONS_L1: - operand_str = CIL_KEY_CONS_L1; - break; - case CIL_CONS_L2: - operand_str = CIL_KEY_CONS_L2; - break; - case CIL_CONS_H1: - operand_str = CIL_KEY_CONS_H1; - break; - case CIL_CONS_H2: - operand_str = CIL_KEY_CONS_H2; - break; - default: - operand_str = ""; - break; - } - fprintf(out, "%s", operand_str); - break; - } - default: - fprintf(out, ""); - break; - } - } - fprintf(out, ")"); -} - -static void write_node_list(FILE *out, struct cil_tree_node *current) -{ - int notfirst = 0; - - fprintf(out, "("); - while (current) { - if (notfirst) - fprintf(out, " "); - else - notfirst = 1; - - fprintf(out, "%s", datum_to_str(current->data)); - current = current->next; - } - fprintf(out, ")"); -} - -static void write_string_list(FILE *out, struct cil_list *list) -{ - struct cil_list_item *curr; - int notfirst = 0; - - if (!list) { - fprintf(out, "()"); - return; - } - - fprintf(out, "("); - cil_list_for_each(curr, list) { - if (notfirst) - fprintf(out, " "); - else - notfirst = 1; - fprintf(out, "%s", (char*)curr->data); - } - fprintf(out, ")"); -} - -static void write_datum_list(FILE *out, struct cil_list *list) -{ - struct cil_list_item *curr; - int notfirst = 0; - - if (!list) { - fprintf(out, "()"); - return; - } - - fprintf(out, "("); - cil_list_for_each(curr, list) { - if (notfirst) - fprintf(out, " "); - else - notfirst = 1; - fprintf(out, "%s", datum_to_str(curr->data)); - } - fprintf(out, ")"); -} - -static void write_classperms(FILE *out, struct cil_classperms *cp) -{ - if (!cp) { - fprintf(out, "()"); - return; - } - - fprintf(out, "(%s ", datum_or_str(DATUM(cp->class), cp->class_str)); - if (cp->perms) - write_expr(out, cp->perms); - else - write_expr(out, cp->perm_strs); - fprintf(out, ")"); -} - -static void write_classperms_list(FILE *out, struct cil_list *cp_list) -{ - struct cil_list_item *curr; - int notfirst = 0; - int num = 0; - - if (!cp_list) { - fprintf(out, "()"); - return; - } - - cil_list_for_each(curr, cp_list) { - num++; - } - if (num > 1) - fprintf(out, "("); - cil_list_for_each(curr, cp_list) { - if (notfirst) - fprintf(out, " "); - else - notfirst = 1; - if (curr->flavor == CIL_CLASSPERMS) { - write_classperms(out, curr->data); - } else { - struct cil_classperms_set *cp_set = curr->data; - struct cil_classpermission *cp = cp_set->set; - if (cp) { - if (cp->datum.name) - fprintf(out, "%s", datum_to_str(DATUM(cp))); - else - write_classperms_list(out,cp->classperms); - } else { - fprintf(out, "%s", cp_set->set_str); - } - } - } - if (num > 1) - fprintf(out, ")"); -} - -static void write_permx(FILE *out, struct cil_permissionx *permx) -{ - if (permx->datum.name) { - fprintf(out, "%s", datum_to_str(DATUM(permx))); - } else { - fprintf(out, "("); - fprintf(out, "%s ", permx->kind == CIL_PERMX_KIND_IOCTL ? "ioctl" : ""); - fprintf(out, "%s ", datum_or_str(DATUM(permx->obj), permx->obj_str)); - write_expr(out, permx->expr_str); - fprintf(out, ")"); - } -} - -static void write_cats(FILE *out, struct cil_cats *cats) -{ - if (cats->datum_expr) { - write_expr(out, cats->datum_expr); - } else { - write_expr(out, cats->str_expr); - } -} - -static void write_level(FILE *out, struct cil_level *level, int print_name) -{ - if (print_name && level->datum.name) { - fprintf(out, "%s", datum_to_str(DATUM(level))); - } else { - fprintf(out, "("); - fprintf(out, "%s", datum_or_str(DATUM(level->sens), level->sens_str)); - if (level->cats) { - fprintf(out, " "); - write_cats(out, level->cats); - } - fprintf(out, ")"); - } -} - -static void write_range(FILE *out, struct cil_levelrange *range, int print_name) -{ - if (print_name && range->datum.name) { - fprintf(out, "%s", datum_to_str(DATUM(range))); - } else { - fprintf(out, "("); - if (range->low) - write_level(out, range->low, CIL_TRUE); - else - fprintf(out, "%s", range->low_str); - fprintf(out, " "); - if (range->high) - write_level(out, range->high, CIL_TRUE); - else - fprintf(out, "%s", range->high_str); - fprintf(out, ")"); - } -} - -static void write_context(FILE *out, struct cil_context *context, int print_name) -{ - if (print_name && context->datum.name) { - fprintf(out, "%s", datum_to_str(DATUM(context))); - } else { - fprintf(out, "("); - fprintf(out, "%s ", datum_or_str(DATUM(context->user), context->user_str)); - fprintf(out, "%s ", datum_or_str(DATUM(context->role), context->role_str)); - fprintf(out, "%s ", datum_or_str(DATUM(context->type), context->type_str)); - if (context->range) - write_range(out, context->range, CIL_TRUE); - else - fprintf(out, "%s", context->range_str); - fprintf(out, ")"); - } -} - -static void write_ipaddr(FILE *out, struct cil_ipaddr *ipaddr) -{ - if (ipaddr->datum.name) { - fprintf(out, "%s", datum_to_str(DATUM(ipaddr))); - } else { - char buf[256]; - if (inet_ntop(ipaddr->family, &ipaddr->ip, buf, 256) == NULL) - strcpy(buf, ""); - fprintf(out, "(%s)", buf); - } -} - -static void write_constrain(FILE *out, struct cil_constrain *cons) -{ - write_classperms_list(out, cons->classperms); - fprintf(out, " "); - if (cons->datum_expr) - write_expr(out, cons->datum_expr); - else - write_expr(out, cons->str_expr); -} - -static void write_call_args(FILE *out, struct cil_list *args) -{ - struct cil_list_item *item; - int notfirst = 0; - - fprintf(out, "("); - cil_list_for_each(item, args) { - struct cil_args* arg = item->data; - enum cil_flavor arg_flavor = arg->flavor; - if (notfirst) - fprintf(out, " "); - else - notfirst = 1; - switch (arg_flavor) { - case CIL_TYPE: - case CIL_ROLE: - case CIL_USER: - case CIL_SENS: - case CIL_CAT: - case CIL_BOOL: - case CIL_CLASS: - case CIL_MAP_CLASS: - case CIL_NAME: { - fprintf(out, "%s", datum_or_str(arg->arg, arg->arg_str)); - break; - } - case CIL_CATSET: { - if (arg->arg) { - struct cil_catset *catset = (struct cil_catset *)arg->arg; - write_cats(out, catset->cats); - } else { - fprintf(out, "%s", arg->arg_str); - } - break; - } - case CIL_LEVEL: { - if (arg->arg) { - struct cil_level *level = (struct cil_level *)arg->arg; - write_level(out, level, CIL_TRUE); - } else { - fprintf(out, "%s", arg->arg_str); - } - break; - } - case CIL_LEVELRANGE: { - if (arg->arg) { - struct cil_levelrange *range = (struct cil_levelrange *)arg->arg; - write_range(out, range, CIL_TRUE); - } else { - fprintf(out, "%s", arg->arg_str); - } - break; - } - case CIL_IPADDR: { - if (arg->arg) { - struct cil_ipaddr *addr = (struct cil_ipaddr *)arg->arg; - write_ipaddr(out, addr); - } else { - fprintf(out, "%s", arg->arg_str); - } - break; - } - case CIL_CLASSPERMISSION: { - if (arg->arg) { - struct cil_classpermission *cp = (struct cil_classpermission *)arg->arg; - if (cp->datum.name) - fprintf(out, "%s", datum_to_str(DATUM(cp))); - else - write_classperms_list(out, cp->classperms); - } else { - fprintf(out, "%s", arg->arg_str); - } - break; - } - default: - fprintf(out, "", datum_or_str(arg->arg, arg->arg_str)); - break; - } - } - fprintf(out, ")"); -} - -static void write_call_args_tree(FILE *out, struct cil_tree_node *arg_node) -{ - while (arg_node) { - if (arg_node->data) { - fprintf(out, "%s", (char *)arg_node->data); - } else if (arg_node->cl_head) { - fprintf(out, "("); - write_call_args_tree(out, arg_node->cl_head); - fprintf(out, ")"); - } - if (arg_node->next) - fprintf(out, " "); - arg_node = arg_node->next; - } -} - -static const char *macro_param_flavor_to_string(enum cil_flavor flavor) -{ - const char *str; - switch(flavor) { - case CIL_TYPE: - str = CIL_KEY_TYPE; - break; - case CIL_ROLE: - str = CIL_KEY_ROLE; - break; - case CIL_USER: - str = CIL_KEY_USER; - break; - case CIL_SENS: - str = CIL_KEY_SENSITIVITY; - break; - case CIL_CAT: - str = CIL_KEY_CATEGORY; - break; - case CIL_CATSET: - str = CIL_KEY_CATSET; - break; - case CIL_LEVEL: - str = CIL_KEY_LEVEL; - break; - case CIL_LEVELRANGE: - str = CIL_KEY_LEVELRANGE; - break; - case CIL_CLASS: - str = CIL_KEY_CLASS; - break; - case CIL_IPADDR: - str = CIL_KEY_IPADDR; - break; - case CIL_MAP_CLASS: - str = CIL_KEY_MAP_CLASS; - break; - case CIL_CLASSPERMISSION: - str = CIL_KEY_CLASSPERMISSION; - break; - case CIL_BOOL: - str = CIL_KEY_BOOL; - break; - case CIL_STRING: - str = CIL_KEY_STRING; - break; - case CIL_NAME: - str = CIL_KEY_NAME; - break; - default: - str = ""; - break; - } - return str; -} - -void cil_write_src_info_node(FILE *out, struct cil_tree_node *node) -{ - struct cil_src_info *info = node->data; - if (info->kind == CIL_KEY_SRC_CIL || info->kind == CIL_KEY_SRC_HLL_LMS) { - fprintf(out, ";;* lms %u %s\n", info->hll_line, info->path); - } else if (info->kind == CIL_KEY_SRC_HLL_LMX) { - fprintf(out, ";;* lmx %u %s\n", info->hll_line, info->path); - } else { - fprintf(out, ";;* %u %s\n", info->hll_line, info->path); - } -} - -void cil_write_ast_node(FILE *out, struct cil_tree_node *node) -{ - if (!node->data) { - return; - } - - switch(node->flavor) { - case CIL_NODE: { - fprintf(out, "%s\n", (char *)node->data); - break; - } - case CIL_BLOCK: { - struct cil_block *block = node->data; - fprintf(out, "(block %s", datum_to_str(DATUM(block))); - if (!node->cl_head) - fprintf(out, ")"); - fprintf(out, "\n"); - break; - } - case CIL_BLOCKINHERIT: { - struct cil_blockinherit *inherit = node->data; - fprintf(out, "(blockinherit %s)\n", datum_or_str(DATUM(inherit->block), inherit->block_str)); - break; - } - case CIL_IN: { - struct cil_in *in = node->data; - fprintf(out, "(in %s", in->block_str); - if (!node->cl_head) - fprintf(out, ")"); - fprintf(out, "\n"); - break; - } - case CIL_OPTIONAL: { - struct cil_optional *optional = node->data; - fprintf(out, "(optional %s", datum_to_str(DATUM(optional))); - if (!node->cl_head) - fprintf(out, ")"); - fprintf(out, "\n"); - break; - } - case CIL_BOOLEANIF: { - struct cil_booleanif *bif = node->data; - fprintf(out, "(booleanif "); - if (bif->datum_expr) - write_expr(out, bif->datum_expr); - else - write_expr(out, bif->str_expr); - if (!node->cl_head) - fprintf(out, ")"); - fprintf(out, "\n"); - break; - } - case CIL_TUNABLEIF: { - struct cil_tunableif *tif = node->data; - fprintf(out, "(tunableif "); - if (tif->datum_expr) - write_expr(out, tif->datum_expr); - else - write_expr(out, tif->str_expr); - if (!node->cl_head) - fprintf(out, ")"); - fprintf(out, "\n"); - break; - } - case CIL_CONDBLOCK: { - struct cil_condblock *cb = node->data; - fprintf(out, "(%s", cb->flavor == CIL_CONDTRUE ? "true" : "false"); - if (!node->cl_head) - fprintf(out, ")"); - fprintf(out, "\n"); - break; - } - case CIL_MACRO: { - struct cil_macro *macro = node->data; - struct cil_list_item *curr; - fprintf(out, "(macro %s (", datum_to_str(DATUM(macro))); - if (macro->params) { - cil_list_for_each(curr, macro->params) { - struct cil_param *param = curr->data; - fprintf(out, "(%s %s)", macro_param_flavor_to_string(param->flavor), param->str); - } - } - fprintf(out, ")"); - if (!node->cl_head) - fprintf(out, ")"); - fprintf(out, "\n"); - break; - } - case CIL_CALL: { - struct cil_call *call = node->data; - fprintf(out, "(call %s", datum_or_str(DATUM(call->macro), call->macro_str)); - if (call->args) { - fprintf(out, " "); - write_call_args(out, call->args); - } else if (call->args_tree) { - fprintf(out, " "); - write_call_args_tree(out, call->args_tree->root); - } - if (!node->cl_head) - fprintf(out, ")"); - fprintf(out, "\n"); - break; - } - case CIL_BLOCKABSTRACT: { - struct cil_blockabstract *abstract = node->data; - fprintf(out, "(blockabstract %s)\n", abstract->block_str); - break; - } - case CIL_MLS: { - struct cil_mls *mls = node->data; - fprintf(out, "(mls %s)\n", mls->value ? "true" : "false"); - break; - } - case CIL_HANDLEUNKNOWN: { - struct cil_handleunknown *unknown = node->data; - fprintf(out, "(handleunknown "); - if (unknown->handle_unknown == SEPOL_ALLOW_UNKNOWN) - fprintf(out, "%s", CIL_KEY_HANDLEUNKNOWN_ALLOW); - else if (unknown->handle_unknown == SEPOL_DENY_UNKNOWN) - fprintf(out, "%s", CIL_KEY_HANDLEUNKNOWN_DENY); - else if (unknown->handle_unknown == SEPOL_REJECT_UNKNOWN) - fprintf(out, "%s", CIL_KEY_HANDLEUNKNOWN_REJECT); - else - fprintf(out, ""); - fprintf(out, ")\n"); - break; - } - case CIL_DEFAULTUSER: { - struct cil_default *def = node->data; - fprintf(out, "(defaultuser "); - if (def->class_datums) - write_datum_list(out, def->class_datums); - else - write_string_list(out, def->class_strs); - if (def->object == CIL_DEFAULT_SOURCE) - fprintf(out, " source"); - else if (def->object == CIL_DEFAULT_TARGET) - fprintf(out, " target"); - else - fprintf(out, " "); - fprintf(out, ")\n"); - break; - } - case CIL_DEFAULTROLE: { - struct cil_default *def = node->data; - fprintf(out, "(defaultrole "); - if (def->class_datums) - write_datum_list(out, def->class_datums); - else - write_string_list(out, def->class_strs); - if (def->object == CIL_DEFAULT_SOURCE) - fprintf(out, " source"); - else if (def->object == CIL_DEFAULT_TARGET) - fprintf(out, " target"); - else - fprintf(out, " "); - fprintf(out, ")\n"); - break; - } - case CIL_DEFAULTTYPE: { - struct cil_default *def = node->data; - fprintf(out, "(defaulttype "); - if (def->class_datums) - write_datum_list(out, def->class_datums); - else - write_string_list(out, def->class_strs); - if (def->object == CIL_DEFAULT_SOURCE) - fprintf(out, " source"); - else if (def->object == CIL_DEFAULT_TARGET) - fprintf(out, " target"); - else - fprintf(out, " "); - fprintf(out, ")\n"); - break; - } - case CIL_DEFAULTRANGE: { - struct cil_defaultrange *def = node->data; - fprintf(out, "(defaultrange "); - if (def->class_datums) - write_datum_list(out, def->class_datums); - else - write_string_list(out, def->class_strs); - if (def->object_range == CIL_DEFAULT_SOURCE_LOW) - fprintf(out, " source low"); - else if (def->object_range == CIL_DEFAULT_SOURCE_HIGH) - fprintf(out, " source high"); - else if (def->object_range == CIL_DEFAULT_SOURCE_LOW_HIGH) - fprintf(out, " source low-high"); - else if (def->object_range == CIL_DEFAULT_TARGET_LOW) - fprintf(out, " target low"); - else if (def->object_range == CIL_DEFAULT_TARGET_HIGH) - fprintf(out, " target high"); - else if (def->object_range == CIL_DEFAULT_TARGET_LOW_HIGH) - fprintf(out, " target low-high"); - else - fprintf(out, " "); - fprintf(out, ")\n"); - break; - } - case CIL_CLASS: { - struct cil_class *class = node->data; - fprintf(out, "(class %s ", datum_to_str(DATUM(class))); - write_node_list(out, node->cl_head); - fprintf(out, ")\n"); - break; - } - case CIL_CLASSORDER: { - struct cil_classorder *classorder = node->data; - fprintf(out, "(classorder "); - write_string_list(out, classorder->class_list_str); - fprintf(out, ")\n"); - break; - } - case CIL_COMMON: { - struct cil_class *common = node->data; - fprintf(out, "(common %s ", datum_to_str(DATUM(common))); - write_node_list(out, node->cl_head); - fprintf(out, ")\n"); - break; - } - case CIL_CLASSCOMMON: { - struct cil_classcommon *cc = node->data; - fprintf(out, "(classcommon %s %s)\n", cc->class_str, cc->common_str); - break; - } - case CIL_CLASSPERMISSION: { - struct cil_classpermission *cp = node->data; - fprintf(out, "(classpermission %s)\n", datum_to_str(DATUM(cp))); - break; - } - case CIL_CLASSPERMISSIONSET: { - struct cil_classpermissionset *cps = node->data; - fprintf(out, "(classpermissionset %s ", cps->set_str); - write_classperms_list(out, cps->classperms); - fprintf(out, ")\n"); - break; - } - case CIL_MAP_CLASS: { - struct cil_class *map = node->data; - fprintf(out, "(classmap %s ", datum_to_str(DATUM(map))); - write_node_list(out, node->cl_head); - fprintf(out, ")\n"); - break; - } - case CIL_CLASSMAPPING: { - struct cil_classmapping *mapping = node->data; - fprintf(out, "(classmapping %s %s ", mapping->map_class_str, mapping->map_perm_str); - write_classperms_list(out, mapping->classperms); - fprintf(out, ")\n"); - break; - } - case CIL_PERMISSIONX: { - struct cil_permissionx *permx = node->data; - fprintf(out, "(permissionx %s (", datum_to_str(DATUM(permx))); - fprintf(out, "%s ", permx->kind == CIL_PERMX_KIND_IOCTL ? "ioctl" : ""); - fprintf(out, "%s ", datum_or_str(DATUM(permx->obj), permx->obj_str)); - write_expr(out, permx->expr_str); - fprintf(out, "))\n"); - break; - } - case CIL_SID: { - struct cil_sid *sid = node->data; - fprintf(out, "(sid %s)\n", datum_to_str(DATUM(sid))); - break; - } - case CIL_SIDCONTEXT: { - struct cil_sidcontext *sidcon = node->data; - fprintf(out, "(sidcontext %s ", sidcon->sid_str); - if (sidcon->context) - write_context(out, sidcon->context, CIL_TRUE); - else - fprintf(out, "%s", sidcon->context_str); - fprintf(out, ")\n"); - break; - } - case CIL_SIDORDER: { - struct cil_sidorder *sidorder = node->data; - fprintf(out, "(sidorder "); - write_string_list(out, sidorder->sid_list_str); - fprintf(out, ")\n"); - break; - } - case CIL_BOOL: { - struct cil_bool *boolean = node->data; - fprintf(out, "(boolean %s %s)\n", datum_to_str(DATUM(boolean)), boolean->value ? "true" : "false"); - break; - } - case CIL_TUNABLE: { - struct cil_tunable *tunable = node->data; - fprintf(out, "(tunable %s %s)\n", datum_to_str(DATUM(tunable)), tunable->value ? "true" : "false"); - break; - } - case CIL_SENS: { - struct cil_sens *sens = node->data; - fprintf(out, "(sensitivity %s)\n", datum_to_str(DATUM(sens))); - break; - } - case CIL_SENSALIAS: { - struct cil_alias *alias = node->data; - fprintf(out, "(sensitivityalias %s)\n", datum_to_str(DATUM(alias))); - break; - } - case CIL_SENSALIASACTUAL: { - struct cil_aliasactual *aliasactual = node->data; - fprintf(out, "(sensitivityaliasactual %s %s)\n", aliasactual->alias_str, aliasactual->actual_str); - break; - } - case CIL_CAT: { - struct cil_cat *cat = node->data; - fprintf(out, "(category %s)\n", datum_to_str(DATUM(cat))); - break; - } - case CIL_CATALIAS: { - struct cil_alias *alias = node->data; - fprintf(out, "(categoryalias %s)\n", datum_to_str(DATUM(alias))); - break; - } - case CIL_CATALIASACTUAL: { - struct cil_aliasactual *aliasactual = node->data; - fprintf(out, "(categoryaliasactual %s %s)\n", aliasactual->alias_str, aliasactual->actual_str); - break; - } - case CIL_CATSET: { - struct cil_catset *catset = node->data; - fprintf(out, "(categoryset %s ", datum_to_str(DATUM(catset))); - write_cats(out, catset->cats); - fprintf(out, ")\n"); - break; - } - case CIL_CATORDER: { - struct cil_catorder *catorder = node->data; - fprintf(out, "(categoryorder "); - write_string_list(out, catorder->cat_list_str); - fprintf(out, ")\n"); - break; - } - case CIL_SENSCAT: { - struct cil_senscat *senscat = node->data; - fprintf(out, "(sensitivitycategory "); - fprintf(out, "%s ", senscat->sens_str); - write_cats(out, senscat->cats); - fprintf(out, ")\n"); - break; - } - case CIL_SENSITIVITYORDER: { - struct cil_sensorder *sensorder = node->data; - fprintf(out, "(sensitivityorder "); - write_string_list(out, sensorder->sens_list_str); - fprintf(out, ")\n"); - break; - } - case CIL_LEVEL: { - struct cil_level *level = node->data; - fprintf(out, "(level %s ", datum_to_str(&level->datum)); - write_level(out, level, CIL_FALSE); - fprintf(out, ")\n"); - break; - } - case CIL_LEVELRANGE: { - struct cil_levelrange *lvlrange = node->data; - fprintf(out, "(levelrange %s ", datum_to_str(DATUM(lvlrange))); - write_range(out, lvlrange, CIL_FALSE); - fprintf(out, ")\n"); - break; - } - case CIL_USER: { - struct cil_user *user = node->data; - fprintf(out, "(user %s)\n", datum_to_str(DATUM(user))); - break; - } - case CIL_USERATTRIBUTE: { - struct cil_userattribute *attr = node->data; - fprintf(out, "(userattribute %s)\n", datum_to_str(DATUM(attr))); - break; - } - case CIL_USERATTRIBUTESET: { - struct cil_userattributeset *attr = node->data; - fprintf(out, "(userattributeset %s ", attr->attr_str); - if (attr->datum_expr) - write_expr(out, attr->datum_expr); - else - write_expr(out, attr->str_expr); - fprintf(out, ")\n"); - break; - } - case CIL_USERROLE: { - struct cil_userrole *userrole = node->data; - fprintf(out, "(userrole "); - fprintf(out, "%s ", datum_or_str(userrole->user, userrole->user_str)); - fprintf(out, "%s", datum_or_str(userrole->role, userrole->role_str)); - fprintf(out, ")\n"); - break; - } - case CIL_USERLEVEL: { - struct cil_userlevel *userlevel = node->data; - fprintf(out, "(userlevel %s ", userlevel->user_str); - if (userlevel->level) - write_level(out, userlevel->level, CIL_TRUE); - else - fprintf(out, "%s", userlevel->level_str); - fprintf(out, ")\n"); - break; - } - case CIL_USERRANGE: { - struct cil_userrange *userrange = node->data; - fprintf(out, "(userrange %s ", userrange->user_str); - if (userrange->range) - write_range(out, userrange->range, CIL_TRUE); - else - fprintf(out, "%s", userrange->range_str); - fprintf(out, ")\n"); - break; - } - case CIL_USERBOUNDS: { - struct cil_bounds *bounds = node->data; - fprintf(out, "(userbounds %s %s)\n", bounds->parent_str, bounds->child_str); - break; - } - case CIL_USERPREFIX: { - struct cil_userprefix *prefix = node->data; - fprintf(out, "(userprefix "); - fprintf(out, "%s ", datum_or_str(DATUM(prefix->user), prefix->user_str)); - fprintf(out, "%s)\n", prefix->prefix_str); - break; - } - case CIL_SELINUXUSER: { - struct cil_selinuxuser *selinuxuser = node->data; - fprintf(out, "(selinuxuser %s ", selinuxuser->name_str); - fprintf(out, "%s ", datum_or_str(DATUM(selinuxuser->user), selinuxuser->user_str)); - if (selinuxuser->range) - write_range(out, selinuxuser->range, CIL_TRUE); - else - fprintf(out, "%s", selinuxuser->range_str); - fprintf(out, ")\n"); - break; - } - case CIL_SELINUXUSERDEFAULT: { - struct cil_selinuxuser *selinuxuser = node->data; - fprintf(out, "(selinuxuserdefault "); - fprintf(out, "%s ", datum_or_str(DATUM(selinuxuser->user), selinuxuser->user_str)); - if (selinuxuser->range) - write_range(out, selinuxuser->range, CIL_TRUE); - else - fprintf(out, "%s", selinuxuser->range_str); - fprintf(out, ")\n"); - break; - } - case CIL_ROLE: { - fprintf(out, "(role %s)\n", datum_to_str(node->data)); - break; - } - case CIL_ROLEATTRIBUTE: { - fprintf(out, "(roleattribute %s)\n", datum_to_str(node->data)); - break; - } - case CIL_ROLEATTRIBUTESET: { - struct cil_roleattributeset *attr = node->data; - fprintf(out, "(roleattributeset %s ", attr->attr_str); - if (attr->datum_expr) - write_expr(out, attr->datum_expr); - else - write_expr(out, attr->str_expr); - fprintf(out, ")\n"); - break; - } - case CIL_ROLETYPE: { - struct cil_roletype *roletype = node->data; - fprintf(out, "(roletype "); - fprintf(out, "%s ", datum_or_str(DATUM(roletype->role), roletype->role_str)); - fprintf(out, "%s", datum_or_str(DATUM(roletype->type), roletype->type_str)); - fprintf(out, ")\n"); - break; - } - case CIL_ROLEBOUNDS: { - struct cil_bounds *bnds = node->data; - fprintf(out, "(rolebounds %s %s)\n", bnds->parent_str, bnds->child_str); - break; - } - case CIL_TYPE: { - fprintf(out, "(type %s)\n", datum_to_str(node->data)); - break; - } - case CIL_TYPEALIAS: { - fprintf(out, "(typealias %s)\n", datum_to_str(node->data)); - break; - } - case CIL_TYPEALIASACTUAL: { - struct cil_aliasactual *aliasactual = node->data; - fprintf(out, "(typealiasactual %s %s)\n", aliasactual->alias_str, aliasactual->actual_str); - break; - } - case CIL_TYPEATTRIBUTE: { - fprintf(out, "(typeattribute %s)\n", datum_to_str(node->data)); - break; - } - case CIL_TYPEATTRIBUTESET: { - struct cil_typeattributeset *attr = node->data; - fprintf(out, "(typeattributeset %s ", attr->attr_str); - if (attr->datum_expr) - write_expr(out, attr->datum_expr); - else - write_expr(out, attr->str_expr); - fprintf(out, ")\n"); - break; - } - case CIL_EXPANDTYPEATTRIBUTE: { - struct cil_expandtypeattribute *attr = node->data; - fprintf(out, "(expandtypeattribute "); - if (attr->attr_datums) - write_expr(out, attr->attr_datums); - else - write_expr(out, attr->attr_strs); - fprintf(out, " %s)\n", attr->expand ? "true" : "false"); - break; - } - case CIL_TYPEPERMISSIVE: { - struct cil_typepermissive *tp = node->data; - fprintf(out, "(typepermissive "); - fprintf(out, "%s", datum_or_str(DATUM(tp->type), tp->type_str)); - fprintf(out, ")\n"); - break; - } - case CIL_TYPEBOUNDS: { - struct cil_bounds *bounds = node->data; - fprintf(out, "(typebounds %s %s)\n", bounds->parent_str, bounds->child_str); - break; - } - case CIL_ROLEALLOW: { - struct cil_roleallow *roleallow = node->data; - fprintf(out, "(roleallow "); - fprintf(out, "%s ", datum_or_str(DATUM(roleallow->src), roleallow->src_str)); - fprintf(out, "%s", datum_or_str(DATUM(roleallow->tgt), roleallow->tgt_str)); - fprintf(out, ")\n"); - break; - } - case CIL_ROLETRANSITION: { - struct cil_roletransition *roletrans = node->data; - fprintf(out, "(roletransition "); - fprintf(out, "%s ", datum_or_str(DATUM(roletrans->src), roletrans->src_str)); - fprintf(out, "%s ", datum_or_str(DATUM(roletrans->tgt), roletrans->tgt_str)); - fprintf(out, "%s ", datum_or_str(DATUM(roletrans->obj), roletrans->obj_str)); - fprintf(out, "%s", datum_or_str(DATUM(roletrans->result), roletrans->result_str)); - fprintf(out, ")\n"); - break; - } - case CIL_AVRULE: { - struct cil_avrule *rule = node->data; - if (rule->rule_kind == AVRULE_ALLOWED) - fprintf(out, "(allow "); - else if (rule->rule_kind == AVRULE_AUDITALLOW) - fprintf(out, "(auditallow "); - else if (rule->rule_kind == AVRULE_DONTAUDIT) - fprintf(out, "(dontaudit "); - else if (rule->rule_kind == AVRULE_NEVERALLOW) - fprintf(out, "(neverallow "); - else - fprintf(out, "( "); - - fprintf(out, "%s ", datum_or_str(DATUM(rule->src), rule->src_str)); - fprintf(out, "%s ", datum_or_str(DATUM(rule->tgt), rule->tgt_str)); - write_classperms_list(out, rule->perms.classperms); - fprintf(out, ")\n"); - break; - } - case CIL_AVRULEX: { - struct cil_avrule *rule = node->data; - if (rule->rule_kind == AVRULE_ALLOWED) - fprintf(out, "(allowx "); - else if (rule->rule_kind == AVRULE_AUDITALLOW) - fprintf(out, "(auditallowx "); - else if (rule->rule_kind == AVRULE_DONTAUDIT) - fprintf(out, "(dontauditx "); - else if (rule->rule_kind == AVRULE_NEVERALLOW) - fprintf(out, "(neverallowx "); - else - fprintf(out, "( "); - fprintf(out, "%s ", datum_or_str(DATUM(rule->src), rule->src_str)); - fprintf(out, "%s ", datum_or_str(DATUM(rule->tgt), rule->tgt_str)); - if (rule->perms.x.permx_str) { - fprintf(out, "%s",rule->perms.x.permx_str); - } else { - write_permx(out, rule->perms.x.permx); - } - fprintf(out, ")\n"); - break; - } - case CIL_TYPE_RULE: { - struct cil_type_rule *rule = node->data; - if (rule->rule_kind == AVRULE_TRANSITION) - fprintf(out, "(typetransition "); - else if (rule->rule_kind == AVRULE_MEMBER) - fprintf(out, "(typemember "); - else if (rule->rule_kind == AVRULE_CHANGE) - fprintf(out, "(typechange "); - else - fprintf(out, "( "); - fprintf(out, "%s ", datum_or_str(DATUM(rule->src), rule->src_str)); - fprintf(out, "%s ", datum_or_str(DATUM(rule->tgt), rule->tgt_str)); - fprintf(out, "%s ", datum_or_str(DATUM(rule->obj), rule->obj_str)); - fprintf(out, "%s", datum_or_str(DATUM(rule->result), rule->result_str)); - fprintf(out, ")\n"); - break; - } - case CIL_NAMETYPETRANSITION: { - struct cil_nametypetransition *rule = node->data; - fprintf(out, "(typetransition "); - fprintf(out, "%s ", datum_or_str(DATUM(rule->src), rule->src_str)); - fprintf(out, "%s ", datum_or_str(DATUM(rule->tgt), rule->tgt_str)); - fprintf(out, "%s ", datum_or_str(DATUM(rule->obj), rule->obj_str)); - fprintf(out, "\"%s\" ", datum_or_str(DATUM(rule->name), rule->name_str)); - fprintf(out, "%s", datum_or_str(DATUM(rule->result), rule->result_str)); - fprintf(out, ")\n"); - break; - } - case CIL_RANGETRANSITION: { - struct cil_rangetransition *rule = node->data; - fprintf(out, "(rangetransition "); - fprintf(out, "%s ", datum_or_str(DATUM(rule->src), rule->src_str)); - fprintf(out, "%s ", datum_or_str(DATUM(rule->exec), rule->exec_str)); - fprintf(out, "%s ", datum_or_str(DATUM(rule->obj), rule->obj_str)); - if (rule->range) - write_range(out, rule->range, CIL_TRUE); - else - fprintf(out, "%s", rule->range_str); - fprintf(out, ")\n"); - break; - } - case CIL_CONSTRAIN: { - struct cil_constrain *cons = node->data; - fprintf(out, "(constrain "); - write_constrain(out, cons); - fprintf(out, ")\n"); - break; - } - case CIL_MLSCONSTRAIN: { - struct cil_constrain *cons = node->data; - fprintf(out, "(mlsconstrain "); - write_constrain(out, cons); - fprintf(out, ")\n"); - break; - } - case CIL_VALIDATETRANS: { - struct cil_validatetrans *vt = node->data; - fprintf(out, "(validatetrans "); - fprintf(out, "%s ", datum_or_str(DATUM(vt->class), vt->class_str)); - if (vt->datum_expr) - write_expr(out, vt->datum_expr); - else - write_expr(out, vt->str_expr); - fprintf(out, ")\n"); - break; - } - case CIL_MLSVALIDATETRANS: { - struct cil_validatetrans *vt = node->data; - fprintf(out, "(mlsvalidatetrans "); - fprintf(out, "%s ", datum_or_str(DATUM(vt->class), vt->class_str)); - if (vt->datum_expr) - write_expr(out, vt->datum_expr); - else - write_expr(out, vt->str_expr); - fprintf(out, ")\n"); - break; - } - case CIL_CONTEXT: { - struct cil_context *context = node->data; - fprintf(out, "(context %s ", datum_to_str(DATUM(context))); - write_context(out, context, CIL_FALSE); - fprintf(out, ")\n"); - break; - } - case CIL_FILECON: { - struct cil_filecon *filecon = node->data; - fprintf(out, "(filecon "); - fprintf(out, "\"%s\" ", filecon->path_str); - if (filecon->type == CIL_FILECON_FILE) - fprintf(out, "%s ", CIL_KEY_FILE); - else if (filecon->type == CIL_FILECON_DIR) - fprintf(out, "%s ", CIL_KEY_DIR); - else if (filecon->type == CIL_FILECON_CHAR) - fprintf(out, "%s ", CIL_KEY_CHAR); - else if (filecon->type == CIL_FILECON_BLOCK) - fprintf(out, "%s ", CIL_KEY_BLOCK); - else if (filecon->type == CIL_FILECON_SOCKET) - fprintf(out, "%s ", CIL_KEY_SOCKET); - else if (filecon->type == CIL_FILECON_PIPE) - fprintf(out, "%s ", CIL_KEY_PIPE); - else if (filecon->type == CIL_FILECON_SYMLINK) - fprintf(out, "%s ", CIL_KEY_SYMLINK); - else if (filecon->type == CIL_FILECON_ANY) - fprintf(out, "%s ", CIL_KEY_ANY); - else - fprintf(out, " "); - if (filecon->context) - write_context(out, filecon->context, CIL_TRUE); - else if (filecon->context_str) - fprintf(out, "%s", filecon->context_str); - else - fprintf(out, "()"); - fprintf(out, ")\n"); - break; - } - case CIL_IBPKEYCON: { - struct cil_ibpkeycon *ibpkeycon = node->data; - fprintf(out, "(ibpkeycon %s ", ibpkeycon->subnet_prefix_str); - fprintf(out, "(%d %d) ", ibpkeycon->pkey_low, ibpkeycon->pkey_high); - if (ibpkeycon->context) - write_context(out, ibpkeycon->context, CIL_TRUE); - else if (ibpkeycon->context_str) - fprintf(out, "%s", ibpkeycon->context_str); - fprintf(out, ")\n"); - break; - } - case CIL_PORTCON: { - struct cil_portcon *portcon = node->data; - fprintf(out, "(portcon "); - if (portcon->proto == CIL_PROTOCOL_UDP) - fprintf(out, " udp "); - else if (portcon->proto == CIL_PROTOCOL_TCP) - fprintf(out, " tcp "); - else if (portcon->proto == CIL_PROTOCOL_DCCP) - fprintf(out, "dccp "); - else if (portcon->proto == CIL_PROTOCOL_SCTP) - fprintf(out, "sctp "); - else - fprintf(out, " "); - if (portcon->port_low == portcon->port_high) - fprintf(out, "%d ", portcon->port_low); - else - fprintf(out, "(%d %d) ", portcon->port_low, portcon->port_high); - if (portcon->context) - write_context(out, portcon->context, CIL_TRUE); - else - fprintf(out, "%s", portcon->context_str); - fprintf(out, ")\n"); - break; - } - case CIL_NODECON: { - struct cil_nodecon *nodecon = node->data; - fprintf(out, "(nodecon "); - if (nodecon->addr) - write_ipaddr(out, nodecon->addr); - else - fprintf(out, "%s ", nodecon->addr_str); - fprintf(out, " "); - if (nodecon->mask) - write_ipaddr(out, nodecon->mask); - else - fprintf(out, "%s ", nodecon->mask_str); - fprintf(out, " "); - if (nodecon->context) - write_context(out, nodecon->context, CIL_TRUE); - else - fprintf(out, "%s", nodecon->context_str); - fprintf(out, ")\n"); - break; - } - case CIL_GENFSCON: { - struct cil_genfscon *genfscon = node->data; - fprintf(out, "(genfscon "); - fprintf(out, "%s \"%s\" ", genfscon->fs_str, genfscon->path_str); - if (genfscon->context) - write_context(out, genfscon->context, CIL_TRUE); - else - fprintf(out, "%s", genfscon->context_str); - fprintf(out, ")\n"); - break; - } - case CIL_NETIFCON: { - struct cil_netifcon *netifcon = node->data; - fprintf(out, "(netifcon %s ", netifcon->interface_str); - if (netifcon->if_context) - write_context(out, netifcon->if_context, CIL_TRUE); - else - fprintf(out, "%s", netifcon->if_context_str); - fprintf(out, " "); - if (netifcon->packet_context) - write_context(out, netifcon->packet_context, CIL_TRUE); - else - fprintf(out, "%s", netifcon->packet_context_str); - fprintf(out, ")\n"); - break; - } - case CIL_IBENDPORTCON: { - struct cil_ibendportcon *ibendportcon = node->data; - fprintf(out, "(ibendportcon %s %u ", ibendportcon->dev_name_str, ibendportcon->port); - if (ibendportcon->context) - write_context(out, ibendportcon->context, CIL_TRUE); - else - fprintf(out, "%s", ibendportcon->context_str); - fprintf(out, ")\n"); - break; - } - case CIL_PIRQCON: { - struct cil_pirqcon *pirqcon = node->data; - fprintf(out, "(pirqcon %d ", pirqcon->pirq); - if (pirqcon->context) - write_context(out, pirqcon->context, CIL_TRUE); - else - fprintf(out, "%s", pirqcon->context_str); - fprintf(out, ")\n"); - break; - } - case CIL_IOMEMCON: { - struct cil_iomemcon *iomemcon = node->data; - fprintf(out, "(iomemcon (%"PRId64" %"PRId64") ", iomemcon->iomem_low, iomemcon->iomem_high); - if (iomemcon->context) - write_context(out, iomemcon->context, CIL_TRUE); - else - fprintf(out, "%s", iomemcon->context_str); - fprintf(out, ")\n"); - break; - } - case CIL_IOPORTCON: { - struct cil_ioportcon *ioportcon = node->data; - fprintf(out, "(ioportcon "); - if (ioportcon->ioport_low == ioportcon->ioport_high) - fprintf(out, "%d ", ioportcon->ioport_low); - else - fprintf(out, "(%d %d) ", ioportcon->ioport_low, ioportcon->ioport_high); - - if (ioportcon->context) - write_context(out, ioportcon->context, CIL_TRUE); - else - fprintf(out, "%s", ioportcon->context_str); - fprintf(out, ")\n"); - break; - } - case CIL_PCIDEVICECON: { - struct cil_pcidevicecon *pcidevicecon = node->data; - fprintf(out, "(pcidevicecon %d ", pcidevicecon->dev); - if (pcidevicecon->context) - write_context(out, pcidevicecon->context, CIL_TRUE); - else - fprintf(out, "%s", pcidevicecon->context_str); - fprintf(out, ")\n"); - break; - } - case CIL_DEVICETREECON: { - struct cil_devicetreecon *devicetreecon = node->data; - fprintf(out, "(devicetreecon \"%s\" ", devicetreecon->path); - if (devicetreecon->context) - write_context(out, devicetreecon->context, CIL_TRUE); - else - fprintf(out, "%s", devicetreecon->context_str); - fprintf(out, ")\n"); - break; - } - case CIL_FSUSE: { - struct cil_fsuse *fsuse = node->data; - fprintf(out, "(fsuse "); - if (fsuse->type == CIL_FSUSE_XATTR) - fprintf(out, "xattr "); - else if (fsuse->type == CIL_FSUSE_TASK) - fprintf(out, "task "); - else if (fsuse->type == CIL_FSUSE_TRANS) - fprintf(out, "trans "); - else - fprintf(out, " "); - fprintf(out, "%s ", fsuse->fs_str); - if (fsuse->context) - write_context(out, fsuse->context, CIL_TRUE); - else - fprintf(out, "%s", fsuse->context_str); - fprintf(out, ")\n"); - break; - } - case CIL_POLICYCAP: { - struct cil_policycap *polcap = node->data; - fprintf(out, "(policycap %s)\n", polcap->datum.name); - break; - } - case CIL_IPADDR: { - struct cil_ipaddr *ipaddr = node->data; - char buf[256]; - if (inet_ntop(ipaddr->family, &ipaddr->ip, buf, 256) == NULL) - strcpy(buf, ""); - fprintf(out, "(ipaddr %s %s)\n", datum_to_str(&ipaddr->datum), buf); - break; - } - default : - fprintf(out, "()\n", cil_node_to_string(node)); - break; - } -} - -/* - * Tree walk data and helper functions for writing the AST of the various phases - */ - -struct cil_write_ast_args { - FILE *out; - int depth; +struct cil_args_write { + FILE *cil_out; + struct cil_db *db; }; -/* - * Helper functions for writing the parse AST - */ +static int cil_unfill_expr(struct cil_list *expr_str, char **out_str, int paren); +static int cil_unfill_classperms_list(struct cil_list *classperms, char **out_str, int paren); +static int __cil_write_first_child_helper(struct cil_tree_node *node, void *extra_args); +static int __cil_write_node_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args); +static int __cil_write_last_child_helper(struct cil_tree_node *node, void *extra_args); -static int __write_parse_ast_node_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args) -{ - struct cil_write_ast_args *args = extra_args; +static int __cil_strlist_concat(struct cil_list *str_list, char **out_str, int paren) { + size_t len = paren ? 3 : 1; + size_t num_elems = 0; + char *p = NULL; + struct cil_list_item *curr; - fprintf(args->out, "%*s", args->depth*4, ""); - if (!node->data) { - if (node->cl_head) - fprintf(args->out, "(\n"); - else - fprintf(args->out, "()\n"); - } else { - char *str = (char *)node->data; - size_t len = strlen(str); - size_t i; + /* get buffer size */ + cil_list_for_each(curr, str_list) { + len += strlen((char *)curr->data); + num_elems++; + } + if (num_elems != 0) { + /* add spaces between elements */ + len += num_elems - 1; + } + *out_str = cil_malloc(len); + p = *out_str; + if (paren) + *p++ = '('; + cil_list_for_each(curr, str_list) { + size_t src_len = strlen((char *)curr->data); + memcpy(p, curr->data, src_len); + p += src_len; + if (curr->next != NULL) + *p++ = ' '; + } + if (paren) + *p++ = ')'; + *p++ = '\0'; + return SEPOL_OK; +} - for (i = 0; i < len; i++) { - if (isspace(str[i])) { - fprintf(args->out, "\"%s\"\n", str); - return SEPOL_OK; - } +static int __cil_unfill_expr_helper(struct cil_list_item *curr, + struct cil_list_item **next, char **out_str, int paren) { + int rc = SEPOL_ERR; + char *str = NULL; + char *operand1 = NULL; + char *operand2 = NULL; + + switch(curr->flavor) { + case CIL_LIST: + rc = cil_unfill_expr((struct cil_list *)curr->data, &str, paren); + if (rc != SEPOL_OK) + goto exit; + *out_str = str; + *next = curr->next; + break; + case CIL_STRING: + str = strdup((char *)curr->data); + if (!str) { + cil_log(CIL_ERR, "OOM. Unable to copy string.\n"); + rc = SEPOL_ERR; + goto exit; + } + *out_str = str; + *next = curr->next; + break; + case CIL_DATUM: + str = strdup(((struct cil_symtab_datum *)curr->data)->name); + if (!str) { + cil_log(CIL_ERR, "OOM. Unable to copy string.\n"); + rc = SEPOL_ERR; + goto exit; + } + *out_str = str; + *next = curr->next; + break; + case CIL_OP: { + char *op_str = NULL; + size_t len = 0; + enum cil_flavor op_flavor = (enum cil_flavor)curr->data; + switch (op_flavor) { + case CIL_AND: + op_str = CIL_KEY_AND; + break; + case CIL_OR: + op_str = CIL_KEY_OR; + break; + case CIL_NOT: + op_str = CIL_KEY_NOT; + break; + case CIL_ALL: + op_str = CIL_KEY_ALL; + break; + case CIL_EQ: + op_str = CIL_KEY_EQ; + break; + case CIL_NEQ: + op_str = CIL_KEY_NEQ; + break; + case CIL_RANGE: + op_str = CIL_KEY_RANGE; + break; + case CIL_XOR: + op_str = CIL_KEY_XOR; + break; + case CIL_CONS_DOM: + op_str = CIL_KEY_CONS_DOM; + break; + case CIL_CONS_DOMBY: + op_str = CIL_KEY_CONS_DOMBY; + break; + case CIL_CONS_INCOMP: + op_str = CIL_KEY_CONS_INCOMP; + break; + default: + cil_log(CIL_ERR, "Unknown operator in expression: %d\n", op_flavor); + goto exit; + break; + } + /* all operands take two args except for 'all' and 'not', which take + * one and two, respectively */ + len = strlen(op_str) + 3; + if (op_flavor == CIL_ALL) { + *out_str = cil_malloc(len); + sprintf(*out_str, "(%s)", op_str); + *next = curr->next; + } else if (op_flavor == CIL_NOT) { + rc = __cil_unfill_expr_helper(curr->next, next, &operand1, paren); + if (rc != SEPOL_OK) + goto exit; + len += strlen(operand1) + 1; + *out_str = cil_malloc(len); + sprintf(*out_str, "(%s %s)", op_str, operand1); + // *next already set by recursive call + } else { + rc = __cil_unfill_expr_helper(curr->next, next, &operand1, paren); + if (rc != SEPOL_OK) + goto exit; + len += strlen(operand1) + 1; + // *next contains operand2, but keep track of next after that + rc = __cil_unfill_expr_helper(*next, next, &operand2, paren); + if (rc != SEPOL_OK) + goto exit; + len += strlen(operand2) + 1; + *out_str = cil_malloc(len); + sprintf(*out_str, "(%s %s %s)", op_str, operand1, operand2); + // *next already set by recursive call } - - fprintf(args->out, "%s\n", (char *)node->data); } - - return SEPOL_OK; + break; + case CIL_CONS_OPERAND: { + enum cil_flavor operand_flavor = (enum cil_flavor)curr->data; + char *operand_str = NULL; + switch (operand_flavor) { + case CIL_CONS_U1: + operand_str = CIL_KEY_CONS_U1; + break; + case CIL_CONS_U2: + operand_str = CIL_KEY_CONS_U2; + break; + case CIL_CONS_U3: + operand_str = CIL_KEY_CONS_U3; + break; + case CIL_CONS_T1: + operand_str = CIL_KEY_CONS_T1; + break; + case CIL_CONS_T2: + operand_str = CIL_KEY_CONS_T2; + break; + case CIL_CONS_T3: + operand_str = CIL_KEY_CONS_T3; + break; + case CIL_CONS_R1: + operand_str = CIL_KEY_CONS_R1; + break; + case CIL_CONS_R2: + operand_str = CIL_KEY_CONS_R2; + break; + case CIL_CONS_R3: + operand_str = CIL_KEY_CONS_R3; + break; + case CIL_CONS_L1: + operand_str = CIL_KEY_CONS_L1; + break; + case CIL_CONS_L2: + operand_str = CIL_KEY_CONS_L2; + break; + case CIL_CONS_H1: + operand_str = CIL_KEY_CONS_H1; + break; + case CIL_CONS_H2: + operand_str = CIL_KEY_CONS_H2; + break; + default: + cil_log(CIL_ERR, "Unknown operand in expression\n"); + goto exit; + break; + } + str = strdup(operand_str); + if (!str) { + cil_log(CIL_ERR, "OOM. Unable to copy string.\n"); + rc = SEPOL_ERR; + goto exit; + } + *out_str = str; + *next = curr->next; + } + break; + default: + cil_log(CIL_ERR, "Unknown flavor in expression\n"); + goto exit; + break; + } + rc = SEPOL_OK; +exit: + free(operand1); + free(operand2); + return rc; } -static int __write_parse_ast_first_child_helper(struct cil_tree_node *node, void *extra_args) -{ - struct cil_write_ast_args *args = extra_args; - struct cil_tree_node *parent = node->parent; +static int cil_unfill_expr(struct cil_list *expr_str, char **out_str, int paren) { + int rc = SEPOL_ERR; - if (parent->flavor != CIL_ROOT) { - args->depth++; + /* reuse cil_list to keep track of strings */ + struct cil_list *str_list = NULL; + struct cil_list_item *curr = NULL; + + cil_list_init(&str_list, CIL_NONE); + + /* iterate through cil_list, grabbing elements as needed */ + curr = expr_str->head; + while(curr != NULL) { + char *str = NULL; + struct cil_list_item *next = NULL; + + rc = __cil_unfill_expr_helper(curr, &next, &str, paren); + if (rc != SEPOL_OK) + goto exit; + cil_list_append(str_list, CIL_STRING, (void *) str); + str = NULL; + curr = next; } - - return SEPOL_OK; + rc = __cil_strlist_concat(str_list, out_str, paren); + if (rc != SEPOL_OK) + goto exit; + rc = SEPOL_OK; +exit: + cil_list_for_each(curr, str_list) { + free(curr->data); + } + cil_list_destroy(&str_list, 0); + return rc; } -static int __write_parse_ast_last_child_helper(struct cil_tree_node *node, void *extra_args) -{ - struct cil_write_ast_args *args = extra_args; - struct cil_tree_node *parent = node->parent; - - if (parent->flavor == CIL_ROOT) { - return SEPOL_OK; - } - - args->depth--; - fprintf(args->out, "%*s", args->depth*4, ""); - fprintf(args->out, ")\n"); - - return SEPOL_OK; +static int cil_unfill_cats(struct cil_cats *cats, char **out_str) { + return cil_unfill_expr(cats->str_expr, out_str, 0); } -/* - * Helper functions for writing the CIL AST for the build and resolve phases - */ - -static int __write_cil_ast_node_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) -{ - struct cil_write_ast_args *args = extra_args; - - if (node->flavor == CIL_SRC_INFO) { - cil_write_src_info_node(args->out, node); - return SEPOL_OK; +static int cil_unfill_level(struct cil_level *lvl, char **out_str) { + int rc = SEPOL_ERR; + size_t len = 0; + char *sens, *cats = NULL; + sens = lvl->sens_str; + len = strlen(sens) + 3; // '()\0' + if (lvl->cats != NULL) { + rc = cil_unfill_cats(lvl->cats, &cats); + if (rc != SEPOL_OK) + goto exit; + len += strlen(cats) + 1; } - - fprintf(args->out, "%*s", args->depth*4, ""); - - cil_write_ast_node(args->out, node); - - if (node->flavor == CIL_CLASS || node->flavor == CIL_COMMON || node->flavor == CIL_MAP_CLASS) { - *finished = CIL_TREE_SKIP_HEAD; - } - - return SEPOL_OK; -} - -static int __write_cil_ast_first_child_helper(struct cil_tree_node *node, void *extra_args) -{ - struct cil_write_ast_args *args = extra_args; - struct cil_tree_node *parent = node->parent; - - if (parent->flavor != CIL_SRC_INFO && parent->flavor != CIL_ROOT) { - args->depth++; - } - - return SEPOL_OK; -} - -static int __write_cil_ast_last_child_helper(struct cil_tree_node *node, void *extra_args) -{ - struct cil_write_ast_args *args = extra_args; - struct cil_tree_node *parent = node->parent; - - if (parent->flavor == CIL_ROOT) { - return SEPOL_OK; - } else if (parent->flavor == CIL_SRC_INFO) { - fprintf(args->out, ";;* lme\n"); - return SEPOL_OK; - } - - args->depth--; - fprintf(args->out, "%*s", args->depth*4, ""); - fprintf(args->out, ")\n"); - - return SEPOL_OK; -} - -int cil_write_ast(FILE *out, enum cil_write_ast_phase phase, struct cil_tree_node *node) -{ - struct cil_write_ast_args extra_args; - int rc; - - extra_args.out = out; - extra_args.depth = 0; - - if (phase == CIL_WRITE_AST_PHASE_PARSE) { - rc = cil_tree_walk(node, __write_parse_ast_node_helper, __write_parse_ast_first_child_helper, __write_parse_ast_last_child_helper, &extra_args); + *out_str = cil_malloc(len); + if (cats == NULL) { + if (sprintf(*out_str, "(%s)", sens) < 0) { + cil_log(CIL_ERR, "Error unpacking and writing level\n"); + rc = SEPOL_ERR; + goto exit; + } } else { - rc = cil_tree_walk(node, __write_cil_ast_node_helper, __write_cil_ast_first_child_helper, __write_cil_ast_last_child_helper, &extra_args); + if (sprintf(*out_str, "(%s %s)", sens, cats) < 0) { + cil_log(CIL_ERR, "Error unpacking and writing level\n"); + rc = SEPOL_ERR; + goto exit; + } } + rc = SEPOL_OK; +exit: + free(cats); + return rc; +} - if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Failed to write AST\n"); - return SEPOL_ERR; +static int cil_unfill_levelrange(struct cil_levelrange *lvlrnge, char **out_str) { + int rc = SEPOL_ERR; + size_t len = 0; + char *low = NULL, *high = NULL; + if (lvlrnge->low_str != NULL) { + low = strdup(lvlrnge->low_str); + if (low == NULL) { + cil_log(CIL_ERR, "OOM. Unable to copy level string.\n"); + rc = SEPOL_ERR; + goto exit; + } + } else { + rc = cil_unfill_level(lvlrnge->low, &low); + if (rc != SEPOL_OK) + goto exit; } + if (lvlrnge->high_str != NULL) { + high = strdup(lvlrnge->high_str); + if (high == NULL) { + cil_log(CIL_ERR, "OOM. Unable to copy level string.\n"); + rc = SEPOL_ERR; + goto exit; + } + } else { + rc = cil_unfill_level(lvlrnge->high, &high); + if (rc != SEPOL_OK) + goto exit; + } + len = strlen(low) + strlen(high) + 4; + *out_str = cil_malloc(len); + if (sprintf(*out_str, "(%s %s)", low, high) < 0) { + cil_log(CIL_ERR, "Error unpacking and writing levelrange\n"); + rc = SEPOL_ERR; + goto exit; + } + rc = SEPOL_OK; +exit: + free(low); + free(high); + return rc; +} +static int cil_unfill_context(struct cil_context *context, char **out_str) { + int rc = SEPOL_ERR; + size_t len = 0; + char *user_str, *role_str, *type_str; + char *range_str = NULL; + + user_str = context->user_str; + role_str = context->role_str; + type_str = context->type_str; + if (context->range_str != NULL) { + range_str = strdup(context->range_str); + if (range_str == NULL) { + cil_log(CIL_ERR, "OOM. Unable to copy range string.\n"); + rc = SEPOL_ERR; + goto exit; + } + } else { + rc = cil_unfill_levelrange(context->range, &range_str); + if (rc != SEPOL_OK) + goto exit; + } + len = strlen(user_str) + strlen(role_str) + strlen(type_str) + + strlen(range_str) + 6; + *out_str = cil_malloc(len); + if (sprintf(*out_str, "(%s %s %s %s)", user_str, role_str, type_str, range_str) < 0) { + cil_log(CIL_ERR, "Error unpacking and writing context\n"); + rc = SEPOL_ERR; + goto exit; + } + rc = SEPOL_OK; +exit: + free(range_str); + return rc; +} + +static int cil_unfill_permx(struct cil_permissionx *permx, char **out_str) { + size_t len = 3; + int rc = SEPOL_ERR; + char *kind, *obj; + char *expr = NULL; + + switch (permx->kind) { + case CIL_PERMX_KIND_IOCTL: + kind = CIL_KEY_IOCTL; + break; + default: + cil_log(CIL_ERR, "Unknown permissionx kind: %d\n", permx->kind); + rc = SEPOL_ERR; + goto exit; + break; + } + obj = permx->obj_str; + rc = cil_unfill_expr(permx->expr_str, &expr, 1); + if (rc != SEPOL_OK) + goto exit; + len += strlen(kind) + strlen(obj) + strlen(expr) + 2; + *out_str = cil_malloc(len); + if (sprintf(*out_str, "(%s %s %s)", kind, obj, expr) < 0) { + cil_log(CIL_ERR, "Error writing xperm\n"); + rc = SEPOL_ERR; + goto exit; + } + rc = SEPOL_OK; +exit: + free(expr); + return rc; +} + +#define cil_write_unsupported(flavor) _cil_write_unsupported(flavor, __LINE__) +static int _cil_write_unsupported(const char *flavor, int line) { + cil_log(CIL_ERR, + "flavor \"%s\" is not supported, look in file \"%s\"" + " on line %d to add support.\n", flavor, __FILE__, line); + return SEPOL_ENOTSUP; +} + +static int cil_write_policycap(struct cil_tree_node *node, FILE *cil_out) { + struct cil_policycap *polcap = (struct cil_policycap *)node->data; + fprintf(cil_out, "(%s %s)\n", CIL_KEY_POLICYCAP, polcap->datum.name); return SEPOL_OK; } + +static int cil_write_perm(struct cil_tree_node *node, FILE *cil_out) { + struct cil_perm *perm = (struct cil_perm *)node->data; + fprintf(cil_out, "%s", perm->datum.name); + if (node->next != NULL) + fprintf(cil_out, " "); + return SEPOL_OK; +} + + +static int cil_write_class(struct cil_tree_node *node, uint32_t *finished, + struct cil_args_write *extra_args) { + int rc = SEPOL_ERR; + FILE *cil_out = extra_args->cil_out; + struct cil_symtab_datum *datum = (struct cil_symtab_datum *)node->data; + char *class_type = (node->flavor == CIL_CLASS) ? CIL_KEY_CLASS : CIL_KEY_COMMON; + + /* print preamble */ + fprintf(cil_out, "(%s %s ", class_type, datum->name); + + if (node->cl_head == NULL) { + /* no associated perms in this part of tree */ + fprintf(cil_out, "()"); + } else { + + /* visit subtree (perms) */ + rc = cil_tree_walk(node, __cil_write_node_helper, + __cil_write_first_child_helper, + __cil_write_last_child_helper, + extra_args); + if (rc != SEPOL_OK) + goto exit; + } + + /* postamble (trailing paren) */ + fprintf(cil_out, ")\n"); + *finished = CIL_TREE_SKIP_HEAD; + rc = SEPOL_OK; +exit: + return rc; +} + +static int cil_write_classorder(struct cil_tree_node *node, FILE *cil_out) { + int rc = SEPOL_ERR; + char *ord_str = NULL; + struct cil_classorder *classord = (struct cil_classorder *)node->data; + + /* cil_unfill_expr() has logic to stringify a cil_list, reuse that. */ + rc = cil_unfill_expr(classord->class_list_str, &ord_str, 1); + if (rc != SEPOL_OK) + goto exit; + fprintf(cil_out, "(%s %s)\n", CIL_KEY_CLASSORDER, ord_str); + rc = SEPOL_OK; +exit: + free(ord_str); + return rc; +} + +static int cil_write_classcommon(struct cil_tree_node *node, FILE *cil_out) { + struct cil_classcommon *classcommon = (struct cil_classcommon *)node->data; + fprintf(cil_out, "(%s %s %s)\n", CIL_KEY_CLASSCOMMON, classcommon->class_str, + classcommon->common_str); + return SEPOL_OK; +} + +static int cil_write_sid(struct cil_tree_node *node, FILE *cil_out) { + struct cil_sid *sid = (struct cil_sid *)node->data; + fprintf(cil_out, "(%s %s)\n", CIL_KEY_SID, sid->datum.name); + return SEPOL_OK; +} + +static int cil_write_sidcontext(struct cil_tree_node *node, FILE *cil_out) { + int rc = SEPOL_ERR; + char *sid; + char *ctx_str = NULL; + struct cil_sidcontext *sidcon = (struct cil_sidcontext *)node->data; + + sid = sidcon->sid_str; + if (sidcon->context_str != NULL) { + ctx_str = strdup(sidcon->context_str); + if (ctx_str == NULL) { + cil_log(CIL_ERR, "OOM. Unable to copy context string.\n"); + rc = SEPOL_ERR; + goto exit; + } + } else { + rc = cil_unfill_context(sidcon->context, &ctx_str); + if (rc != SEPOL_OK) + goto exit; + } + fprintf(cil_out, "(%s %s %s)\n", CIL_KEY_SIDCONTEXT, sid, ctx_str); + rc = SEPOL_OK; +exit: + free(ctx_str); + return rc; +} + +static int cil_write_sidorder(struct cil_tree_node *node, FILE *cil_out) { + int rc = SEPOL_ERR; + char *ord_str = NULL; + struct cil_sidorder *sidord = (struct cil_sidorder *)node->data; + + /* cil_unfill_expr() has logic to stringify a cil_list, reuse that. */ + rc = cil_unfill_expr(sidord->sid_list_str, &ord_str, 1); + if (rc != SEPOL_OK) + goto exit; + fprintf(cil_out, "(%s %s)\n", CIL_KEY_SIDORDER, ord_str); + rc = SEPOL_OK; +exit: + free(ord_str); + return rc; +} + +static int cil_write_user(struct cil_tree_node *node, FILE *cil_out) { + struct cil_user *user = (struct cil_user *)node->data; + fprintf(cil_out, "(%s %s)\n", CIL_KEY_USER, user->datum.name); + return SEPOL_OK; +} + +static int cil_write_userrole(struct cil_tree_node *node, FILE *cil_out) { + struct cil_userrole *userrole = (struct cil_userrole *)node->data; + fprintf(cil_out, "(%s %s %s)\n", CIL_KEY_USERROLE, userrole->user_str, + userrole->role_str); + return SEPOL_OK; +} + +static int cil_write_userlevel(struct cil_tree_node *node, FILE *cil_out) { + struct cil_userlevel *usrlvl = (struct cil_userlevel *)node->data; + int rc = SEPOL_ERR; + char *usr; + char *lvl = NULL; + + usr = usrlvl->user_str; + if (usrlvl->level_str != NULL) { + lvl = strdup(usrlvl->level_str); + if (lvl == NULL) { + cil_log(CIL_ERR, "OOM. Unable to copy level string.\n"); + rc = SEPOL_ERR; + goto exit; + } + } else { + rc = cil_unfill_level(usrlvl->level, &lvl); + if (rc != SEPOL_OK) + goto exit; + } + fprintf(cil_out, "(%s %s %s)\n", CIL_KEY_USERLEVEL, usr, lvl); + rc = SEPOL_OK; +exit: + free(lvl); + return rc; +} + +static int cil_write_userrange(struct cil_tree_node *node, FILE *cil_out) { + struct cil_userrange *usrrng = (struct cil_userrange *)node->data; + int rc = SEPOL_ERR; + char *usr; + char *range = NULL; + + usr = usrrng->user_str; + if (usrrng->range_str != NULL) { + range = strdup(usrrng->range_str); + if (range == NULL) { + cil_log(CIL_ERR, "OOM. Unable to copy levelrange string.\n"); + rc = SEPOL_ERR; + goto exit; + } + } else { + rc = cil_unfill_levelrange(usrrng->range, &range); + if (rc != SEPOL_OK) + goto exit; + } + fprintf(cil_out, "(%s %s %s)\n", CIL_KEY_USERRANGE, usr, range); + rc = SEPOL_OK; +exit: + free(range); + return rc; +} + +static int cil_write_role(struct cil_tree_node *node, FILE *cil_out) { + struct cil_role *role = (struct cil_role *)node->data; + fprintf(cil_out, "(%s %s)\n", CIL_KEY_ROLE, role->datum.name); + return SEPOL_OK; +} + +static int cil_write_roletype(struct cil_tree_node *node, FILE *cil_out) { + struct cil_roletype *roletype = (struct cil_roletype *)node->data; + fprintf(cil_out, "(%s %s %s)\n", CIL_KEY_ROLETYPE, roletype->role_str, roletype->type_str); + return SEPOL_OK; +} + +static int cil_write_roleattribute(struct cil_tree_node *node, FILE *cil_out) { + struct cil_roleattribute *roleattr = (struct cil_roleattribute *)node->data; + fprintf(cil_out, "(%s %s)\n", CIL_KEY_ROLEATTRIBUTE, roleattr->datum.name); + return SEPOL_OK; +} + +static int cil_write_type(struct cil_tree_node *node, FILE *cil_out) { + struct cil_type *type = (struct cil_type *)node->data; + fprintf(cil_out, "(%s %s)\n", CIL_KEY_TYPE, type->datum.name); + return SEPOL_OK; +} + +static int cil_write_typepermissive(struct cil_tree_node *node, FILE *cil_out) { + struct cil_typepermissive *type = (struct cil_typepermissive *)node->data; + fprintf(cil_out, "(%s %s)\n", CIL_KEY_TYPEPERMISSIVE, type->type_str); + return SEPOL_OK; +} + +static int cil_write_typeattribute(struct cil_tree_node *node, FILE *cil_out) { + struct cil_typeattribute *typeattr = (struct cil_typeattribute *)node->data; + fprintf(cil_out, "(%s %s)\n", CIL_KEY_TYPEATTRIBUTE, typeattr->datum.name); + return SEPOL_OK; +} + +static int cil_write_typeattributeset(struct cil_tree_node *node, FILE *cil_out) { + int rc = SEPOL_ERR; + char *typeattr; + char *set_str = NULL; + struct cil_typeattributeset *typeattrset = (struct cil_typeattributeset *)node->data; + + typeattr = typeattrset->attr_str; + rc = cil_unfill_expr(typeattrset->str_expr, &set_str, 1); + if (rc != SEPOL_OK) + goto exit; + + fprintf(cil_out, "(%s %s %s)\n", CIL_KEY_TYPEATTRIBUTESET, typeattr, set_str); + rc = SEPOL_OK; +exit: + free(set_str); + return rc; +} + +static int cil_write_expandtypeattribute(struct cil_tree_node *node, FILE *cil_out) +{ + int rc = SEPOL_ERR; + char *attr_strs = NULL; + struct cil_expandtypeattribute *expandattr = (struct cil_expandtypeattribute *)node->data; + + rc = cil_unfill_expr(expandattr->attr_strs, &attr_strs, 1); + if (rc != SEPOL_OK) + goto exit; + + fprintf(cil_out, "(%s %s %s)\n", CIL_KEY_EXPANDTYPEATTRIBUTE, attr_strs, + expandattr->expand ? CIL_KEY_CONDTRUE : CIL_KEY_CONDFALSE); + rc = SEPOL_OK; +exit: + free(attr_strs); + return rc; +} + +static int cil_write_alias(struct cil_tree_node *node, FILE *cil_out) { + int rc = SEPOL_ERR; + char *type; + struct cil_alias *alias = (struct cil_alias *)node->data; + + switch (node->flavor) { + case CIL_TYPEALIAS: + type = CIL_KEY_TYPEALIAS; + break; + case CIL_SENSALIAS: + type = CIL_KEY_SENSALIAS; + break; + case CIL_CATALIAS: + type = CIL_KEY_CATALIAS; + break; + default: + cil_log(CIL_ERR, "Unknown alias type: %d\n", node->flavor); + rc = SEPOL_ERR; + goto exit; + break; + } + fprintf(cil_out, "(%s %s)\n", type, alias->datum.name); + rc = SEPOL_OK; +exit: + return rc; +} + +static int cil_write_aliasactual(struct cil_tree_node *node, FILE *cil_out) { + int rc = SEPOL_ERR; + char *type, *alias, *actual; + struct cil_aliasactual *aliasact = (struct cil_aliasactual *)node->data; + + switch (node->flavor) { + case CIL_TYPEALIASACTUAL: + type = CIL_KEY_TYPEALIASACTUAL; + break; + case CIL_SENSALIASACTUAL: + type = CIL_KEY_SENSALIASACTUAL; + break; + case CIL_CATALIASACTUAL: + type = CIL_KEY_CATALIASACTUAL; + break; + default: + cil_log(CIL_ERR, "Unknown alias type: %d\n", node->flavor); + rc = SEPOL_ERR; + goto exit; + break; + } + alias = aliasact->alias_str; + actual = aliasact->actual_str; + fprintf(cil_out, "(%s %s %s)\n", type, alias, actual); + rc = SEPOL_OK; +exit: + return rc; +} + +static int cil_write_nametypetransition(struct cil_tree_node *node, FILE *cil_out) { + char *src, *tgt, *obj, *res, *name; + struct cil_nametypetransition *ntrans = (struct cil_nametypetransition *)node->data; + + src = ntrans->src_str; + tgt = ntrans->tgt_str; + obj = ntrans->obj_str; + res = ntrans->result_str; + name = ntrans->name_str; + fprintf(cil_out, "(%s %s %s %s \"%s\" %s)\n", CIL_KEY_TYPETRANSITION, + src, tgt, obj, name, res); + return SEPOL_OK; +} + +static int cil_write_avrule_x(struct cil_avrule *avrule, FILE *cil_out) { + int rc = SEPOL_ERR; + char *rulekind, *src, *tgt; + char *xperms = NULL; + + switch (avrule->rule_kind) { + case CIL_AVRULE_ALLOWED: + rulekind = CIL_KEY_ALLOWX; + break; + case CIL_AVRULE_AUDITALLOW: + rulekind = CIL_KEY_AUDITALLOWX; + break; + case CIL_AVRULE_DONTAUDIT: + rulekind = CIL_KEY_DONTAUDITX; + break; + case CIL_AVRULE_NEVERALLOW: + rulekind = CIL_KEY_NEVERALLOWX; + break; + default: + cil_log(CIL_ERR, "Unknown AVRULE type: %d\n", avrule->rule_kind); + rc = SEPOL_ERR; + goto exit; + break; + } + src = avrule->src_str; + tgt = avrule->tgt_str; + + if (avrule->perms.x.permx_str != NULL) { + xperms = strdup(avrule->perms.x.permx_str); + if (xperms == NULL) { + cil_log(CIL_ERR, "OOM. Unable to copy xperms string.\n"); + rc = SEPOL_ERR; + goto exit; + } + } else { + rc = cil_unfill_permx(avrule->perms.x.permx, &xperms); + if (rc != SEPOL_OK) + goto exit; + } + fprintf(cil_out, "(%s %s %s %s)\n", rulekind, src, tgt, xperms); + rc = SEPOL_OK; +exit: + free(xperms); + return rc; +} + +static int cil_write_avrule_orig(struct cil_avrule *avrule, FILE *cil_out) { + int rc = SEPOL_ERR; + char *rulekind, *src, *tgt; + char *classperms = NULL; + + switch (avrule->rule_kind) { + case CIL_AVRULE_ALLOWED: + rulekind = CIL_KEY_ALLOW; + break; + case CIL_AVRULE_AUDITALLOW: + rulekind = CIL_KEY_AUDITALLOW; + break; + case CIL_AVRULE_DONTAUDIT: + rulekind = CIL_KEY_DONTAUDIT; + break; + case CIL_AVRULE_NEVERALLOW: + rulekind = CIL_KEY_NEVERALLOW; + break; + default: + cil_log(CIL_ERR, "Unknown AVRULE type: %d\n", avrule->rule_kind); + rc = SEPOL_ERR; + goto exit; + break; + } + src = avrule->src_str; + tgt = avrule->tgt_str; + + rc = cil_unfill_classperms_list(avrule->perms.classperms, &classperms, 0); + if (rc != SEPOL_OK) + goto exit; + fprintf(cil_out, "(%s %s %s %s)\n", rulekind, src, tgt, classperms); + rc = SEPOL_OK; +exit: + free(classperms); + return rc; +} + +static int cil_write_avrule(struct cil_tree_node *node, FILE *cil_out) { + int rc = SEPOL_ERR; + struct cil_avrule *avrule = (struct cil_avrule *)node->data; + + if (avrule->is_extended) + rc = cil_write_avrule_x(avrule, cil_out); + else + rc = cil_write_avrule_orig(avrule, cil_out); + return rc; +} + +static int cil_write_type_rule(struct cil_tree_node *node, FILE *cil_out) { + int rc = SEPOL_ERR; + char *type, *src, *tgt, *obj, *res; + struct cil_type_rule *typerule = (struct cil_type_rule *)node->data; + + switch (typerule->rule_kind) { + case CIL_TYPE_TRANSITION: + type = CIL_KEY_TYPETRANSITION; + break; + case CIL_TYPE_MEMBER: + type = CIL_KEY_TYPEMEMBER; + break; + case CIL_TYPE_CHANGE: + type = CIL_KEY_TYPECHANGE; + break; + default: + cil_log(CIL_ERR, "Unknown TYPERULE type: %d\n", typerule->rule_kind); + rc = SEPOL_ERR; + goto exit; + break; + } + src = typerule->src_str; + tgt = typerule->tgt_str; + obj = typerule->obj_str; + res = typerule->result_str; + fprintf(cil_out, "(%s %s %s %s %s)\n", type, src, tgt, obj, res); + rc = SEPOL_OK; +exit: + return rc; +} + +static int cil_write_sens(struct cil_tree_node *node, FILE *cil_out) { + struct cil_sens *sens = (struct cil_sens *)node->data; + fprintf(cil_out, "(%s %s)\n", CIL_KEY_SENSITIVITY, sens->datum.name); + return SEPOL_OK; +} + +static int cil_write_cat(struct cil_tree_node *node, FILE *cil_out) { + struct cil_cat *cat = (struct cil_cat *)node->data; + fprintf(cil_out, "(%s %s)\n", CIL_KEY_CATEGORY, cat->datum.name); + return SEPOL_OK; +} + +static int cil_write_senscat(struct cil_tree_node *node, FILE *cil_out) { + int rc = SEPOL_ERR; + char *sens; + char *cats = NULL; + struct cil_senscat *senscat = (struct cil_senscat *)node->data; + + sens = senscat->sens_str; + rc = cil_unfill_cats(senscat->cats, &cats); + if (rc != SEPOL_OK) + goto exit; + /* TODO: deal with extra/missing parens */ + fprintf(cil_out, "(%s %s (%s))\n", CIL_KEY_SENSCAT, sens, cats); + rc = SEPOL_OK; +exit: + free(cats); + return rc; +} + +static int cil_write_catorder(struct cil_tree_node *node, FILE *cil_out) { + int rc = SEPOL_ERR; + char *ord_str = NULL; + struct cil_catorder *catord = (struct cil_catorder *)node->data; + + /* cil_unfill_expr() has logic to stringify a cil_list, reuse that. */ + rc = cil_unfill_expr(catord->cat_list_str, &ord_str, 1); + if (rc != SEPOL_OK) + goto exit; + fprintf(cil_out, "(%s %s)\n", CIL_KEY_CATORDER, ord_str); + rc = SEPOL_OK; +exit: + free(ord_str); + return rc; +} + +static int cil_write_sensorder(struct cil_tree_node *node, FILE *cil_out) { + int rc = SEPOL_ERR; + char *ord_str = NULL; + struct cil_sensorder *sensord = (struct cil_sensorder *)node->data; + + /* cil_unfill_expr() has logic to stringify a cil_list, reuse that. */ + rc = cil_unfill_expr(sensord->sens_list_str, &ord_str, 1); + if (rc != SEPOL_OK) + goto exit; + fprintf(cil_out, "(%s %s)\n", CIL_KEY_SENSITIVITYORDER, ord_str); + rc = SEPOL_OK; +exit: + free(ord_str); + return rc; +} + +static int cil_write_genfscon(struct cil_tree_node *node, FILE *cil_out) { + int rc = SEPOL_ERR; + char *ctx_str = NULL; + + struct cil_genfscon *genfscon = (struct cil_genfscon *)node->data; + if (genfscon->context_str != NULL) { + ctx_str = strdup(genfscon->context_str); + if (ctx_str == NULL) { + cil_log(CIL_ERR, "OOM. Unable to copy context string.\n"); + rc = SEPOL_ERR; + goto exit; + } + } else { + rc = cil_unfill_context(genfscon->context, &ctx_str); + if (rc != SEPOL_OK) + goto exit; + } + fprintf(cil_out, "(%s %s %s %s)\n", CIL_KEY_GENFSCON, genfscon->fs_str, + genfscon->path_str, ctx_str); + rc = SEPOL_OK; +exit: + free(ctx_str); + return rc; +} + +static int cil_unfill_classperms(struct cil_list_item *curr, char **out_str) { + int rc = SEPOL_ERR; + size_t len = 3; + char *class_str; + char *perms_str = NULL; + struct cil_classperms *cp = (struct cil_classperms *)curr->data; + + class_str = cp->class_str; + len += strlen(class_str) + 1; + + /* fill_perms just calls gen_expr */ + rc = cil_unfill_expr(cp->perm_strs, &perms_str, 1); + if (rc != SEPOL_OK) + goto exit; + len += strlen(perms_str); + *out_str = cil_malloc(len); + sprintf(*out_str, "(%s %s)", class_str, perms_str); + rc = SEPOL_OK; +exit: + free(perms_str); + return rc; +} + +static int cil_unfill_classperms_list(struct cil_list *classperms, char **out_str, int paren) { + int rc = SEPOL_ERR; + struct cil_list_item *curr; + char *str = NULL; + + /* reuse cil_list to keep track of strings */ + struct cil_list *str_list = NULL; + cil_list_init(&str_list, CIL_NONE); + cil_list_for_each(curr, classperms) { + switch (curr->flavor) { + case CIL_CLASSPERMS_SET: + str = strdup(((struct cil_classperms_set *)curr->data)->set_str); + if (str == NULL) { + cil_log(CIL_ERR, "OOM. Unable to copy classpermset.\n"); + rc = SEPOL_ERR; + goto exit; + } + break; + case CIL_CLASSPERMS: + rc = cil_unfill_classperms(curr, &str); + if (rc != SEPOL_OK) + goto exit; + break; + default: + cil_log(CIL_ERR, "Unrecognized classperms flavor\n."); + goto exit; + } + cil_list_append(str_list, CIL_STRING, (void *) str); + str = NULL; + } + rc = __cil_strlist_concat(str_list, out_str, paren); + if (rc != SEPOL_OK) + goto exit; + rc = SEPOL_OK; +exit: + cil_list_for_each(curr, str_list) { + free(curr->data); + } + cil_list_destroy(&str_list, 0); + return rc; +} + +static int cil_write_fsuse(struct cil_tree_node *node, FILE *cil_out) { + int rc = SEPOL_ERR; + struct cil_fsuse *fsuse = (struct cil_fsuse *)node->data; + char *type, *fsname; + char *ctx_str = NULL; + + switch(fsuse->type) { + case CIL_FSUSE_XATTR: + type = CIL_KEY_XATTR; + break; + case CIL_FSUSE_TASK: + type = CIL_KEY_TASK; + break; + case CIL_FSUSE_TRANS: + type = CIL_KEY_TRANS; + break; + default: + cil_log(CIL_ERR, "Unrecognized fsuse type\n"); + rc = SEPOL_ERR; + goto exit; + break; + } + + fsname = fsuse->fs_str; + if (fsuse->context_str != NULL) { + ctx_str = strdup(fsuse->context_str); + if (ctx_str == NULL) { + cil_log(CIL_ERR, "OOM. Unable to copy context string.\n"); + rc = SEPOL_ERR; + goto exit; + } + } else { + rc = cil_unfill_context(fsuse->context, &ctx_str); + if (rc != SEPOL_OK) + goto exit; + } + fprintf(cil_out, "(%s %s %s %s)\n", CIL_KEY_FSUSE, type, fsname, ctx_str); +exit: + free(ctx_str); + return rc; +} + +static int cil_write_constrain(struct cil_tree_node *node, FILE *cil_out) { + int rc = SEPOL_ERR; + struct cil_constrain *cons = (struct cil_constrain *)node->data; + char *flav; + char *classperms = NULL; + char *expr = NULL; + + flav = (node->flavor == CIL_CONSTRAIN) ? CIL_KEY_CONSTRAIN : CIL_KEY_MLSCONSTRAIN; + + rc = cil_unfill_classperms_list(cons->classperms, &classperms, 0); + if (rc != SEPOL_OK) + goto exit; + + rc = cil_unfill_expr(cons->str_expr, &expr, 0); + if (rc != SEPOL_OK) + goto exit; + + fprintf(cil_out, "(%s %s %s)\n", flav, classperms, expr); +exit: + free(classperms); + free(expr); + return rc; +} + +static int cil_write_handleunknown(struct cil_tree_node *node, FILE *cil_out) { + int rc = SEPOL_OK; + struct cil_handleunknown *handunknown = (struct cil_handleunknown *)node->data; + char *val = NULL; + switch (handunknown->handle_unknown) { + case SEPOL_ALLOW_UNKNOWN: + val = CIL_KEY_HANDLEUNKNOWN_ALLOW; + break; + case SEPOL_DENY_UNKNOWN: + val = CIL_KEY_HANDLEUNKNOWN_DENY; + break; + case SEPOL_REJECT_UNKNOWN: + val = CIL_KEY_HANDLEUNKNOWN_REJECT; + break; + default: + cil_log(CIL_ERR, "Unknown handleunknown value: %d.\n", + handunknown->handle_unknown); + rc = SEPOL_ERR; + goto exit; + break; + } + fprintf(cil_out, "(%s %s)\n", CIL_KEY_HANDLEUNKNOWN, val); +exit: + return rc; +} + +static int cil_write_mls(struct cil_tree_node *node, FILE *cil_out) { + int rc = SEPOL_OK; + struct cil_mls *mls = (struct cil_mls *)node->data; + char *val = NULL; + switch (mls->value) { + case CIL_TRUE: + val = CIL_KEY_CONDTRUE; + break; + case CIL_FALSE: + val = CIL_KEY_CONDFALSE; + break; + default: + cil_log(CIL_ERR, "Unknown mls value: %d.\n", mls->value); + rc = SEPOL_ERR; + goto exit; + break; + } + fprintf(cil_out, "(%s %s)\n", CIL_KEY_MLS, val); +exit: + return rc; +} + +static int __cil_write_first_child_helper(struct cil_tree_node *node, void *extra_args) +{ + int rc = SEPOL_ERR; + struct cil_args_write *args = (struct cil_args_write *) extra_args; + FILE *cil_out = NULL; + + if (node == NULL || extra_args == NULL) { + goto exit; + } + + cil_out = args->cil_out; + + if (node->parent && node->parent->flavor != CIL_ROOT && node->parent->flavor != CIL_SRC_INFO) + fprintf(cil_out,"("); + rc = SEPOL_OK; +exit: + return rc; +} + +static int __cil_write_node_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) +{ + int rc = SEPOL_OK; + struct cil_args_write *args = NULL; + FILE *cil_out = NULL; + + if (node == NULL || extra_args == NULL) { + goto exit; + } + + args = extra_args; + cil_out = args->cil_out; + + switch (node->flavor) { + case CIL_BLOCK: + rc = cil_write_unsupported("CIL_BLOCK"); + break; + case CIL_BLOCKABSTRACT: + rc = cil_write_unsupported("CIL_BLOCKABSTRACT"); + break; + case CIL_BLOCKINHERIT: + rc = cil_write_unsupported("CIL_BLOCKINHERIT"); + break; + case CIL_IN: + rc = cil_write_unsupported("CIL_IN"); + break; + case CIL_POLICYCAP: + cil_write_policycap(node, cil_out); + break; + case CIL_PERM: + rc = cil_write_perm(node, cil_out); + break; + case CIL_MAP_PERM: + rc = cil_write_unsupported("CIL_MAP_PERM"); + break; + case CIL_CLASSMAPPING: + rc = cil_write_unsupported("CIL_CLASSMAPPING"); + break; + case CIL_CLASS: + rc = cil_write_class(node, finished, extra_args); + break; + case CIL_COMMON: + rc = cil_write_class(node, finished, extra_args); + break; + case CIL_MAP_CLASS: + rc = cil_write_unsupported("CIL_MAP_CLASS"); + break; + case CIL_CLASSORDER: + rc = cil_write_classorder(node, cil_out); + break; + case CIL_CLASSPERMISSION: + rc = cil_write_unsupported("CIL_CLASSPERMISSION"); + break; + case CIL_CLASSPERMISSIONSET: + rc = cil_write_unsupported("CIL_CLASSPERMISSIONSET"); + break; + case CIL_CLASSCOMMON: + rc = cil_write_classcommon(node, cil_out); + break; + case CIL_SID: + rc = cil_write_sid(node, cil_out); + break; + case CIL_SIDCONTEXT: + rc = cil_write_sidcontext(node, cil_out); + break; + case CIL_SIDORDER: + rc = cil_write_sidorder(node, cil_out); + break; + case CIL_USER: + rc = cil_write_user(node, cil_out); + break; + case CIL_USERATTRIBUTE: + rc = cil_write_unsupported("CIL_USERATTRIBUTE"); + break; + case CIL_USERATTRIBUTESET: + rc = cil_write_unsupported("CIL_USERATTRIBUTESET"); + break; + case CIL_USERROLE: + rc = cil_write_userrole(node, cil_out); + break; + case CIL_USERLEVEL: + rc = cil_write_userlevel(node, cil_out); + break; + case CIL_USERRANGE: + rc = cil_write_userrange(node, cil_out); + break; + case CIL_USERBOUNDS: + rc = cil_write_unsupported("CIL_USERBOUNDS"); + break; + case CIL_USERPREFIX: + rc = cil_write_unsupported("CIL_USERPREFIX"); + break; + case CIL_ROLE: + rc = cil_write_role(node, cil_out); + break; + case CIL_ROLETYPE: + rc = cil_write_roletype(node, cil_out); + break; + case CIL_ROLEBOUNDS: + rc = cil_write_unsupported("CIL_ROLEBOUNDS"); + break; + case CIL_ROLEATTRIBUTE: + cil_write_roleattribute(node, cil_out); + break; + case CIL_ROLEATTRIBUTESET: + rc = cil_write_unsupported("CIL_ROLEATTRIBUTESET"); + break; + case CIL_ROLEALLOW: + rc = cil_write_unsupported("CIL_ROLEALLOW"); + break; + case CIL_TYPE: + rc = cil_write_type(node, cil_out); + break; + case CIL_TYPEBOUNDS: + rc = cil_write_unsupported("CIL_TYPEBOUNDS"); + break; + case CIL_TYPEPERMISSIVE: + rc = cil_write_typepermissive(node, cil_out); + break; + case CIL_TYPEATTRIBUTE: + rc = cil_write_typeattribute(node, cil_out); + break; + case CIL_TYPEATTRIBUTESET: + rc = cil_write_typeattributeset(node, cil_out); + break; + case CIL_EXPANDTYPEATTRIBUTE: + rc = cil_write_expandtypeattribute(node, cil_out); + break; + case CIL_TYPEALIAS: + rc = cil_write_alias(node, cil_out); + break; + case CIL_TYPEALIASACTUAL: + rc = cil_write_aliasactual(node, cil_out); + break; + case CIL_ROLETRANSITION: + rc = cil_write_unsupported("CIL_ROLETRANSITION"); + break; + case CIL_NAMETYPETRANSITION: + rc = cil_write_nametypetransition(node, cil_out); + break; + case CIL_RANGETRANSITION: + rc = cil_write_unsupported("CIL_RANGETRANSITION"); + break; + case CIL_TUNABLE: + rc = cil_write_unsupported("CIL_TUNABLE"); + break; + case CIL_BOOL: + rc = cil_write_unsupported("CIL_BOOL"); + break; + case CIL_AVRULE: + case CIL_AVRULEX: + rc = cil_write_avrule(node, cil_out); + break; + case CIL_PERMISSIONX: + rc = cil_write_unsupported("CIL_PERMISSIONX"); + break; + case CIL_TYPE_RULE: + cil_write_type_rule(node, cil_out); + break; + case CIL_SENS: + rc = cil_write_sens(node, cil_out); + break; + case CIL_SENSALIAS: + rc = cil_write_alias(node, cil_out); + break; + case CIL_SENSALIASACTUAL: + rc = cil_write_aliasactual(node, cil_out); + break; + case CIL_CAT: + rc = cil_write_cat(node, cil_out); + break; + case CIL_CATALIAS: + rc = cil_write_alias(node, cil_out); + break; + case CIL_CATALIASACTUAL: + rc = cil_write_aliasactual(node, cil_out); + break; + case CIL_CATSET: + rc = cil_write_unsupported("CIL_CATSET"); + break; + case CIL_SENSCAT: + rc = cil_write_senscat(node, cil_out); + break; + case CIL_CATORDER: + rc = cil_write_catorder(node, cil_out); + break; + case CIL_SENSITIVITYORDER: + rc = cil_write_sensorder(node, cil_out); + break; + case CIL_LEVEL: + rc = cil_write_unsupported("CIL_LEVEL"); + break; + case CIL_LEVELRANGE: + rc = cil_write_unsupported("CIL_LEVELRANGE"); + break; + case CIL_CONTEXT: + rc = cil_write_unsupported("CIL_CONTEXT"); + break; + case CIL_NETIFCON: + rc = cil_write_unsupported("CIL_NETIFCON"); + break; + case CIL_GENFSCON: + rc = cil_write_genfscon(node, cil_out); + break; + case CIL_FILECON: + rc = cil_write_unsupported("CIL_FILECON"); + break; + case CIL_NODECON: + rc = cil_write_unsupported("CIL_NODECON"); + break; + case CIL_PORTCON: + rc = cil_write_unsupported("CIL_PORTCON"); + break; + case CIL_PIRQCON: + rc = cil_write_unsupported("CIL_PIRQCON"); + break; + case CIL_IOMEMCON: + rc = cil_write_unsupported("CIL_IOMEMCON"); + break; + case CIL_IOPORTCON: + rc = cil_write_unsupported("CIL_IOPORTCON"); + break; + case CIL_PCIDEVICECON: + rc = cil_write_unsupported("CIL_PCIDEVICECON"); + break; + case CIL_DEVICETREECON: + rc = cil_write_unsupported("CIL_DEVICETREECON"); + break; + case CIL_FSUSE: + rc = cil_write_fsuse(node, cil_out); + break; + case CIL_CONSTRAIN: + rc = cil_write_unsupported("CIL_CONSTRAIN"); + break; + case CIL_MLSCONSTRAIN: + rc = cil_write_constrain(node, cil_out); + break; + case CIL_VALIDATETRANS: + rc = cil_write_unsupported("CIL_VALIDATETRANS"); + break; + case CIL_MLSVALIDATETRANS: + rc = cil_write_unsupported("CIL_MLSVALIDATETRANS"); + break; + case CIL_CALL: + rc = cil_write_unsupported("CIL_CALL"); + break; + case CIL_MACRO: + rc = cil_write_unsupported("CIL_MACRO"); + break; + case CIL_NODE: + rc = cil_write_unsupported("CIL_NODE"); + break; + case CIL_OPTIONAL: + rc = cil_write_unsupported("CIL_OPTIONAL"); + break; + case CIL_IPADDR: + rc = cil_write_unsupported("CIL_IPADDR"); + break; + case CIL_CONDBLOCK: + rc = cil_write_unsupported("CIL_CONDBLOCK"); + break; + case CIL_BOOLEANIF: + rc = cil_write_unsupported("CIL_BOOLEANIF"); + break; + case CIL_TUNABLEIF: + rc = cil_write_unsupported("CIL_TUNABLEIF"); + break; + case CIL_DEFAULTUSER: + rc = cil_write_unsupported("CIL_DEFAULTUSER"); + break; + case CIL_DEFAULTROLE: + rc = cil_write_unsupported("CIL_DEFAULTROLE"); + break; + case CIL_DEFAULTTYPE: + rc = cil_write_unsupported("CIL_DEFAULTTYPE"); + break; + case CIL_DEFAULTRANGE: + rc = cil_write_unsupported("CIL_DEFAULTRANGE"); + break; + case CIL_SELINUXUSER: + rc = cil_write_unsupported("CIL_SELINUXUSER"); + break; + case CIL_SELINUXUSERDEFAULT: + rc = cil_write_unsupported("CIL_SELINUXUSERDEFAULT"); + break; + case CIL_HANDLEUNKNOWN: + rc = cil_write_handleunknown(node, cil_out); + break; + case CIL_MLS: + rc = cil_write_mls(node, cil_out); + break; + case CIL_SRC_INFO: + break; + case CIL_NONE: + // TODO: add proper removal support + *finished = CIL_TREE_SKIP_HEAD; + break; + default: + cil_log(CIL_ERR, "Unknown AST flavor: %d.\n", node->flavor); + rc = SEPOL_ERR; + goto exit; + break; + } +exit: + return rc; +} + +static int __cil_write_last_child_helper(struct cil_tree_node *node, void *extra_args) +{ + int rc = SEPOL_ERR; + struct cil_args_write *args = NULL; + FILE *cil_out = NULL; + + if (node == NULL || extra_args == NULL) { + goto exit; + } + + args = extra_args; + cil_out = args->cil_out; + + if (node->parent && node->parent->flavor != CIL_ROOT && node->parent->flavor != CIL_SRC_INFO) { + fprintf(cil_out,")"); + } + rc = SEPOL_OK; +exit: + return rc; +} + +/* main exported function */ +int cil_write_ast(struct cil_db *db, const char* path) { + int rc = SEPOL_ERR; + struct cil_args_write extra_args; + FILE *cil_out = NULL; + + cil_out = fopen(path, "we"); + if (cil_out == NULL) { + cil_log(CIL_ERR, "Failure opening output file for writing AST\n"); + rc = SEPOL_ERR; + goto exit; + } + + extra_args.cil_out = cil_out; + extra_args.db = db; + rc = cil_tree_walk(db->ast->root, __cil_write_node_helper, + __cil_write_first_child_helper, + __cil_write_last_child_helper, + &extra_args); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "cil_tree_walk failed, rc: %d\n", rc); + goto exit; + } + +exit: + fclose(cil_out); + cil_out = NULL; + return rc; +} diff --git a/libsepol/cil/src/cil_write_ast.h b/libsepol/cil/src/cil_write_ast.h deleted file mode 100644 index 3f4b9d95..00000000 --- a/libsepol/cil/src/cil_write_ast.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2011 Tresys Technology, LLC. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those - * of the authors and should not be interpreted as representing official policies, - * either expressed or implied, of Tresys Technology, LLC. - */ - -#ifndef CIL_WRITE_AST_H_ -#define CIL_WRITE_AST_H_ - -#include - -#include "cil_tree.h" - -enum cil_write_ast_phase { - CIL_WRITE_AST_PHASE_PARSE = 0, - CIL_WRITE_AST_PHASE_BUILD, - CIL_WRITE_AST_PHASE_RESOLVE, -}; - -void cil_write_ast_node(FILE *out, struct cil_tree_node *node); -int cil_write_ast(FILE *out, enum cil_write_ast_phase phase, struct cil_tree_node *node); - -#endif /* CIL_WRITE_AST_H_ */ diff --git a/libsepol/cil/src/dso.h b/libsepol/cil/src/dso.h new file mode 100644 index 00000000..64a162ce --- /dev/null +++ b/libsepol/cil/src/dso.h @@ -0,0 +1,27 @@ +#ifndef _SEPOL_DSO_H +#define _SEPOL_DSO_H 1 + +#if !defined(SHARED) || defined(ANDROID) || defined(__APPLE__) + #define DISABLE_SYMVER 1 +#endif + +#ifdef SHARED +# define hidden __attribute__ ((visibility ("hidden"))) +# define hidden_proto(fct) __hidden_proto (fct, fct##_internal) +# define __hidden_proto(fct, internal) \ + extern __typeof (fct) internal; \ + extern __typeof (fct) fct __asm (#internal) hidden; +# if defined(__alpha__) || defined(__mips__) +# define hidden_def(fct) \ + asm (".globl " #fct "\n" #fct " = " #fct "_internal"); +# else +# define hidden_def(fct) \ + asm (".globl " #fct "\n.set " #fct ", " #fct "_internal"); +#endif +#else +# define hidden +# define hidden_proto(fct) +# define hidden_def(fct) +#endif + +#endif diff --git a/libsepol/fuzz/secilc-fuzzer.c b/libsepol/fuzz/secilc-fuzzer.c deleted file mode 100644 index 255b3241..00000000 --- a/libsepol/fuzz/secilc-fuzzer.c +++ /dev/null @@ -1,69 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include - -int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - enum cil_log_level log_level = CIL_ERR; - struct sepol_policy_file *pf = NULL; - FILE *dev_null = NULL; - int target = SEPOL_TARGET_SELINUX; - int disable_dontaudit = 0; - int multiple_decls = 0; - int disable_neverallow = 0; - int preserve_tunables = 0; - int policyvers = POLICYDB_VERSION_MAX; - int mls = -1; - int attrs_expand_generated = 0; - struct cil_db *db = NULL; - sepol_policydb_t *pdb = NULL; - - cil_set_log_level(log_level); - - cil_db_init(&db); - cil_set_disable_dontaudit(db, disable_dontaudit); - cil_set_multiple_decls(db, multiple_decls); - cil_set_disable_neverallow(db, disable_neverallow); - cil_set_preserve_tunables(db, preserve_tunables); - cil_set_mls(db, mls); - cil_set_target_platform(db, target); - cil_set_policy_version(db, policyvers); - cil_set_attrs_expand_generated(db, attrs_expand_generated); - - if (cil_add_file(db, "fuzz", (const char *)data, size) != SEPOL_OK) - goto exit; - - if (cil_compile(db) != SEPOL_OK) - goto exit; - - if (cil_build_policydb(db, &pdb) != SEPOL_OK) - goto exit; - - if (sepol_policydb_optimize(pdb) != SEPOL_OK) - goto exit; - - dev_null = fopen("/dev/null", "w"); - if (dev_null == NULL) - goto exit; - - if (sepol_policy_file_create(&pf) != 0) - goto exit; - - sepol_policy_file_set_fp(pf, dev_null); - - if (sepol_policydb_write(pdb, pf) != 0) - goto exit; -exit: - if (dev_null != NULL) - fclose(dev_null); - - cil_db_destroy(&db); - sepol_policydb_free(pdb); - sepol_policy_file_free(pf); - return 0; -} diff --git a/libsepol/include/sepol/booleans.h b/libsepol/include/sepol/booleans.h index 25229057..06d2230c 100644 --- a/libsepol/include/sepol/booleans.h +++ b/libsepol/include/sepol/booleans.h @@ -10,6 +10,11 @@ extern "C" { #endif +/* These two functions are deprecated. See src/deprecated_funcs.c */ +extern int sepol_genbools(void *data, size_t len, const char *boolpath); +extern int sepol_genbools_array(void *data, size_t len, + char **names, int *values, int nel); + /* Set the specified boolean */ extern int sepol_bool_set(sepol_handle_t * handle, sepol_policydb_t * policydb, diff --git a/libsepol/include/sepol/policydb/conditional.h b/libsepol/include/sepol/policydb/conditional.h index 49c0d766..9c3df3ef 100644 --- a/libsepol/include/sepol/policydb/conditional.h +++ b/libsepol/include/sepol/policydb/conditional.h @@ -90,7 +90,7 @@ typedef struct cond_node { uint32_t expr_pre_comp; struct cond_node *next; /* a tunable conditional, calculated and used at expansion */ -#define COND_NODE_FLAGS_TUNABLE UINT32_C(0x01) +#define COND_NODE_FLAGS_TUNABLE 0x01 uint32_t flags; } cond_node_t; diff --git a/libsepol/include/sepol/policydb/ebitmap.h b/libsepol/include/sepol/policydb/ebitmap.h index 81d0c7a6..e62df01c 100644 --- a/libsepol/include/sepol/policydb/ebitmap.h +++ b/libsepol/include/sepol/policydb/ebitmap.h @@ -39,7 +39,6 @@ typedef struct ebitmap { uint32_t highbit; /* highest position in the total bitmap */ } ebitmap_t; -#define ebitmap_is_empty(e) (((e)->highbit) == 0) #define ebitmap_length(e) ((e)->highbit) #define ebitmap_startbit(e) ((e)->node ? (e)->node->startbit : 0) #define ebitmap_startnode(e) ((e)->node) @@ -67,7 +66,7 @@ static inline unsigned int ebitmap_next(ebitmap_node_t ** n, unsigned int bit) return (bit + 1); } -static inline int ebitmap_node_get_bit(const ebitmap_node_t * n, unsigned int bit) +static inline int ebitmap_node_get_bit(ebitmap_node_t * n, unsigned int bit) { if (n->map & (MAPBIT << (bit - n->startbit))) return 1; @@ -83,18 +82,17 @@ static inline int ebitmap_node_get_bit(const ebitmap_node_t * n, unsigned int bi extern int ebitmap_cmp(const ebitmap_t * e1, const ebitmap_t * e2); extern int ebitmap_or(ebitmap_t * dst, const ebitmap_t * e1, const ebitmap_t * e2); extern int ebitmap_union(ebitmap_t * dst, const ebitmap_t * e1); -extern int ebitmap_and(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2); -extern int ebitmap_xor(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2); -extern int ebitmap_not(ebitmap_t *dst, const ebitmap_t *e1, unsigned int maxbit); -extern int ebitmap_andnot(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2, unsigned int maxbit); -extern unsigned int ebitmap_cardinality(const ebitmap_t *e1); -extern int ebitmap_hamming_distance(const ebitmap_t * e1, const ebitmap_t * e2); +extern int ebitmap_and(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2); +extern int ebitmap_xor(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2); +extern int ebitmap_not(ebitmap_t *dst, ebitmap_t *e1, unsigned int maxbit); +extern int ebitmap_andnot(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2, unsigned int maxbit); +extern unsigned int ebitmap_cardinality(ebitmap_t *e1); +extern int ebitmap_hamming_distance(ebitmap_t * e1, ebitmap_t * e2); extern int ebitmap_cpy(ebitmap_t * dst, const ebitmap_t * src); extern int ebitmap_contains(const ebitmap_t * e1, const ebitmap_t * e2); extern int ebitmap_match_any(const ebitmap_t *e1, const ebitmap_t *e2); extern int ebitmap_get_bit(const ebitmap_t * e, unsigned int bit); extern int ebitmap_set_bit(ebitmap_t * e, unsigned int bit, int value); -extern unsigned int ebitmap_highest_set_bit(const ebitmap_t * e); extern void ebitmap_destroy(ebitmap_t * e); extern int ebitmap_read(ebitmap_t * e, void *fp); diff --git a/libsepol/include/sepol/policydb/flask.h b/libsepol/include/sepol/policydb/flask.h new file mode 100644 index 00000000..3134284b --- /dev/null +++ b/libsepol/include/sepol/policydb/flask.h @@ -0,0 +1,94 @@ +/* This file is automatically generated. Do not edit. */ +#ifndef _SEPOL_POLICYDB_FLASK_H_ +#define _SEPOL_POLICYDB_FLASK_H_ + +/* + * Security object class definitions + */ +#define SECCLASS_SECURITY 1 +#define SECCLASS_PROCESS 2 +#define SECCLASS_SYSTEM 3 +#define SECCLASS_CAPABILITY 4 +#define SECCLASS_FILESYSTEM 5 +#define SECCLASS_FILE 6 +#define SECCLASS_DIR 7 +#define SECCLASS_FD 8 +#define SECCLASS_LNK_FILE 9 +#define SECCLASS_CHR_FILE 10 +#define SECCLASS_BLK_FILE 11 +#define SECCLASS_SOCK_FILE 12 +#define SECCLASS_FIFO_FILE 13 +#define SECCLASS_SOCKET 14 +#define SECCLASS_TCP_SOCKET 15 +#define SECCLASS_UDP_SOCKET 16 +#define SECCLASS_RAWIP_SOCKET 17 +#define SECCLASS_NODE 18 +#define SECCLASS_NETIF 19 +#define SECCLASS_NETLINK_SOCKET 20 +#define SECCLASS_PACKET_SOCKET 21 +#define SECCLASS_KEY_SOCKET 22 +#define SECCLASS_UNIX_STREAM_SOCKET 23 +#define SECCLASS_UNIX_DGRAM_SOCKET 24 +#define SECCLASS_SEM 25 +#define SECCLASS_MSG 26 +#define SECCLASS_MSGQ 27 +#define SECCLASS_SHM 28 +#define SECCLASS_IPC 29 +#define SECCLASS_PASSWD 30 +#define SECCLASS_DRAWABLE 31 +#define SECCLASS_WINDOW 32 +#define SECCLASS_GC 33 +#define SECCLASS_FONT 34 +#define SECCLASS_COLORMAP 35 +#define SECCLASS_PROPERTY 36 +#define SECCLASS_CURSOR 37 +#define SECCLASS_XCLIENT 38 +#define SECCLASS_XINPUT 39 +#define SECCLASS_XSERVER 40 +#define SECCLASS_XEXTENSION 41 +#define SECCLASS_PAX 42 +#define SECCLASS_NETLINK_ROUTE_SOCKET 43 +#define SECCLASS_NETLINK_FIREWALL_SOCKET 44 +#define SECCLASS_NETLINK_TCPDIAG_SOCKET 45 +#define SECCLASS_NETLINK_NFLOG_SOCKET 46 +#define SECCLASS_NETLINK_XFRM_SOCKET 47 +#define SECCLASS_NETLINK_SELINUX_SOCKET 48 +#define SECCLASS_NETLINK_AUDIT_SOCKET 49 +#define SECCLASS_NETLINK_IP6FW_SOCKET 50 +#define SECCLASS_NETLINK_DNRT_SOCKET 51 +#define SECCLASS_DBUS 52 + +/* + * Security identifier indices for initial entities + */ +#define SECINITSID_KERNEL 1 +#define SECINITSID_SECURITY 2 +#define SECINITSID_UNLABELED 3 +#define SECINITSID_FS 4 +#define SECINITSID_FILE 5 +#define SECINITSID_FILE_LABELS 6 +#define SECINITSID_INIT 7 +#define SECINITSID_ANY_SOCKET 8 +#define SECINITSID_PORT 9 +#define SECINITSID_NETIF 10 +#define SECINITSID_NETMSG 11 +#define SECINITSID_NODE 12 +#define SECINITSID_IGMP_PACKET 13 +#define SECINITSID_ICMP_SOCKET 14 +#define SECINITSID_TCP_SOCKET 15 +#define SECINITSID_SYSCTL_MODPROBE 16 +#define SECINITSID_SYSCTL 17 +#define SECINITSID_SYSCTL_FS 18 +#define SECINITSID_SYSCTL_KERNEL 19 +#define SECINITSID_SYSCTL_NET 20 +#define SECINITSID_SYSCTL_NET_UNIX 21 +#define SECINITSID_SYSCTL_VM 22 +#define SECINITSID_SYSCTL_DEV 23 +#define SECINITSID_KMOD 24 +#define SECINITSID_POLICY 25 +#define SECINITSID_SCMP_PACKET 26 +#define SECINITSID_DEVNULL 27 + +#define SECINITSID_NUM 27 + +#endif diff --git a/libsepol/include/sepol/policydb/flask_types.h b/libsepol/include/sepol/policydb/flask_types.h index 7bec5129..714176fd 100644 --- a/libsepol/include/sepol/policydb/flask_types.h +++ b/libsepol/include/sepol/policydb/flask_types.h @@ -33,13 +33,17 @@ typedef char *sepol_security_context_t; * for a pair of SIDs. The bits within an access vector * are interpreted differently depending on the class of * the object. The access vector interpretations are specified - * in policy. + * in flask/access_vectors, and the corresponding constants + * for permissions are defined in the automatically generated + * header file av_permissions.h. */ typedef uint32_t sepol_access_vector_t; /* * Each object class is identified by a fixed-size value. - * The set of security classes is specified in policy. + * The set of security classes is specified in flask/security_classes, + * with the corresponding constants defined in the automatically + * generated header file flask.h. */ typedef uint16_t sepol_security_class_t; #define SEPOL_SECCLASS_NULL 0x0000 /* no class */ diff --git a/libsepol/include/sepol/policydb/hashtab.h b/libsepol/include/sepol/policydb/hashtab.h index dca8c983..ca5ba862 100644 --- a/libsepol/include/sepol/policydb/hashtab.h +++ b/libsepol/include/sepol/policydb/hashtab.h @@ -79,6 +79,20 @@ extern int hashtab_remove(hashtab_t h, hashtab_key_t k, hashtab_datum_t d, void *args), void *args); +/* + Insert or replace the specified (key, datum) pair in the specified + hash table. If an entry for the specified key already exists, + then the specified destroy function is applied to (key,datum,args) + for the entry prior to replacing the entry's contents. + + Returns SEPOL_ENOMEM if insufficient space is available or + SEPOL_OK otherwise. + */ +extern int hashtab_replace(hashtab_t h, hashtab_key_t k, hashtab_datum_t d, + void (*destroy) (hashtab_key_t k, + hashtab_datum_t d, + void *args), void *args); + /* Searches for the entry with the specified key in the hash table. @@ -108,6 +122,20 @@ extern int hashtab_map(hashtab_t h, hashtab_datum_t d, void *args), void *args); +/* + Same as hashtab_map, except that if apply returns a non-zero status, + then the (key,datum) pair will be removed from the hashtab and the + destroy function will be applied to (key,datum,args). + */ +extern void hashtab_map_remove_on_error(hashtab_t h, + int (*apply) (hashtab_key_t k, + hashtab_datum_t d, + void *args), + void (*destroy) (hashtab_key_t k, + hashtab_datum_t d, + void *args), + void *args); + extern void hashtab_hash_eval(hashtab_t h, char *tag); #ifdef __cplusplus diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h index f0f3476c..3c356873 100644 --- a/libsepol/include/sepol/policydb/policydb.h +++ b/libsepol/include/sepol/policydb/policydb.h @@ -162,16 +162,15 @@ typedef struct role_allow { } role_allow_t; /* filename_trans rules */ -typedef struct filename_trans_key { +typedef struct filename_trans { + uint32_t stype; uint32_t ttype; uint32_t tclass; char *name; -} filename_trans_key_t; +} filename_trans_t; typedef struct filename_trans_datum { - ebitmap_t stypes; - uint32_t otype; - struct filename_trans_datum *next; + uint32_t otype; /* expected of new object */ } filename_trans_datum_t; /* Type attributes */ @@ -251,9 +250,9 @@ typedef struct class_perm_node { struct class_perm_node *next; } class_perm_node_t; -#define xperm_test(x, p) (UINT32_C(1) & (p[x >> 5] >> (x & 0x1f))) -#define xperm_set(x, p) (p[x >> 5] |= (UINT32_C(1) << (x & 0x1f))) -#define xperm_clear(x, p) (p[x >> 5] &= ~(UINT32_C(1) << (x & 0x1f))) +#define xperm_test(x, p) (1 & (p[x >> 5] >> (x & 0x1f))) +#define xperm_set(x, p) (p[x >> 5] |= (1 << (x & 0x1f))) +#define xperm_clear(x, p) (p[x >> 5] &= ~(1 << (x & 0x1f))) #define EXTENDED_PERMS_LEN 8 typedef struct av_extended_perms { @@ -592,7 +591,6 @@ typedef struct policydb { /* file transitions with the last path component */ hashtab_t filename_trans; - uint32_t filename_trans_count; ebitmap_t *type_attr_map; @@ -607,11 +605,6 @@ typedef struct policydb { unsigned policyvers; unsigned handle_unknown; - - sepol_security_class_t process_class; - sepol_security_class_t dir_class; - sepol_access_vector_t process_trans; - sepol_access_vector_t process_trans_dyntrans; } policydb_t; struct sepol_policydb { @@ -652,11 +645,6 @@ extern int policydb_load_isids(policydb_t * p, sidtab_t * s); extern int policydb_sort_ocontexts(policydb_t *p); -extern int policydb_filetrans_insert(policydb_t *p, uint32_t stype, - uint32_t ttype, uint32_t tclass, - const char *name, char **name_alloc, - uint32_t otype, uint32_t *present_otype); - /* Deprecated */ extern int policydb_context_isvalid(const policydb_t * p, const context_struct_t * c); @@ -667,8 +655,8 @@ extern int scope_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p); extern void class_perm_node_init(class_perm_node_t * x); extern void type_set_init(type_set_t * x); extern void type_set_destroy(type_set_t * x); -extern int type_set_cpy(type_set_t * dst, const type_set_t * src); -extern int type_set_or_eq(type_set_t * dst, const type_set_t * other); +extern int type_set_cpy(type_set_t * dst, type_set_t * src); +extern int type_set_or_eq(type_set_t * dst, type_set_t * other); extern void role_set_init(role_set_t * x); extern void role_set_destroy(role_set_t * x); extern void avrule_init(avrule_t * x); @@ -755,11 +743,10 @@ extern int policydb_set_target_platform(policydb_t *p, int platform); #define POLICYDB_VERSION_XPERMS_IOCTL 30 /* Linux-specific */ #define POLICYDB_VERSION_INFINIBAND 31 /* Linux-specific */ #define POLICYDB_VERSION_GLBLUB 32 -#define POLICYDB_VERSION_COMP_FTRANS 33 /* compressed filename transitions */ /* Range of policy versions we understand*/ #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE -#define POLICYDB_VERSION_MAX POLICYDB_VERSION_COMP_FTRANS +#define POLICYDB_VERSION_MAX POLICYDB_VERSION_GLBLUB /* Module versions and specific changes*/ #define MOD_POLICYDB_VERSION_BASE 4 diff --git a/libsepol/include/sepol/roles.h b/libsepol/include/sepol/roles.h new file mode 100644 index 00000000..e750078c --- /dev/null +++ b/libsepol/include/sepol/roles.h @@ -0,0 +1,18 @@ +#ifndef _SEPOL_ROLES_H_ +#define _SEPOL_ROLES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int sepol_role_exists(const sepol_policydb_t * policydb, + const char *role, int *response); + +extern int sepol_role_list(const sepol_policydb_t * policydb, + char ***roles, unsigned int *nroles); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libsepol/include/sepol/users.h b/libsepol/include/sepol/users.h index 156d1adb..70158ac4 100644 --- a/libsepol/include/sepol/users.h +++ b/libsepol/include/sepol/users.h @@ -10,6 +10,12 @@ extern "C" { #endif +/* These two functions are deprecated. See src/deprecated_funcs.c */ +extern int sepol_genusers(void *data, size_t len, + const char *usersdir, + void **newdata, size_t * newlen); +extern void sepol_set_delusers(int on); + /* Modify the user, or add it, if the key is not found */ extern int sepol_user_modify(sepol_handle_t * handle, sepol_policydb_t * policydb, diff --git a/libsepol/src/Makefile b/libsepol/src/Makefile index dc8b1773..ccb70233 100644 --- a/libsepol/src/Makefile +++ b/libsepol/src/Makefile @@ -7,7 +7,7 @@ RANLIB ?= ranlib CILDIR ?= ../cil VERSION = $(shell cat ../VERSION) -LIBVERSION = 2 +LIBVERSION = 1 LEX = flex CIL_GENERATED = $(CILDIR)/src/cil_lexer.c @@ -19,7 +19,7 @@ LIBMAP=libsepol.map LIBSO=$(TARGET).$(LIBVERSION) OBJS= $(patsubst %.c,%.o,$(sort $(wildcard *.c))) LOBJS= $(patsubst %.c,%.lo,$(sort $(wildcard *.c))) -CFLAGS ?= -Werror -Wall -W -Wundef -Wshadow -Wmissing-format-attribute -O2 -fno-semantic-interposition +CFLAGS ?= -Werror -Wall -W -Wundef -Wshadow -Wmissing-format-attribute -O2 override CFLAGS += -I. -I../include -D_GNU_SOURCE diff --git a/libsepol/src/assertion.c b/libsepol/src/assertion.c index dd2749a0..1181edc2 100644 --- a/libsepol/src/assertion.c +++ b/libsepol/src/assertion.c @@ -234,7 +234,7 @@ static int report_assertion_avtab_matches(avtab_key_t *k, avtab_datum_t *d, void if (rc) goto oom; - if (ebitmap_is_empty(&src_matches)) + if (ebitmap_length(&src_matches) == 0) goto exit; rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, &p->attr_type_map[k->target_type -1]); @@ -249,14 +249,14 @@ static int report_assertion_avtab_matches(avtab_key_t *k, avtab_datum_t *d, void if (rc) goto oom; - if (!ebitmap_is_empty(&self_matches)) { + if (ebitmap_length(&self_matches) > 0) { rc = ebitmap_union(&tgt_matches, &self_matches); if (rc) goto oom; } } - if (ebitmap_is_empty(&tgt_matches)) + if (ebitmap_length(&tgt_matches) == 0) goto exit; for (cp = avrule->perms; cp; cp = cp->next) { @@ -291,7 +291,7 @@ exit: return rc; } -static int report_assertion_failures(sepol_handle_t *handle, policydb_t *p, avrule_t *avrule) +int report_assertion_failures(sepol_handle_t *handle, policydb_t *p, avrule_t *avrule) { int rc; struct avtab_match_args args; @@ -394,7 +394,7 @@ static int check_assertion_extended_permissions(avrule_t *avrule, avtab_t *avtab if (rc) goto oom; - if (ebitmap_is_empty(&src_matches)) + if (ebitmap_length(&src_matches) == 0) goto exit; rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, @@ -411,14 +411,14 @@ static int check_assertion_extended_permissions(avrule_t *avrule, avtab_t *avtab if (rc) goto oom; - if (!ebitmap_is_empty(&self_matches)) { + if (ebitmap_length(&self_matches) > 0) { rc = ebitmap_union(&tgt_matches, &self_matches); if (rc) goto oom; } } - if (ebitmap_is_empty(&tgt_matches)) + if (ebitmap_length(&tgt_matches) == 0) goto exit; for (cp = avrule->perms; cp; cp = cp->next) { diff --git a/libsepol/src/av_permissions.h b/libsepol/src/av_permissions.h new file mode 100644 index 00000000..97278ed9 --- /dev/null +++ b/libsepol/src/av_permissions.h @@ -0,0 +1,3 @@ +/* Used by security_compute_av. */ +#define PROCESS__TRANSITION 0x00000002UL +#define PROCESS__DYNTRANSITION 0x00800000UL diff --git a/libsepol/src/avrule_block.c b/libsepol/src/avrule_block.c index dcfce8b8..a9832d0d 100644 --- a/libsepol/src/avrule_block.c +++ b/libsepol/src/avrule_block.c @@ -30,7 +30,7 @@ /* It is anticipated that there be less declarations within an avrule * block than the global policy. Thus the symbol table sizes are * smaller than those listed in policydb.c */ -static const unsigned int symtab_sizes[SYM_NUM] = { +static unsigned int symtab_sizes[SYM_NUM] = { 2, 4, 8, diff --git a/libsepol/src/avtab.c b/libsepol/src/avtab.c index 93505b20..257f051a 100644 --- a/libsepol/src/avtab.c +++ b/libsepol/src/avtab.c @@ -52,7 +52,6 @@ /* Based on MurmurHash3, written by Austin Appleby and placed in the * public domain. */ -ignore_unsigned_overflow_ static inline int avtab_hash(struct avtab_key *keyp, uint32_t mask) { static const uint32_t c1 = 0xcc9e2d51; @@ -64,7 +63,7 @@ static inline int avtab_hash(struct avtab_key *keyp, uint32_t mask) uint32_t hash = 0; -#define mix(input) do { \ +#define mix(input) { \ uint32_t v = input; \ v *= c1; \ v = (v << r1) | (v >> (32 - r1)); \ @@ -72,7 +71,7 @@ static inline int avtab_hash(struct avtab_key *keyp, uint32_t mask) hash ^= v; \ hash = (hash << r2) | (hash >> (32 - r2)); \ hash = hash * m + n; \ -} while (0) +} mix(keyp->target_class); mix(keyp->target_type); @@ -419,7 +418,7 @@ void avtab_hash_eval(avtab_t * h, char *tag) } /* Ordering of datums in the original avtab format in the policy file. */ -static const uint16_t spec_order[] = { +static uint16_t spec_order[] = { AVTAB_ALLOWED, AVTAB_AUDITDENY, AVTAB_AUDITALLOW, diff --git a/libsepol/src/boolean_internal.h b/libsepol/src/boolean_internal.h index 1c1e6a39..aad7adec 100644 --- a/libsepol/src/boolean_internal.h +++ b/libsepol/src/boolean_internal.h @@ -3,5 +3,14 @@ #include #include +#include "dso.h" +hidden_proto(sepol_bool_key_create) + hidden_proto(sepol_bool_key_unpack) + hidden_proto(sepol_bool_get_name) + hidden_proto(sepol_bool_set_name) + hidden_proto(sepol_bool_get_value) + hidden_proto(sepol_bool_set_value) + hidden_proto(sepol_bool_create) + hidden_proto(sepol_bool_free) #endif diff --git a/libsepol/src/boolean_record.c b/libsepol/src/boolean_record.c index 6cbf627a..a194704e 100644 --- a/libsepol/src/boolean_record.c +++ b/libsepol/src/boolean_record.c @@ -41,6 +41,7 @@ int sepol_bool_key_create(sepol_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(sepol_bool_key_create) void sepol_bool_key_unpack(const sepol_bool_key_t * key, const char **name) { @@ -48,6 +49,7 @@ void sepol_bool_key_unpack(const sepol_bool_key_t * key, const char **name) *name = key->name; } +hidden_def(sepol_bool_key_unpack) int sepol_bool_key_extract(sepol_handle_t * handle, const sepol_bool_t * boolean, @@ -92,6 +94,7 @@ const char *sepol_bool_get_name(const sepol_bool_t * boolean) return boolean->name; } +hidden_def(sepol_bool_get_name) int sepol_bool_set_name(sepol_handle_t * handle, sepol_bool_t * boolean, const char *name) @@ -107,6 +110,7 @@ int sepol_bool_set_name(sepol_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(sepol_bool_set_name) /* Value */ int sepol_bool_get_value(const sepol_bool_t * boolean) @@ -115,6 +119,7 @@ int sepol_bool_get_value(const sepol_bool_t * boolean) return boolean->value; } +hidden_def(sepol_bool_get_value) void sepol_bool_set_value(sepol_bool_t * boolean, int value) { @@ -122,6 +127,7 @@ void sepol_bool_set_value(sepol_bool_t * boolean, int value) boolean->value = value; } +hidden_def(sepol_bool_set_value) /* Create */ int sepol_bool_create(sepol_handle_t * handle, sepol_bool_t ** bool_ptr) @@ -142,6 +148,7 @@ int sepol_bool_create(sepol_handle_t * handle, sepol_bool_t ** bool_ptr) return STATUS_SUCCESS; } +hidden_def(sepol_bool_create) /* Deep copy clone */ int sepol_bool_clone(sepol_handle_t * handle, @@ -178,3 +185,4 @@ void sepol_bool_free(sepol_bool_t * boolean) free(boolean); } +hidden_def(sepol_bool_free) diff --git a/libsepol/src/booleans.c b/libsepol/src/booleans.c index 716da6b4..30fcf29d 100644 --- a/libsepol/src/booleans.c +++ b/libsepol/src/booleans.c @@ -19,7 +19,6 @@ static int bool_update(sepol_handle_t * handle, const char *cname; char *name; int value; - cond_bool_datum_t *datum; sepol_bool_key_unpack(key, &cname); name = strdup(cname); @@ -28,7 +27,8 @@ static int bool_update(sepol_handle_t * handle, if (!name) goto omem; - datum = hashtab_search(policydb->p_bools.table, name); + cond_bool_datum_t *datum = + hashtab_search(policydb->p_bools.table, name); if (!datum) { ERR(handle, "boolean %s no longer in policy", name); goto err; @@ -84,10 +84,10 @@ int sepol_bool_set(sepol_handle_t * handle, const sepol_bool_key_t * key, const sepol_bool_t * data) { - policydb_t *policydb = &p->p; const char *name; sepol_bool_key_unpack(key, &name); + policydb_t *policydb = &p->p; if (bool_update(handle, policydb, key, data) < 0) goto err; diff --git a/libsepol/src/conditional.c b/libsepol/src/conditional.c index e3ede694..823b649a 100644 --- a/libsepol/src/conditional.c +++ b/libsepol/src/conditional.c @@ -388,6 +388,7 @@ int cond_normalize_expr(policydb_t * p, cond_node_t * cn) for (e = cn->expr; e != NULL; e = e->next) { switch (e->expr_type) { case COND_BOOL: + i = 0; /* see if we've already seen this bool */ if (!bool_present(e->bool, cn->bool_ids, cn->nbools)) { /* count em all but only record up to COND_MAX_BOOLS */ @@ -714,6 +715,7 @@ static int cond_read_av_list(policydb_t * p, void *fp, *ret_list = NULL; + len = 0; rc = next_entry(buf, fp, sizeof(uint32_t)); if (rc < 0) return -1; @@ -767,6 +769,7 @@ static int cond_read_node(policydb_t * p, cond_node_t * node, void *fp) node->cur_state = le32_to_cpu(buf[0]); + len = 0; rc = next_entry(buf, fp, sizeof(uint32_t)); if (rc < 0) goto err; diff --git a/libsepol/src/constraint.c b/libsepol/src/constraint.c index 58eb6da7..71540195 100644 --- a/libsepol/src/constraint.c +++ b/libsepol/src/constraint.c @@ -38,14 +38,10 @@ int constraint_expr_init(constraint_expr_t * expr) void constraint_expr_destroy(constraint_expr_t * expr) { - constraint_expr_t *next; - - while (expr != NULL) { - next = expr->next; + if (expr != NULL) { ebitmap_destroy(&expr->names); type_set_destroy(expr->type_names); free(expr->type_names); free(expr); - expr = next; } } diff --git a/libsepol/src/context_internal.h b/libsepol/src/context_internal.h index 3dc9cd15..7987c1ce 100644 --- a/libsepol/src/context_internal.h +++ b/libsepol/src/context_internal.h @@ -1,7 +1,19 @@ #ifndef _SEPOL_CONTEXT_INTERNAL_H_ #define _SEPOL_CONTEXT_INTERNAL_H_ -#include #include +#include "dso.h" +hidden_proto(sepol_context_clone) + hidden_proto(sepol_context_create) + hidden_proto(sepol_context_free) + hidden_proto(sepol_context_from_string) + hidden_proto(sepol_context_get_mls) + hidden_proto(sepol_context_get_role) + hidden_proto(sepol_context_get_type) + hidden_proto(sepol_context_get_user) + hidden_proto(sepol_context_set_mls) + hidden_proto(sepol_context_set_role) + hidden_proto(sepol_context_set_type) + hidden_proto(sepol_context_set_user) #endif diff --git a/libsepol/src/context_record.c b/libsepol/src/context_record.c index 435f7880..0a8bbf6d 100644 --- a/libsepol/src/context_record.c +++ b/libsepol/src/context_record.c @@ -29,6 +29,7 @@ const char *sepol_context_get_user(const sepol_context_t * con) return con->user; } +hidden_def(sepol_context_get_user) int sepol_context_set_user(sepol_handle_t * handle, sepol_context_t * con, const char *user) @@ -46,6 +47,7 @@ int sepol_context_set_user(sepol_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(sepol_context_set_user) /* Role */ const char *sepol_context_get_role(const sepol_context_t * con) @@ -54,6 +56,7 @@ const char *sepol_context_get_role(const sepol_context_t * con) return con->role; } +hidden_def(sepol_context_get_role) int sepol_context_set_role(sepol_handle_t * handle, sepol_context_t * con, const char *role) @@ -70,6 +73,7 @@ int sepol_context_set_role(sepol_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(sepol_context_set_role) /* Type */ const char *sepol_context_get_type(const sepol_context_t * con) @@ -78,6 +82,7 @@ const char *sepol_context_get_type(const sepol_context_t * con) return con->type; } +hidden_def(sepol_context_get_type) int sepol_context_set_type(sepol_handle_t * handle, sepol_context_t * con, const char *type) @@ -94,6 +99,7 @@ int sepol_context_set_type(sepol_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(sepol_context_set_type) /* MLS */ const char *sepol_context_get_mls(const sepol_context_t * con) @@ -102,6 +108,7 @@ const char *sepol_context_get_mls(const sepol_context_t * con) return con->mls; } +hidden_def(sepol_context_get_mls) int sepol_context_set_mls(sepol_handle_t * handle, sepol_context_t * con, const char *mls) @@ -118,6 +125,7 @@ int sepol_context_set_mls(sepol_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(sepol_context_set_mls) /* Create */ int sepol_context_create(sepol_handle_t * handle, sepol_context_t ** con_ptr) @@ -139,6 +147,7 @@ int sepol_context_create(sepol_handle_t * handle, sepol_context_t ** con_ptr) return STATUS_SUCCESS; } +hidden_def(sepol_context_create) /* Deep copy clone */ int sepol_context_clone(sepol_handle_t * handle, @@ -179,6 +188,7 @@ int sepol_context_clone(sepol_handle_t * handle, return STATUS_ERR; } +hidden_def(sepol_context_clone) /* Destroy */ void sepol_context_free(sepol_context_t * con) @@ -194,6 +204,7 @@ void sepol_context_free(sepol_context_t * con) free(con); } +hidden_def(sepol_context_free) int sepol_context_from_string(sepol_handle_t * handle, const char *str, sepol_context_t ** con) @@ -267,13 +278,32 @@ int sepol_context_from_string(sepol_handle_t * handle, return STATUS_ERR; } +hidden_def(sepol_context_from_string) + +static inline int safe_sum(size_t *sum, const size_t augends[], const size_t cnt) { + + size_t a, i; + + *sum = 0; + for(i=0; i < cnt; i++) { + /* sum should not be smaller than the addend */ + a = augends[i]; + *sum += a; + if (*sum < a) { + return i; + } + } + + return 0; +} + int sepol_context_to_string(sepol_handle_t * handle, const sepol_context_t * con, char **str_ptr) { int rc; char *str = NULL; - size_t total_sz = 0, i; + size_t total_sz, err; const size_t sizes[] = { strlen(con->user), /* user length */ strlen(con->role), /* role length */ @@ -282,11 +312,10 @@ int sepol_context_to_string(sepol_handle_t * handle, ((con->mls) ? 3 : 2) + 1 /* mls has extra ":" also null byte */ }; - for (i = 0; i < ARRAY_SIZE(sizes); i++) { - if (__builtin_add_overflow(total_sz, sizes[i], &total_sz)) { - ERR(handle, "invalid size, overflow at position: %zu", i); - goto err; - } + err = safe_sum(&total_sz, sizes, ARRAY_SIZE(sizes)); + if (err) { + ERR(handle, "invalid size, overflow at position: %zu", err); + goto err; } str = (char *)malloc(total_sz); diff --git a/libsepol/src/debug.c b/libsepol/src/debug.c index f6a59ae7..db57090f 100644 --- a/libsepol/src/debug.c +++ b/libsepol/src/debug.c @@ -23,28 +23,30 @@ int sepol_msg_get_level(sepol_handle_t * handle) return handle->msg_level; } +hidden_def(sepol_msg_get_level) const char *sepol_msg_get_channel(sepol_handle_t * handle) { return handle->msg_channel; } +hidden_def(sepol_msg_get_channel) const char *sepol_msg_get_fname(sepol_handle_t * handle) { return handle->msg_fname; } +hidden_def(sepol_msg_get_fname) #ifdef __GNUC__ __attribute__ ((format(printf, 3, 4))) #endif -void sepol_msg_default_handler(void *varg __attribute__ ((unused)), +void hidden sepol_msg_default_handler(void *varg __attribute__ ((unused)), sepol_handle_t * handle, const char *fmt, ...) { FILE *stream = NULL; - va_list ap; switch (sepol_msg_get_level(handle)) { @@ -61,6 +63,7 @@ void sepol_msg_default_handler(void *varg __attribute__ ((unused)), fprintf(stream, "%s.%s: ", sepol_msg_get_channel(handle), sepol_msg_get_fname(handle)); + va_list ap; va_start(ap, fmt); vfprintf(stream, fmt, ap); va_end(ap); diff --git a/libsepol/src/debug.h b/libsepol/src/debug.h index 0b3965d8..56b397b5 100644 --- a/libsepol/src/debug.h +++ b/libsepol/src/debug.h @@ -21,6 +21,7 @@ #include #include +#include "dso.h" #include "handle.h" #define STATUS_SUCCESS 0 @@ -61,10 +62,13 @@ #ifdef __GNUC__ __attribute__ ((format(printf, 3, 4))) #endif -extern void sepol_msg_default_handler(void *varg, +extern void hidden sepol_msg_default_handler(void *varg, sepol_handle_t * msg, const char *fmt, ...); extern struct sepol_handle sepol_compat_handle; +hidden_proto(sepol_msg_get_channel) + hidden_proto(sepol_msg_get_fname) + hidden_proto(sepol_msg_get_level) #endif diff --git a/libsepol/src/deprecated_funcs.c b/libsepol/src/deprecated_funcs.c new file mode 100644 index 00000000..d0dab7df --- /dev/null +++ b/libsepol/src/deprecated_funcs.c @@ -0,0 +1,50 @@ +#include +#include "debug.h" + +/* + * Need to keep these stubs for the libsepol interfaces exported in + * libsepol.map.in, as they are part of the shared library ABI. + */ + +static const char *msg = "Deprecated interface"; + +/* + * These two functions are deprecated and referenced in: + * include/libsepol/users.h + */ +int sepol_genusers(void *data __attribute((unused)), + size_t len __attribute((unused)), + const char *usersdir __attribute((unused)), + void **newdata __attribute((unused)), + size_t *newlen __attribute((unused))) +{ + WARN(NULL, "%s", msg); + return -1; +} + +void sepol_set_delusers(int on __attribute((unused))) +{ + WARN(NULL, "%s", msg); +} + +/* + * These two functions are deprecated and referenced in: + * include/libsepol/booleans.h + */ +int sepol_genbools(void *data __attribute((unused)), + size_t len __attribute((unused)), + const char *booleans __attribute((unused))) +{ + WARN(NULL, "%s", msg); + return -1; +} + +int sepol_genbools_array(void *data __attribute((unused)), + size_t len __attribute((unused)), + char **names __attribute((unused)), + int *values __attribute((unused)), + int nel __attribute((unused))) +{ + WARN(NULL, "%s", msg); + return -1; +} diff --git a/libsepol/src/dso.h b/libsepol/src/dso.h new file mode 100644 index 00000000..a06e3496 --- /dev/null +++ b/libsepol/src/dso.h @@ -0,0 +1,27 @@ +#ifndef _SEPOL_DSO_H +#define _SEPOL_DSO_H 1 + +#if !defined(SHARED) || defined(ANDROID) + #define DISABLE_SYMVER 1 +#endif + +#ifdef SHARED +# define hidden __attribute__ ((visibility ("hidden"))) +# define hidden_proto(fct) __hidden_proto (fct, fct##_internal) +# define __hidden_proto(fct, internal) \ + extern __typeof (fct) internal; \ + extern __typeof (fct) fct __asm (#internal) hidden; +# if defined(__alpha__) || defined(__mips__) +# define hidden_def(fct) \ + asm (".globl " #fct "\n" #fct " = " #fct "_internal"); +# else +# define hidden_def(fct) \ + asm (".globl " #fct "\n.set " #fct ", " #fct "_internal"); +#endif +#else +# define hidden +# define hidden_proto(fct) +# define hidden_def(fct) +#endif + +#endif diff --git a/libsepol/src/ebitmap.c b/libsepol/src/ebitmap.c index 4e9acdf8..6c9951b7 100644 --- a/libsepol/src/ebitmap.c +++ b/libsepol/src/ebitmap.c @@ -71,7 +71,7 @@ int ebitmap_union(ebitmap_t * dst, const ebitmap_t * e1) return 0; } -int ebitmap_and(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2) +int ebitmap_and(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2) { unsigned int i, length = min(ebitmap_length(e1), ebitmap_length(e2)); ebitmap_init(dst); @@ -85,7 +85,7 @@ int ebitmap_and(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2) return 0; } -int ebitmap_xor(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2) +int ebitmap_xor(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2) { unsigned int i, length = max(ebitmap_length(e1), ebitmap_length(e2)); ebitmap_init(dst); @@ -98,7 +98,7 @@ int ebitmap_xor(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2) return 0; } -int ebitmap_not(ebitmap_t *dst, const ebitmap_t *e1, unsigned int maxbit) +int ebitmap_not(ebitmap_t *dst, ebitmap_t *e1, unsigned int maxbit) { unsigned int i; ebitmap_init(dst); @@ -111,12 +111,11 @@ int ebitmap_not(ebitmap_t *dst, const ebitmap_t *e1, unsigned int maxbit) return 0; } -int ebitmap_andnot(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2, unsigned int maxbit) +int ebitmap_andnot(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2, unsigned int maxbit) { - int rc; ebitmap_t e3; ebitmap_init(dst); - rc = ebitmap_not(&e3, e2, maxbit); + int rc = ebitmap_not(&e3, e2, maxbit); if (rc < 0) return rc; rc = ebitmap_and(dst, e1, &e3); @@ -126,28 +125,24 @@ int ebitmap_andnot(ebitmap_t *dst, const ebitmap_t *e1, const ebitmap_t *e2, uns return 0; } -unsigned int ebitmap_cardinality(const ebitmap_t *e1) +unsigned int ebitmap_cardinality(ebitmap_t *e1) { - unsigned int count = 0; - const ebitmap_node_t *n; - - for (n = e1->node; n; n = n->next) { - count += __builtin_popcountll(n->map); - } + unsigned int i, count = 0; + for (i=ebitmap_startbit(e1); i < ebitmap_length(e1); i++) + if (ebitmap_get_bit(e1, i)) + count++; return count; } -int ebitmap_hamming_distance(const ebitmap_t * e1, const ebitmap_t * e2) +int ebitmap_hamming_distance(ebitmap_t * e1, ebitmap_t * e2) { - int rc; - ebitmap_t tmp; - int distance; if (ebitmap_cmp(e1, e2)) return 0; - rc = ebitmap_xor(&tmp, e1, e2); + ebitmap_t tmp; + int rc = ebitmap_xor(&tmp, e1, e2); if (rc < 0) return -1; - distance = ebitmap_cardinality(&tmp); + int distance = ebitmap_cardinality(&tmp); ebitmap_destroy(&tmp); return distance; } @@ -347,26 +342,6 @@ int ebitmap_set_bit(ebitmap_t * e, unsigned int bit, int value) return 0; } -unsigned int ebitmap_highest_set_bit(const ebitmap_t * e) -{ - const ebitmap_node_t *n; - MAPTYPE map; - unsigned int pos = 0; - - n = e->node; - if (!n) - return 0; - - while (n->next) - n = n->next; - - map = n->map; - while (map >>= 1) - pos++; - - return n->startbit + pos; -} - void ebitmap_destroy(ebitmap_t * e) { ebitmap_node_t *n, *temp; diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c index aac5b35f..5738b598 100644 --- a/libsepol/src/expand.c +++ b/libsepol/src/expand.c @@ -71,38 +71,6 @@ static int map_ebitmap(ebitmap_t * src, ebitmap_t * dst, uint32_t * map) return 0; } -static int ebitmap_expand_roles(policydb_t *p, ebitmap_t *roles) -{ - ebitmap_node_t *node; - unsigned int bit; - role_datum_t *role; - ebitmap_t tmp; - - ebitmap_init(&tmp); - ebitmap_for_each_positive_bit(roles, node, bit) { - role = p->role_val_to_struct[bit]; - assert(role); - if (role->flavor != ROLE_ATTRIB) { - if (ebitmap_set_bit(&tmp, bit, 1)) { - ebitmap_destroy(&tmp); - return -1; - } - } else { - if (ebitmap_union(&tmp, &role->roles)) { - ebitmap_destroy(&tmp); - return -1; - } - } - } - ebitmap_destroy(roles); - if (ebitmap_cpy(roles, &tmp)) { - ebitmap_destroy(&tmp); - return -1; - } - ebitmap_destroy(&tmp); - return 0; -} - static int type_copy_callback(hashtab_key_t key, hashtab_datum_t datum, void *data) { @@ -365,9 +333,6 @@ static int constraint_node_clone(constraint_node_t ** dst, if (map_ebitmap(&expr->names, &new_expr->names, state->rolemap)) { goto out_of_mem; } - if (ebitmap_expand_roles(state->out, &new_expr->names)) { - goto out_of_mem; - } } else if (new_expr->attr & CEXPR_USER) { if (map_ebitmap(&expr->names, &new_expr->names, state->usermap)) { goto out_of_mem; @@ -1406,6 +1371,8 @@ static int copy_role_trans(expand_state_t * state, role_trans_rule_t * rules) static int expand_filename_trans(expand_state_t *state, filename_trans_rule_t *rules) { unsigned int i, j; + filename_trans_t key, *new_trans; + filename_trans_datum_t *otype; filename_trans_rule_t *cur_rule; ebitmap_t stypes, ttypes; ebitmap_node_t *snode, *tnode; @@ -1413,7 +1380,7 @@ static int expand_filename_trans(expand_state_t *state, filename_trans_rule_t *r cur_rule = rules; while (cur_rule) { - uint32_t mapped_otype, present_otype; + uint32_t mapped_otype; ebitmap_init(&stypes); ebitmap_init(&ttypes); @@ -1434,14 +1401,15 @@ static int expand_filename_trans(expand_state_t *state, filename_trans_rule_t *r ebitmap_for_each_positive_bit(&stypes, snode, i) { ebitmap_for_each_positive_bit(&ttypes, tnode, j) { - rc = policydb_filetrans_insert( - state->out, i + 1, j + 1, - cur_rule->tclass, cur_rule->name, - NULL, mapped_otype, &present_otype - ); - if (rc == SEPOL_EEXIST) { + key.stype = i + 1; + key.ttype = j + 1; + key.tclass = cur_rule->tclass; + key.name = cur_rule->name; + otype = hashtab_search(state->out->filename_trans, + (hashtab_key_t) &key); + if (otype) { /* duplicate rule, ignore */ - if (present_otype == mapped_otype) + if (otype->otype == mapped_otype) continue; ERR(state->handle, "Conflicting name-based type_transition %s %s:%s \"%s\": %s vs %s", @@ -1449,13 +1417,46 @@ static int expand_filename_trans(expand_state_t *state, filename_trans_rule_t *r state->out->p_type_val_to_name[j], state->out->p_class_val_to_name[cur_rule->tclass - 1], cur_rule->name, - state->out->p_type_val_to_name[present_otype - 1], + state->out->p_type_val_to_name[otype->otype - 1], state->out->p_type_val_to_name[mapped_otype - 1]); return -1; - } else if (rc < 0) { + } + + new_trans = calloc(1, sizeof(*new_trans)); + if (!new_trans) { ERR(state->handle, "Out of memory!"); return -1; } + + new_trans->name = strdup(cur_rule->name); + if (!new_trans->name) { + ERR(state->handle, "Out of memory!"); + free(new_trans); + return -1; + } + new_trans->stype = i + 1; + new_trans->ttype = j + 1; + new_trans->tclass = cur_rule->tclass; + + otype = calloc(1, sizeof(*otype)); + if (!otype) { + ERR(state->handle, "Out of memory!"); + free(new_trans->name); + free(new_trans); + return -1; + } + otype->otype = mapped_otype; + + rc = hashtab_insert(state->out->filename_trans, + (hashtab_key_t)new_trans, + otype); + if (rc) { + ERR(state->handle, "Out of memory!"); + free(otype); + free(new_trans->name); + free(new_trans); + return -1; + } } } @@ -1605,22 +1606,17 @@ static avtab_ptr_t find_avtab_node(sepol_handle_t * handle, /* AVTAB_XPERMS entries are not necessarily unique */ if (key->specified & AVTAB_XPERMS) { - if (xperms == NULL) { - ERR(handle, "searching xperms NULL"); - node = NULL; - } else { - node = avtab_search_node(avtab, key); - while (node) { - if ((node->datum.xperms->specified == xperms->specified) && - (node->datum.xperms->driver == xperms->driver)) { - match = 1; - break; - } - node = avtab_search_node_next(node, key->specified); + node = avtab_search_node(avtab, key); + while (node) { + if ((node->datum.xperms->specified == xperms->specified) && + (node->datum.xperms->driver == xperms->driver)) { + match = 1; + break; } - if (!match) - node = NULL; + node = avtab_search_node_next(node, key->specified); } + if (!match) + node = NULL; } else { node = avtab_search_node(avtab, key); } @@ -1641,7 +1637,7 @@ static avtab_ptr_t find_avtab_node(sepol_handle_t * handle, * AUDITDENY, aka DONTAUDIT, are &= assigned, versus |= for * others. Initialize the data accordingly. */ - avdatum.data = key->specified == AVTAB_AUDITDENY ? ~UINT32_C(0) : UINT32_C(0); + avdatum.data = key->specified == AVTAB_AUDITDENY ? ~0 : 0; /* this is used to get the node - insertion is actually unique */ node = avtab_insert_nonunique(avtab, key, &avdatum); if (!node) { @@ -2508,7 +2504,7 @@ int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p, unsigned int i; ebitmap_t types, neg_types; ebitmap_node_t *tnode; - unsigned char expand = alwaysexpand || !ebitmap_is_empty(&set->negset) || set->flags; + unsigned char expand = alwaysexpand || ebitmap_length(&set->negset) || set->flags; type_datum_t *type; int rc =-1; @@ -3052,6 +3048,10 @@ int expand_module(sepol_handle_t * handle, if (hashtab_map(state.base->p_roles.table, role_bounds_copy_callback, &state)) goto cleanup; + /* escalate the type_set_t in a role attribute to all regular roles + * that belongs to it. */ + if (hashtab_map(state.base->p_roles.table, role_fix_callback, &state)) + goto cleanup; /* copy MLS's sensitivity level and categories - this needs to be done * before expanding users (they need to be indexed too) */ @@ -3117,11 +3117,6 @@ int expand_module(sepol_handle_t * handle, goto cleanup; } - /* escalate the type_set_t in a role attribute to all regular roles - * that belongs to it. */ - if (hashtab_map(state.base->p_roles.table, role_fix_callback, &state)) - goto cleanup; - if (copy_and_expand_avrule_block(&state) < 0) { ERR(handle, "Error during expand"); goto cleanup; @@ -3374,9 +3369,9 @@ static int expand_cond_insert(cond_av_list_t ** l, return 0; } -static int expand_cond_av_node(policydb_t * p, - avtab_ptr_t node, - cond_av_list_t ** newl, avtab_t * expa) +int expand_cond_av_node(policydb_t * p, + avtab_ptr_t node, + cond_av_list_t ** newl, avtab_t * expa) { avtab_key_t *k = &node->key; avtab_datum_t *d = &node->datum; diff --git a/libsepol/src/flask.h b/libsepol/src/flask.h deleted file mode 100644 index b4130bbc..00000000 --- a/libsepol/src/flask.h +++ /dev/null @@ -1,38 +0,0 @@ -/* This file is automatically generated. Do not edit. */ -#ifndef _SEPOL_POLICYDB_FLASK_H_ -#define _SEPOL_POLICYDB_FLASK_H_ - -/* - * Security identifier indices for initial entities - */ -#define SECINITSID_KERNEL 1 -#define SECINITSID_SECURITY 2 -#define SECINITSID_UNLABELED 3 -#define SECINITSID_FS 4 -#define SECINITSID_FILE 5 -#define SECINITSID_FILE_LABELS 6 -#define SECINITSID_INIT 7 -#define SECINITSID_ANY_SOCKET 8 -#define SECINITSID_PORT 9 -#define SECINITSID_NETIF 10 -#define SECINITSID_NETMSG 11 -#define SECINITSID_NODE 12 -#define SECINITSID_IGMP_PACKET 13 -#define SECINITSID_ICMP_SOCKET 14 -#define SECINITSID_TCP_SOCKET 15 -#define SECINITSID_SYSCTL_MODPROBE 16 -#define SECINITSID_SYSCTL 17 -#define SECINITSID_SYSCTL_FS 18 -#define SECINITSID_SYSCTL_KERNEL 19 -#define SECINITSID_SYSCTL_NET 20 -#define SECINITSID_SYSCTL_NET_UNIX 21 -#define SECINITSID_SYSCTL_VM 22 -#define SECINITSID_SYSCTL_DEV 23 -#define SECINITSID_KMOD 24 -#define SECINITSID_POLICY 25 -#define SECINITSID_SCMP_PACKET 26 -#define SECINITSID_DEVNULL 27 - -#define SECINITSID_NUM 27 - -#endif diff --git a/libsepol/src/hashtab.c b/libsepol/src/hashtab.c index 21143b76..f5407ab6 100644 --- a/libsepol/src/hashtab.c +++ b/libsepol/src/hashtab.c @@ -63,45 +63,6 @@ hashtab_t hashtab_create(unsigned int (*hash_value) (hashtab_t h, return p; } -static void hashtab_check_resize(hashtab_t h) -{ - unsigned int hvalue, i, old_size, new_size = h->size; - hashtab_ptr_t *new_htable, *dst, cur, next; - - while (new_size <= h->nel && new_size * 2 != 0) - new_size *= 2; - - if (h->size == new_size) - return; - - new_htable = calloc(new_size, sizeof(*new_htable)); - if (!new_htable) - return; - - old_size = h->size; - h->size = new_size; - - /* Move all elements to the new htable */ - for (i = 0; i < old_size; i++) { - cur = h->htable[i]; - while (cur != NULL) { - hvalue = h->hash_value(h, cur->key); - dst = &new_htable[hvalue]; - while (*dst && h->keycmp(h, cur->key, (*dst)->key) > 0) - dst = &(*dst)->next; - - next = cur->next; - - cur->next = *dst; - *dst = cur; - - cur = next; - } - } - free(h->htable); - h->htable = new_htable; -} - int hashtab_insert(hashtab_t h, hashtab_key_t key, hashtab_datum_t datum) { int hvalue; @@ -110,8 +71,6 @@ int hashtab_insert(hashtab_t h, hashtab_key_t key, hashtab_datum_t datum) if (!h) return SEPOL_ENOMEM; - hashtab_check_resize(h); - hvalue = h->hash_value(h, key); prev = NULL; cur = h->htable[hvalue]; @@ -174,6 +133,48 @@ int hashtab_remove(hashtab_t h, hashtab_key_t key, return SEPOL_OK; } +int hashtab_replace(hashtab_t h, hashtab_key_t key, hashtab_datum_t datum, + void (*destroy) (hashtab_key_t k, + hashtab_datum_t d, void *args), void *args) +{ + int hvalue; + hashtab_ptr_t prev, cur, newnode; + + if (!h) + return SEPOL_ENOMEM; + + hvalue = h->hash_value(h, key); + prev = NULL; + cur = h->htable[hvalue]; + while (cur != NULL && h->keycmp(h, key, cur->key) > 0) { + prev = cur; + cur = cur->next; + } + + if (cur && (h->keycmp(h, key, cur->key) == 0)) { + if (destroy) + destroy(cur->key, cur->datum, args); + cur->key = key; + cur->datum = datum; + } else { + newnode = (hashtab_ptr_t) malloc(sizeof(hashtab_node_t)); + if (newnode == NULL) + return SEPOL_ENOMEM; + memset(newnode, 0, sizeof(struct hashtab_node)); + newnode->key = key; + newnode->datum = datum; + if (prev) { + newnode->next = prev->next; + prev->next = newnode; + } else { + newnode->next = h->htable[hvalue]; + h->htable[hvalue] = newnode; + } + } + + return SEPOL_OK; +} + hashtab_datum_t hashtab_search(hashtab_t h, const_hashtab_key_t key) { @@ -240,6 +241,49 @@ int hashtab_map(hashtab_t h, return SEPOL_OK; } +void hashtab_map_remove_on_error(hashtab_t h, + int (*apply) (hashtab_key_t k, + hashtab_datum_t d, + void *args), + void (*destroy) (hashtab_key_t k, + hashtab_datum_t d, + void *args), void *args) +{ + unsigned int i; + int ret; + hashtab_ptr_t last, cur, temp; + + if (!h) + return; + + for (i = 0; i < h->size; i++) { + last = NULL; + cur = h->htable[i]; + while (cur != NULL) { + ret = apply(cur->key, cur->datum, args); + if (ret) { + if (last) { + last->next = cur->next; + } else { + h->htable[i] = cur->next; + } + + temp = cur; + cur = cur->next; + if (destroy) + destroy(temp->key, temp->datum, args); + free(temp); + h->nel--; + } else { + last = cur; + cur = cur->next; + } + } + } + + return; +} + void hashtab_hash_eval(hashtab_t h, char *tag) { unsigned int i; diff --git a/libsepol/src/ibendport_internal.h b/libsepol/src/ibendport_internal.h index 8bfb499e..ed8f9b4d 100644 --- a/libsepol/src/ibendport_internal.h +++ b/libsepol/src/ibendport_internal.h @@ -3,5 +3,16 @@ #include #include +#include "dso.h" +hidden_proto(sepol_ibendport_create) +hidden_proto(sepol_ibendport_free) +hidden_proto(sepol_ibendport_get_con) +hidden_proto(sepol_ibendport_get_port) +hidden_proto(sepol_ibendport_key_create) +hidden_proto(sepol_ibendport_key_unpack) +hidden_proto(sepol_ibendport_set_con) +hidden_proto(sepol_ibendport_set_port) +hidden_proto(sepol_ibendport_get_ibdev_name) +hidden_proto(sepol_ibendport_set_ibdev_name) #endif diff --git a/libsepol/src/ibendport_record.c b/libsepol/src/ibendport_record.c index 1eb50914..bc56f090 100644 --- a/libsepol/src/ibendport_record.c +++ b/libsepol/src/ibendport_record.c @@ -62,7 +62,7 @@ int sepol_ibendport_key_create(sepol_handle_t *handle, if (sepol_ibendport_alloc_ibdev_name(handle, &tmp_key->ibdev_name) < 0) goto err; - strncpy(tmp_key->ibdev_name, ibdev_name, IB_DEVICE_NAME_MAX - 1); + strncpy(tmp_key->ibdev_name, ibdev_name, IB_DEVICE_NAME_MAX); tmp_key->port = port; *key_ptr = tmp_key; @@ -78,6 +78,7 @@ err: return STATUS_ERR; } +hidden_def(sepol_ibendport_key_create) void sepol_ibendport_key_unpack(const sepol_ibendport_key_t *key, const char **ibdev_name, int *port) @@ -86,6 +87,7 @@ void sepol_ibendport_key_unpack(const sepol_ibendport_key_t *key, *port = key->port; } +hidden_def(sepol_ibendport_key_unpack) int sepol_ibendport_key_extract(sepol_handle_t *handle, const sepol_ibendport_t *ibendport, @@ -150,12 +152,14 @@ int sepol_ibendport_get_port(const sepol_ibendport_t *ibendport) return ibendport->port; } +hidden_def(sepol_ibendport_get_port) void sepol_ibendport_set_port(sepol_ibendport_t *ibendport, int port) { ibendport->port = port; } +hidden_def(sepol_ibendport_set_port) int sepol_ibendport_get_ibdev_name(sepol_handle_t *handle, const sepol_ibendport_t *ibendport, @@ -166,7 +170,7 @@ int sepol_ibendport_get_ibdev_name(sepol_handle_t *handle, if (sepol_ibendport_alloc_ibdev_name(handle, &tmp_ibdev_name) < 0) goto err; - strncpy(tmp_ibdev_name, ibendport->ibdev_name, IB_DEVICE_NAME_MAX - 1); + strncpy(tmp_ibdev_name, ibendport->ibdev_name, IB_DEVICE_NAME_MAX); *ibdev_name = tmp_ibdev_name; return STATUS_SUCCESS; @@ -176,6 +180,7 @@ err: return STATUS_ERR; } +hidden_def(sepol_ibendport_get_ibdev_name) int sepol_ibendport_set_ibdev_name(sepol_handle_t *handle, sepol_ibendport_t *ibendport, @@ -186,7 +191,7 @@ int sepol_ibendport_set_ibdev_name(sepol_handle_t *handle, if (sepol_ibendport_alloc_ibdev_name(handle, &tmp) < 0) goto err; - strncpy(tmp, ibdev_name, IB_DEVICE_NAME_MAX - 1); + strncpy(tmp, ibdev_name, IB_DEVICE_NAME_MAX); free(ibendport->ibdev_name); ibendport->ibdev_name = tmp; return STATUS_SUCCESS; @@ -197,6 +202,7 @@ err: return STATUS_ERR; } +hidden_def(sepol_ibendport_set_ibdev_name) /* Create */ int sepol_ibendport_create(sepol_handle_t *handle, sepol_ibendport_t **ibendport) @@ -216,6 +222,7 @@ int sepol_ibendport_create(sepol_handle_t *handle, sepol_ibendport_t **ibendport return STATUS_SUCCESS; } +hidden_def(sepol_ibendport_create) /* Deep copy clone */ int sepol_ibendport_clone(sepol_handle_t *handle, @@ -230,7 +237,7 @@ int sepol_ibendport_clone(sepol_handle_t *handle, if (sepol_ibendport_alloc_ibdev_name(handle, &new_ibendport->ibdev_name) < 0) goto omem; - strncpy(new_ibendport->ibdev_name, ibendport->ibdev_name, IB_DEVICE_NAME_MAX - 1); + strncpy(new_ibendport->ibdev_name, ibendport->ibdev_name, IB_DEVICE_NAME_MAX); new_ibendport->port = ibendport->port; if (ibendport->con && @@ -260,6 +267,7 @@ void sepol_ibendport_free(sepol_ibendport_t *ibendport) free(ibendport); } +hidden_def(sepol_ibendport_free) /* Context */ sepol_context_t *sepol_ibendport_get_con(const sepol_ibendport_t *ibendport) @@ -267,6 +275,7 @@ sepol_context_t *sepol_ibendport_get_con(const sepol_ibendport_t *ibendport) return ibendport->con; } +hidden_def(sepol_ibendport_get_con) int sepol_ibendport_set_con(sepol_handle_t *handle, sepol_ibendport_t *ibendport, sepol_context_t *con) @@ -283,3 +292,4 @@ int sepol_ibendport_set_con(sepol_handle_t *handle, return STATUS_SUCCESS; } +hidden_def(sepol_ibendport_set_con) diff --git a/libsepol/src/ibendports.c b/libsepol/src/ibendports.c index ee5cb193..6d56c9a1 100644 --- a/libsepol/src/ibendports.c +++ b/libsepol/src/ibendports.c @@ -34,7 +34,7 @@ static int ibendport_from_record(sepol_handle_t *handle, &ibdev_name) < 0) goto err; - strncpy(tmp_ibendport->u.ibendport.dev_name, ibdev_name, IB_DEVICE_NAME_MAX - 1); + strncpy(tmp_ibendport->u.ibendport.dev_name, ibdev_name, IB_DEVICE_NAME_MAX); free(ibdev_name); ibdev_name = NULL; diff --git a/libsepol/src/ibpkey_internal.h b/libsepol/src/ibpkey_internal.h index b875f942..addf80a8 100644 --- a/libsepol/src/ibpkey_internal.h +++ b/libsepol/src/ibpkey_internal.h @@ -3,5 +3,19 @@ #include #include +#include "dso.h" +hidden_proto(sepol_ibpkey_create) +hidden_proto(sepol_ibpkey_free) +hidden_proto(sepol_ibpkey_get_con) +hidden_proto(sepol_ibpkey_get_high) +hidden_proto(sepol_ibpkey_get_low) +hidden_proto(sepol_ibpkey_key_create) +hidden_proto(sepol_ibpkey_key_unpack) +hidden_proto(sepol_ibpkey_set_con) +hidden_proto(sepol_ibpkey_set_range) +hidden_proto(sepol_ibpkey_get_subnet_prefix) +hidden_proto(sepol_ibpkey_get_subnet_prefix_bytes) +hidden_proto(sepol_ibpkey_set_subnet_prefix) +hidden_proto(sepol_ibpkey_set_subnet_prefix_bytes) #endif diff --git a/libsepol/src/ibpkey_record.c b/libsepol/src/ibpkey_record.c index d95e95fe..badf2b3b 100644 --- a/libsepol/src/ibpkey_record.c +++ b/libsepol/src/ibpkey_record.c @@ -38,8 +38,8 @@ static int ibpkey_parse_subnet_prefix(sepol_handle_t *handle, struct in6_addr in_addr; if (inet_pton(AF_INET6, subnet_prefix_str, &in_addr) <= 0) { - ERR(handle, "could not parse IPv6 address for ibpkey subnet prefix %s: %m", - subnet_prefix_str); + ERR(handle, "could not parse IPv6 address for ibpkey subnet prefix %s: %s", + subnet_prefix_str, strerror(errno)); return STATUS_ERR; } @@ -64,7 +64,8 @@ static int ibpkey_expand_subnet_prefix(sepol_handle_t *handle, if (inet_ntop(AF_INET6, &addr, subnet_prefix_str, INET6_ADDRSTRLEN) == NULL) { ERR(handle, - "could not expand IPv6 address to string: %m"); + "could not expand IPv6 address to string: %s", + strerror(errno)); return STATUS_ERR; } @@ -127,6 +128,7 @@ err: return STATUS_ERR; } +hidden_def(sepol_ibpkey_key_create) void sepol_ibpkey_key_unpack(const sepol_ibpkey_key_t *key, uint64_t *subnet_prefix, int *low, int *high) @@ -136,6 +138,7 @@ void sepol_ibpkey_key_unpack(const sepol_ibpkey_key_t *key, *high = key->high; } +hidden_def(sepol_ibpkey_key_unpack) int sepol_ibpkey_key_extract(sepol_handle_t *handle, const sepol_ibpkey_t *ibpkey, @@ -210,12 +213,14 @@ int sepol_ibpkey_get_low(const sepol_ibpkey_t *ibpkey) return ibpkey->low; } +hidden_def(sepol_ibpkey_get_low) int sepol_ibpkey_get_high(const sepol_ibpkey_t *ibpkey) { return ibpkey->high; } +hidden_def(sepol_ibpkey_get_high) void sepol_ibpkey_set_pkey(sepol_ibpkey_t *ibpkey, int pkey_num) { @@ -229,6 +234,7 @@ void sepol_ibpkey_set_range(sepol_ibpkey_t *ibpkey, int low, int high) ibpkey->high = high; } +hidden_def(sepol_ibpkey_set_range) int sepol_ibpkey_get_subnet_prefix(sepol_handle_t *handle, const sepol_ibpkey_t *ibpkey, @@ -251,6 +257,7 @@ err: return STATUS_ERR; } +hidden_def(sepol_ibpkey_get_subnet_prefix) /* Subnet prefix */ uint64_t sepol_ibpkey_get_subnet_prefix_bytes(const sepol_ibpkey_t *ibpkey) @@ -258,6 +265,7 @@ uint64_t sepol_ibpkey_get_subnet_prefix_bytes(const sepol_ibpkey_t *ibpkey) return ibpkey->subnet_prefix; } +hidden_def(sepol_ibpkey_get_subnet_prefix_bytes) int sepol_ibpkey_set_subnet_prefix(sepol_handle_t *handle, sepol_ibpkey_t *ibpkey, @@ -276,6 +284,7 @@ err: return STATUS_ERR; } +hidden_def(sepol_ibpkey_set_subnet_prefix) void sepol_ibpkey_set_subnet_prefix_bytes(sepol_ibpkey_t *ibpkey, uint64_t subnet_prefix) @@ -283,6 +292,7 @@ void sepol_ibpkey_set_subnet_prefix_bytes(sepol_ibpkey_t *ibpkey, ibpkey->subnet_prefix = subnet_prefix; } +hidden_def(sepol_ibpkey_set_subnet_prefix_bytes) /* Create */ int sepol_ibpkey_create(sepol_handle_t *handle, sepol_ibpkey_t **ibpkey) @@ -303,6 +313,7 @@ int sepol_ibpkey_create(sepol_handle_t *handle, sepol_ibpkey_t **ibpkey) return STATUS_SUCCESS; } +hidden_def(sepol_ibpkey_create) /* Deep copy clone */ int sepol_ibpkey_clone(sepol_handle_t *handle, @@ -340,6 +351,7 @@ void sepol_ibpkey_free(sepol_ibpkey_t *ibpkey) free(ibpkey); } +hidden_def(sepol_ibpkey_free) /* Context */ sepol_context_t *sepol_ibpkey_get_con(const sepol_ibpkey_t *ibpkey) @@ -347,6 +359,7 @@ sepol_context_t *sepol_ibpkey_get_con(const sepol_ibpkey_t *ibpkey) return ibpkey->con; } +hidden_def(sepol_ibpkey_get_con) int sepol_ibpkey_set_con(sepol_handle_t *handle, sepol_ibpkey_t *ibpkey, sepol_context_t *con) @@ -363,3 +376,4 @@ int sepol_ibpkey_set_con(sepol_handle_t *handle, return STATUS_SUCCESS; } +hidden_def(sepol_ibpkey_set_con) diff --git a/libsepol/src/iface_internal.h b/libsepol/src/iface_internal.h index 82fb60cb..5b78d9bd 100644 --- a/libsepol/src/iface_internal.h +++ b/libsepol/src/iface_internal.h @@ -3,5 +3,16 @@ #include #include +#include "dso.h" +hidden_proto(sepol_iface_create) + hidden_proto(sepol_iface_free) + hidden_proto(sepol_iface_get_ifcon) + hidden_proto(sepol_iface_get_msgcon) + hidden_proto(sepol_iface_get_name) + hidden_proto(sepol_iface_key_create) + hidden_proto(sepol_iface_key_unpack) + hidden_proto(sepol_iface_set_ifcon) + hidden_proto(sepol_iface_set_msgcon) + hidden_proto(sepol_iface_set_name) #endif diff --git a/libsepol/src/iface_record.c b/libsepol/src/iface_record.c index e7756989..6d568355 100644 --- a/libsepol/src/iface_record.c +++ b/libsepol/src/iface_record.c @@ -47,6 +47,7 @@ int sepol_iface_key_create(sepol_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(sepol_iface_key_create) void sepol_iface_key_unpack(const sepol_iface_key_t * key, const char **name) { @@ -54,6 +55,7 @@ void sepol_iface_key_unpack(const sepol_iface_key_t * key, const char **name) *name = key->name; } +hidden_def(sepol_iface_key_unpack) int sepol_iface_key_extract(sepol_handle_t * handle, const sepol_iface_t * iface, @@ -112,6 +114,7 @@ int sepol_iface_create(sepol_handle_t * handle, sepol_iface_t ** iface) return STATUS_SUCCESS; } +hidden_def(sepol_iface_create) /* Name */ const char *sepol_iface_get_name(const sepol_iface_t * iface) @@ -120,6 +123,7 @@ const char *sepol_iface_get_name(const sepol_iface_t * iface) return iface->name; } +hidden_def(sepol_iface_get_name) int sepol_iface_set_name(sepol_handle_t * handle, sepol_iface_t * iface, const char *name) @@ -135,6 +139,7 @@ int sepol_iface_set_name(sepol_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(sepol_iface_set_name) /* Interface Context */ sepol_context_t *sepol_iface_get_ifcon(const sepol_iface_t * iface) @@ -143,6 +148,7 @@ sepol_context_t *sepol_iface_get_ifcon(const sepol_iface_t * iface) return iface->netif_con; } +hidden_def(sepol_iface_get_ifcon) int sepol_iface_set_ifcon(sepol_handle_t * handle, sepol_iface_t * iface, sepol_context_t * con) @@ -160,6 +166,7 @@ int sepol_iface_set_ifcon(sepol_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(sepol_iface_set_ifcon) /* Message Context */ sepol_context_t *sepol_iface_get_msgcon(const sepol_iface_t * iface) @@ -168,6 +175,7 @@ sepol_context_t *sepol_iface_get_msgcon(const sepol_iface_t * iface) return iface->netmsg_con; } +hidden_def(sepol_iface_get_msgcon) int sepol_iface_set_msgcon(sepol_handle_t * handle, sepol_iface_t * iface, sepol_context_t * con) @@ -184,6 +192,7 @@ int sepol_iface_set_msgcon(sepol_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(sepol_iface_set_msgcon) /* Deep copy clone */ int sepol_iface_clone(sepol_handle_t * handle, @@ -229,3 +238,4 @@ void sepol_iface_free(sepol_iface_t * iface) free(iface); } +hidden_def(sepol_iface_free) diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c index 305567a5..ca2e4a9b 100644 --- a/libsepol/src/kernel_to_cil.c +++ b/libsepol/src/kernel_to_cil.c @@ -16,9 +16,9 @@ #define IPPROTO_SCTP 132 #endif -#include #include #include +#include #include #include #include @@ -189,13 +189,9 @@ static char *constraint_expr_to_str(struct policydb *pdb, struct constraint_expr names = ebitmap_to_str(&curr->names, pdb->p_role_val_to_name, 1); } if (!names) { - names = strdup("NO_IDENTIFIER"); - } - if (strchr(names, ' ')) { - new_val = create_str("(%s %s (%s))", 3, op, attr1, names); - } else { - new_val = create_str("(%s %s %s)", 3, op, attr1, names); + goto exit; } + new_val = create_str("(%s %s %s)", 3, op, attr1, names); free(names); } } else { @@ -782,20 +778,9 @@ exit: static void write_default_mls_level(FILE *out) { - sepol_printf(out, "(sensitivity s0)\n"); - sepol_printf(out, "(sensitivityorder (s0))\n"); - sepol_printf(out, "(level %s (s0))\n", DEFAULT_LEVEL); -} - -static int map_count_sensitivity_aliases(__attribute__((unused)) char *key, void *data, void *args) -{ - level_datum_t *sens = data; - unsigned *count = args; - - if (sens->isalias) - (*count)++; - - return SEPOL_OK; + sepol_printf(out, "(sensitivity s0)"); + sepol_printf(out, "(sensitivityorder (s0))"); + sepol_printf(out, "(level %s (s0))", DEFAULT_LEVEL); } static int map_sensitivity_aliases_to_strs(char *key, void *data, void *args) @@ -815,13 +800,26 @@ static int write_sensitivity_rules_to_cil(FILE *out, struct policydb *pdb) { level_datum_t *level; char *prev, *name, *actual; - struct strs *strs = NULL; - unsigned i, num = 0; + struct strs *strs; + unsigned i, num; int rc = 0; + rc = strs_init(&strs, pdb->p_levels.nprim); + if (rc != 0) { + goto exit; + } + /* sensitivities */ for (i=0; i < pdb->p_levels.nprim; i++) { name = pdb->p_sens_val_to_name[i]; + if (!name) continue; + level = hashtab_search(pdb->p_levels.table, name); + if (!level) { + rc = -1; + goto exit; + } + if (level->isalias) continue; + sepol_printf(out, "(sensitivity %s)\n", name); } @@ -830,6 +828,14 @@ static int write_sensitivity_rules_to_cil(FILE *out, struct policydb *pdb) prev = NULL; for (i=0; i < pdb->p_levels.nprim; i++) { name = pdb->p_sens_val_to_name[i]; + if (!name) continue; + level = hashtab_search(pdb->p_levels.table, name); + if (!level) { + rc = -1; + goto exit; + } + if (level->isalias) continue; + if (prev) { sepol_printf(out, "%s ", prev); } @@ -840,22 +846,6 @@ static int write_sensitivity_rules_to_cil(FILE *out, struct policydb *pdb) } sepol_printf(out, "))\n"); - rc = hashtab_map(pdb->p_levels.table, map_count_sensitivity_aliases, &num); - if (rc != 0) { - goto exit; - } - - if (num == 0) { - /* No aliases, so skip sensitivity alias rules */ - rc = 0; - goto exit; - } - - rc = strs_init(&strs, num); - if (rc != 0) { - goto exit; - } - rc = hashtab_map(pdb->p_levels.table, map_sensitivity_aliases_to_strs, strs); if (rc != 0) { goto exit; @@ -863,9 +853,16 @@ static int write_sensitivity_rules_to_cil(FILE *out, struct policydb *pdb) strs_sort(strs); + num = strs_num_items(strs); + /* sensitivity aliases */ for (i=0; i < num; i++) { name = strs_read_at_index(strs, i); + level = hashtab_search(pdb->p_levels.table, name); + if (!level) { + rc = -1; + goto exit; + } sepol_printf(out, "(sensitivityalias %s)\n", name); } @@ -891,17 +888,6 @@ exit: return rc; } -static int map_count_category_aliases(__attribute__((unused)) char *key, void *data, void *args) -{ - cat_datum_t *cat = data; - unsigned *count = args; - - if (cat->isalias) - (*count)++; - - return SEPOL_OK; -} - static int map_category_aliases_to_strs(char *key, void *data, void *args) { cat_datum_t *cat = data; @@ -919,13 +905,26 @@ static int write_category_rules_to_cil(FILE *out, struct policydb *pdb) { cat_datum_t *cat; char *prev, *name, *actual; - struct strs *strs = NULL; - unsigned i, num = 0; + struct strs *strs; + unsigned i, num; int rc = 0; + rc = strs_init(&strs, pdb->p_levels.nprim); + if (rc != 0) { + goto exit; + } + /* categories */ for (i=0; i < pdb->p_cats.nprim; i++) { name = pdb->p_cat_val_to_name[i]; + if (!name) continue; + cat = hashtab_search(pdb->p_cats.table, name); + if (!cat) { + rc = -1; + goto exit; + } + if (cat->isalias) continue; + sepol_printf(out, "(category %s)\n", name); } @@ -934,6 +933,14 @@ static int write_category_rules_to_cil(FILE *out, struct policydb *pdb) prev = NULL; for (i=0; i < pdb->p_cats.nprim; i++) { name = pdb->p_cat_val_to_name[i]; + if (!name) continue; + cat = hashtab_search(pdb->p_cats.table, name); + if (!cat) { + rc = -1; + goto exit; + } + if (cat->isalias) continue; + if (prev) { sepol_printf(out, "%s ", prev); } @@ -944,22 +951,6 @@ static int write_category_rules_to_cil(FILE *out, struct policydb *pdb) } sepol_printf(out, "))\n"); - rc = hashtab_map(pdb->p_cats.table, map_count_category_aliases, &num); - if (rc != 0) { - goto exit; - } - - if (num == 0) { - /* No aliases, so skip category alias rules */ - rc = 0; - goto exit; - } - - rc = strs_init(&strs, num); - if (rc != 0) { - goto exit; - } - rc = hashtab_map(pdb->p_cats.table, map_category_aliases_to_strs, strs); if (rc != 0) { goto exit; @@ -967,9 +958,16 @@ static int write_category_rules_to_cil(FILE *out, struct policydb *pdb) strs_sort(strs); + num = strs_num_items(strs); + /* category aliases */ for (i=0; i < num; i++) { name = strs_read_at_index(strs, i); + cat = hashtab_search(pdb->p_cats.table, name); + if (!cat) { + rc = -1; + goto exit; + } sepol_printf(out, "(categoryalias %s)\n", name); } @@ -1034,14 +1032,11 @@ static char *cats_ebitmap_to_str(struct ebitmap *cats, char **val_to_name) { struct ebitmap_node *node; uint32_t i, start, range; - char *catsbuf = NULL, *p; + char *catsbuf, *p; const char *fmt; int len, remaining; remaining = (int)cats_ebitmap_len(cats, val_to_name); - if (remaining == 0) { - goto exit; - } catsbuf = malloc(remaining); if (!catsbuf) { goto exit; @@ -1050,7 +1045,7 @@ static char *cats_ebitmap_to_str(struct ebitmap *cats, char **val_to_name) p = catsbuf; *p++ = '('; - remaining--; + remaining--;; range = 0; ebitmap_for_each_positive_bit(cats, node, i) { @@ -1106,7 +1101,7 @@ static int write_sensitivitycategory_rules_to_cil(FILE *out, struct policydb *pd } if (level->isalias) continue; - if (!ebitmap_is_empty(&level->level->cat)) { + if (ebitmap_cardinality(&level->level->cat) > 0) { cats = cats_ebitmap_to_str(&level->level->cat, pdb->p_cat_val_to_name); sepol_printf(out, "(sensitivitycategory %s %s)\n", name, cats); free(cats); @@ -1373,55 +1368,33 @@ exit: return rc; } -static int map_count_type_aliases(__attribute__((unused)) char *key, void *data, void *args) -{ - type_datum_t *datum = data; - unsigned *count = args; - - if (datum->primary == 0 && datum->flavor == TYPE_TYPE) - (*count)++; - - return SEPOL_OK; -} - -static int map_type_aliases_to_strs(char *key, void *data, void *args) -{ - type_datum_t *datum = data; - struct strs *strs = args; - int rc = 0; - - if (datum->primary == 0 && datum->flavor == TYPE_TYPE) - rc = strs_add(strs, key); - - return rc; -} - static int write_type_alias_rules_to_cil(FILE *out, struct policydb *pdb) { type_datum_t *alias; struct strs *strs; char *name; char *type; - unsigned i, num = 0; + unsigned i, num; int rc = 0; - rc = hashtab_map(pdb->p_types.table, map_count_type_aliases, &num); + rc = strs_init(&strs, pdb->p_types.nprim); if (rc != 0) { goto exit; } - rc = strs_init(&strs, num); - if (rc != 0) { - goto exit; - } - - rc = hashtab_map(pdb->p_types.table, map_type_aliases_to_strs, strs); - if (rc != 0) { - goto exit; + for (i=0; i < pdb->p_types.nprim; i++) { + alias = pdb->type_val_to_struct[i]; + if (!alias->primary) { + rc = strs_add(strs, pdb->p_type_val_to_name[i]); + if (rc != 0) { + goto exit; + } + } } strs_sort(strs); + num = strs_num_items(strs); for (i=0; iflavor != TYPE_ATTRIB) continue; name = pdb->p_type_val_to_name[i]; typemap = &pdb->attr_type_map[i]; - if (ebitmap_is_empty(typemap)) continue; + if (ebitmap_cardinality(typemap) == 0) continue; types = ebitmap_to_str(typemap, pdb->p_type_val_to_name, 1); if (!types) { rc = -1; @@ -1849,35 +1822,21 @@ struct map_filename_trans_args { static int map_filename_trans_to_str(hashtab_key_t key, void *data, void *arg) { - filename_trans_key_t *ft = (filename_trans_key_t *)key; + filename_trans_t *ft = (filename_trans_t *)key; filename_trans_datum_t *datum = data; struct map_filename_trans_args *map_args = arg; struct policydb *pdb = map_args->pdb; struct strs *strs = map_args->strs; char *src, *tgt, *class, *filename, *new; - struct ebitmap_node *node; - uint32_t bit; - int rc; + src = pdb->p_type_val_to_name[ft->stype - 1]; tgt = pdb->p_type_val_to_name[ft->ttype - 1]; class = pdb->p_class_val_to_name[ft->tclass - 1]; filename = ft->name; - do { - new = pdb->p_type_val_to_name[datum->otype - 1]; + new = pdb->p_type_val_to_name[datum->otype - 1]; - ebitmap_for_each_positive_bit(&datum->stypes, node, bit) { - src = pdb->p_type_val_to_name[bit]; - rc = strs_create_and_add(strs, - "(typetransition %s %s %s %s %s)", - 5, src, tgt, class, filename, new); - if (rc) - return rc; - } - - datum = datum->next; - } while (datum); - - return 0; + return strs_create_and_add(strs, "(typetransition %s %s %s %s %s)", 5, + src, tgt, class, filename, new); } static int write_filename_trans_rules_to_cil(FILE *out, struct policydb *pdb) @@ -1920,7 +1879,7 @@ static char *level_to_str(struct policydb *pdb, struct mls_level *level) char *sens_str = pdb->p_sens_val_to_name[level->sens - 1]; char *cats_str; - if (!ebitmap_is_empty(cats)) { + if (ebitmap_cardinality(cats) > 0) { cats_str = cats_ebitmap_to_str(cats, pdb->p_cat_val_to_name); level_str = create_str("(%s %s)", 2, sens_str, cats_str); free(cats_str); @@ -2229,7 +2188,7 @@ static int write_role_decl_rules_to_cil(FILE *out, struct policydb *pdb) goto exit; } types = &role->types.types; - if (types && !ebitmap_is_empty(types)) { + if (types && (ebitmap_cardinality(types) > 0)) { rc = strs_init(&type_strs, pdb->p_types.nprim); if (rc != 0) { goto exit; @@ -2414,7 +2373,7 @@ static int write_user_decl_rules_to_cil(FILE *out, struct policydb *pdb) } roles = &user->roles.roles; - if (roles && !ebitmap_is_empty(roles)) { + if (roles && (ebitmap_cardinality(roles) > 0)) { rc = strs_init(&role_strs, pdb->p_roles.nprim); if (rc != 0) { goto exit; @@ -2497,10 +2456,9 @@ static int write_user_decl_rules_to_cil(FILE *out, struct policydb *pdb) sepol_printf(out, ")\n"); } -exit: - if (strs) - strs_destroy(&strs); + strs_destroy(&strs); +exit: if (rc != 0) { sepol_log_err("Error writing user declarations to CIL\n"); } @@ -2658,7 +2616,7 @@ static int write_genfscon_rules_to_cil(FILE *out, struct policydb *pdb) goto exit; } - rc = strs_create_and_add(strs, "(genfscon %s \"%s\" %s)", 3, + rc = strs_create_and_add(strs, "(genfscon %s %s %s)", 3, fstype, name, ctx); free(ctx); if (rc != 0) { @@ -2780,13 +2738,13 @@ static int write_selinux_node_rules_to_cil(FILE *out, struct policydb *pdb) for (node = pdb->ocontexts[4]; node != NULL; node = node->next) { if (inet_ntop(AF_INET, &node->u.node.addr, addr, INET_ADDRSTRLEN) == NULL) { - sepol_log_err("Nodecon address is invalid: %m"); + sepol_log_err("Nodecon address is invalid: %s", strerror(errno)); rc = -1; goto exit; } if (inet_ntop(AF_INET, &node->u.node.mask, mask, INET_ADDRSTRLEN) == NULL) { - sepol_log_err("Nodecon mask is invalid: %m"); + sepol_log_err("Nodecon mask is invalid: %s", strerror(errno)); rc = -1; goto exit; } @@ -2820,13 +2778,13 @@ static int write_selinux_node6_rules_to_cil(FILE *out, struct policydb *pdb) for (node = pdb->ocontexts[6]; node != NULL; node = node->next) { if (inet_ntop(AF_INET6, &node->u.node6.addr, addr, INET6_ADDRSTRLEN) == NULL) { - sepol_log_err("Nodecon address is invalid: %m"); + sepol_log_err("Nodecon address is invalid: %s", strerror(errno)); rc = -1; goto exit; } if (inet_ntop(AF_INET6, &node->u.node6.mask, mask, INET6_ADDRSTRLEN) == NULL) { - sepol_log_err("Nodecon mask is invalid: %m"); + sepol_log_err("Nodecon mask is invalid: %s", strerror(errno)); rc = -1; goto exit; } @@ -2868,7 +2826,8 @@ static int write_selinux_ibpkey_rules_to_cil(FILE *out, struct policydb *pdb) if (inet_ntop(AF_INET6, &subnet_prefix.s6_addr, subnet_prefix_str, INET6_ADDRSTRLEN) == NULL) { - sepol_log_err("ibpkeycon subnet_prefix is invalid: %m"); + sepol_log_err("ibpkeycon subnet_prefix is invalid: %s", + strerror(errno)); rc = -1; goto exit; } @@ -3118,7 +3077,7 @@ static int write_xen_devicetree_rules_to_cil(FILE *out, struct policydb *pdb) goto exit; } - sepol_printf(out, "(devicetreecon \"%s\" %s)\n", name, ctx); + sepol_printf(out, "(devicetreecon %s %s)\n", name, ctx); free(ctx); } @@ -3171,18 +3130,6 @@ int sepol_kernel_policydb_to_cil(FILE *out, struct policydb *pdb) goto exit; } - if (pdb->policyvers >= POLICYDB_VERSION_AVTAB && pdb->policyvers <= POLICYDB_VERSION_PERMISSIVE) { - /* - * For policy versions between 20 and 23, attributes exist in the policy, - * but only in the type_attr_map. This means that there are gaps in both - * the type_val_to_struct and p_type_val_to_name arrays and policy rules - * can refer to those gaps. - */ - sepol_log_err("Writing policy versions between 20 and 23 as CIL is not supported"); - rc = -1; - goto exit; - } - rc = constraint_rules_to_strs(pdb, mls_constraints, non_mls_constraints); if (rc != 0) { goto exit; diff --git a/libsepol/src/kernel_to_common.c b/libsepol/src/kernel_to_common.c index a7453d3c..7b53c92f 100644 --- a/libsepol/src/kernel_to_common.c +++ b/libsepol/src/kernel_to_common.c @@ -470,9 +470,11 @@ static int portcon_data_cmp(const void *a, const void *b) rc = compare_ranges((*aa)->u.port.low_port, (*aa)->u.port.high_port, (*bb)->u.port.low_port, (*bb)->u.port.high_port); if (rc == 0) { - if ((*aa)->u.port.protocol < (*bb)->u.port.protocol) { + if ((*aa)->u.port.protocol == (*bb)->u.port.protocol) { + rc = 0; + } else if ((*aa)->u.port.protocol == IPPROTO_TCP) { rc = -1; - } else if ((*aa)->u.port.protocol > (*bb)->u.port.protocol) { + } else { rc = 1; } } diff --git a/libsepol/src/kernel_to_conf.c b/libsepol/src/kernel_to_conf.c index eb72e4ac..b4966162 100644 --- a/libsepol/src/kernel_to_conf.c +++ b/libsepol/src/kernel_to_conf.c @@ -15,9 +15,9 @@ #define IPPROTO_SCTP 132 #endif -#include #include #include +#include #include #include #include @@ -186,13 +186,9 @@ static char *constraint_expr_to_str(struct policydb *pdb, struct constraint_expr names = ebitmap_to_str(&curr->names, pdb->p_role_val_to_name, 1); } if (!names) { - names = strdup("NO_IDENTIFIER"); - } - if (strchr(names, ' ')) { - new_val = create_str("%s %s { %s }", 3, attr1, op, names); - } else { - new_val = create_str("%s %s %s", 3, attr1, op, names); + goto exit; } + new_val = create_str("%s %s %s", 3, attr1, op, names); free(names); } } else { @@ -1025,15 +1021,12 @@ static char *cats_ebitmap_to_str(struct ebitmap *cats, char **val_to_name) { struct ebitmap_node *node; uint32_t i, start, range, first; - char *catsbuf = NULL, *p; + char *catsbuf, *p; const char *fmt; char sep; int len, remaining; remaining = (int)cats_ebitmap_len(cats, val_to_name); - if (remaining == 0) { - goto exit; - } catsbuf = malloc(remaining); if (!catsbuf) { goto exit; @@ -1097,7 +1090,7 @@ static int write_level_rules_to_conf(FILE *out, struct policydb *pdb) } if (level->isalias) continue; - if (!ebitmap_is_empty(&level->level->cat)) { + if (ebitmap_cardinality(&level->level->cat) > 0) { cats = cats_ebitmap_to_str(&level->level->cat, pdb->p_cat_val_to_name); sepol_printf(out, "level %s:%s;\n", name, cats); free(cats); @@ -1361,55 +1354,34 @@ exit: return rc; } -static int map_count_type_aliases(__attribute__((unused)) char *key, void *data, void *args) -{ - type_datum_t *datum = data; - unsigned *count = args; - - if (datum->primary == 0 && datum->flavor == TYPE_TYPE) - (*count)++; - - return SEPOL_OK; -} - -static int map_type_aliases_to_strs(char *key, void *data, void *args) -{ - type_datum_t *datum = data; - struct strs *strs = args; - int rc = 0; - - if (datum->primary == 0 && datum->flavor == TYPE_TYPE) - rc = strs_add(strs, key); - - return rc; -} - static int write_type_alias_rules_to_conf(FILE *out, struct policydb *pdb) { type_datum_t *alias; struct strs *strs; char *name; char *type; - unsigned i, num = 0; + unsigned i, num; int rc = 0; - rc = hashtab_map(pdb->p_types.table, map_count_type_aliases, &num); + rc = strs_init(&strs, pdb->p_types.nprim); if (rc != 0) { goto exit; } - rc = strs_init(&strs, num); - if (rc != 0) { - goto exit; - } - - rc = hashtab_map(pdb->p_types.table, map_type_aliases_to_strs, strs); - if (rc != 0) { - goto exit; + for (i=0; i < pdb->p_types.nprim; i++) { + alias = pdb->type_val_to_struct[i]; + if (!alias->primary) { + rc = strs_add(strs, pdb->p_type_val_to_name[i]); + if (rc != 0) { + goto exit; + } + } } strs_sort(strs); + num = strs_num_items(strs); + for (i=0; ip_type_val_to_name[alias->s.value - 1]; - sepol_printf(out, "typealias %s alias %s;\n", type, name); + sepol_printf(out, "typealias %s %s;\n", type, name); } exit: @@ -1830,35 +1802,21 @@ struct map_filename_trans_args { static int map_filename_trans_to_str(hashtab_key_t key, void *data, void *arg) { - filename_trans_key_t *ft = (filename_trans_key_t *)key; + filename_trans_t *ft = (filename_trans_t *)key; filename_trans_datum_t *datum = data; struct map_filename_trans_args *map_args = arg; struct policydb *pdb = map_args->pdb; struct strs *strs = map_args->strs; char *src, *tgt, *class, *filename, *new; - struct ebitmap_node *node; - uint32_t bit; - int rc; + src = pdb->p_type_val_to_name[ft->stype - 1]; tgt = pdb->p_type_val_to_name[ft->ttype - 1]; class = pdb->p_class_val_to_name[ft->tclass - 1]; filename = ft->name; - do { - new = pdb->p_type_val_to_name[datum->otype - 1]; + new = pdb->p_type_val_to_name[datum->otype - 1]; - ebitmap_for_each_positive_bit(&datum->stypes, node, bit) { - src = pdb->p_type_val_to_name[bit]; - rc = strs_create_and_add(strs, - "type_transition %s %s:%s %s \"%s\";", - 5, src, tgt, class, new, filename); - if (rc) - return rc; - } - - datum = datum->next; - } while (datum); - - return 0; + return strs_create_and_add(strs, "type_transition %s %s:%s %s \"%s\";", 5, + src, tgt, class, new, filename); } static int write_filename_trans_rules_to_conf(FILE *out, struct policydb *pdb) @@ -1901,7 +1859,7 @@ static char *level_to_str(struct policydb *pdb, struct mls_level *level) char *sens_str = pdb->p_sens_val_to_name[level->sens - 1]; char *cats_str; - if (!ebitmap_is_empty(cats)) { + if (ebitmap_cardinality(cats) > 0) { cats_str = cats_ebitmap_to_str(cats, pdb->p_cat_val_to_name); level_str = create_str("%s:%s", 2, sens_str, cats_str); free(cats_str); @@ -2187,7 +2145,7 @@ static int write_role_decl_rules_to_conf(FILE *out, struct policydb *pdb) rc = -1; goto exit; } - if (ebitmap_is_empty(&role->types.types)) continue; + if (ebitmap_cardinality(&role->types.types) == 0) continue; types = ebitmap_to_str(&role->types.types, pdb->p_type_val_to_name, 1); if (!types) { rc = -1; @@ -2340,7 +2298,7 @@ static int write_user_decl_rules_to_conf(FILE *out, struct policydb *pdb) } sepol_printf(out, "user %s", name); - if (!ebitmap_is_empty(&user->roles.roles)) { + if (ebitmap_cardinality(&user->roles.roles) > 0) { roles = ebitmap_to_str(&user->roles.roles, pdb->p_role_val_to_name, 1); if (!roles) { @@ -2375,10 +2333,9 @@ static int write_user_decl_rules_to_conf(FILE *out, struct policydb *pdb) sepol_printf(out, ";\n"); } -exit: - if (strs) - strs_destroy(&strs); + strs_destroy(&strs); +exit: if (rc != 0) { sepol_log_err("Error writing user declarations to policy.conf\n"); } @@ -2531,7 +2488,7 @@ static int write_genfscon_rules_to_conf(FILE *out, struct policydb *pdb) goto exit; } - rc = strs_create_and_add(strs, "genfscon %s \"%s\" %s", 3, + rc = strs_create_and_add(strs, "genfscon %s %s %s", 3, fstype, name, ctx); free(ctx); if (rc != 0) { @@ -2653,13 +2610,13 @@ static int write_selinux_node_rules_to_conf(FILE *out, struct policydb *pdb) for (node = pdb->ocontexts[4]; node != NULL; node = node->next) { if (inet_ntop(AF_INET, &node->u.node.addr, addr, INET_ADDRSTRLEN) == NULL) { - sepol_log_err("Nodecon address is invalid: %m"); + sepol_log_err("Nodecon address is invalid: %s", strerror(errno)); rc = -1; goto exit; } if (inet_ntop(AF_INET, &node->u.node.mask, mask, INET_ADDRSTRLEN) == NULL) { - sepol_log_err("Nodecon mask is invalid: %m"); + sepol_log_err("Nodecon mask is invalid: %s", strerror(errno)); rc = -1; goto exit; } @@ -2694,13 +2651,13 @@ static int write_selinux_node6_rules_to_conf(FILE *out, struct policydb *pdb) for (node6 = pdb->ocontexts[6]; node6 != NULL; node6 = node6->next) { if (inet_ntop(AF_INET6, &node6->u.node6.addr, addr, INET6_ADDRSTRLEN) == NULL) { - sepol_log_err("Nodecon address is invalid: %m"); + sepol_log_err("Nodecon address is invalid: %s", strerror(errno)); rc = -1; goto exit; } if (inet_ntop(AF_INET6, &node6->u.node6.mask, mask, INET6_ADDRSTRLEN) == NULL) { - sepol_log_err("Nodecon mask is invalid: %m"); + sepol_log_err("Nodecon mask is invalid: %s", strerror(errno)); rc = -1; goto exit; } @@ -2742,7 +2699,8 @@ static int write_selinux_ibpkey_rules_to_conf(FILE *out, struct policydb *pdb) if (inet_ntop(AF_INET6, &subnet_prefix.s6_addr, subnet_prefix_str, INET6_ADDRSTRLEN) == NULL) { - sepol_log_err("ibpkeycon address is invalid: %m"); + sepol_log_err("ibpkeycon address is invalid: %s", + strerror(errno)); rc = -1; goto exit; } @@ -2995,7 +2953,7 @@ static int write_xen_devicetree_rules_to_conf(FILE *out, struct policydb *pdb) goto exit; } - sepol_printf(out, "devicetreecon \"%s\" %s\n", name, ctx); + sepol_printf(out, "devicetreecon %s %s\n", name, ctx); free(ctx); } @@ -3048,18 +3006,6 @@ int sepol_kernel_policydb_to_conf(FILE *out, struct policydb *pdb) goto exit; } - if (pdb->policyvers >= POLICYDB_VERSION_AVTAB && pdb->policyvers <= POLICYDB_VERSION_PERMISSIVE) { - /* - * For policy versions between 20 and 23, attributes exist in the policy, - * but only in the type_attr_map. This means that there are gaps in both - * the type_val_to_struct and p_type_val_to_name arrays and policy rules - * can refer to those gaps. - */ - sepol_log_err("Writing policy versions between 20 and 23 as a policy.conf is not supported"); - rc = -1; - goto exit; - } - rc = constraint_rules_to_strs(pdb, mls_constraints, non_mls_constraints); if (rc != 0) { goto exit; diff --git a/libsepol/src/libsepol.map.in b/libsepol/src/libsepol.map.in index 0e05d606..f4946a79 100644 --- a/libsepol/src/libsepol.map.in +++ b/libsepol/src/libsepol.map.in @@ -1,245 +1,39 @@ LIBSEPOL_1.0 { - global: - cil_add_file; - cil_db_destroy; + global: + expand_module_avrules; + sepol_module_package_*; sepol_link_modules; sepol_expand_module; sepol_link_packages; + sepol_bool_*; sepol_genbools*; + sepol_context_*; sepol_mls_*; sepol_check_context; + sepol_iface_*; + sepol_port_*; + sepol_ibpkey_*; + sepol_ibendport_*; + sepol_node_*; + sepol_user_*; sepol_genusers; sepol_set_delusers; + sepol_msg_*; sepol_debug; + sepol_handle_*; + sepol_policydb_*; sepol_set_policydb_from_file; + sepol_policy_kern_*; + sepol_policy_file_*; + sepol_get_disable_dontaudit; + sepol_set_disable_dontaudit; + sepol_set_expand_consume_base; + sepol_get_preserve_tunables; sepol_set_preserve_tunables; cil_db_init; cil_set_disable_dontaudit; cil_set_disable_neverallow; - cil_set_handle_unknown; - cil_set_log_handler; - cil_set_log_level; cil_set_preserve_tunables; - expand_module_avrules; - sepol_bool_clone; - sepol_bool_compare; - sepol_bool_compare2; - sepol_bool_count; - sepol_bool_create; - sepol_bool_exists; - sepol_bool_free; - sepol_bool_get_name; - sepol_bool_get_value; - sepol_bool_iterate; - sepol_bool_key_create; - sepol_bool_key_extract; - sepol_bool_key_free; - sepol_bool_key_unpack; - sepol_bool_query; - sepol_bool_set; - sepol_bool_set_name; - sepol_bool_set_value; - sepol_check_context; - sepol_context_check; - sepol_context_clone; - sepol_context_create; - sepol_context_free; - sepol_context_from_string; - sepol_context_get_mls; - sepol_context_get_role; - sepol_context_get_type; - sepol_context_get_user; - sepol_context_set_mls; - sepol_context_set_role; - sepol_context_set_type; - sepol_context_set_user; - sepol_context_to_string; - sepol_debug; - sepol_expand_module; - sepol_get_disable_dontaudit; - sepol_get_preserve_tunables; - sepol_handle_create; - sepol_handle_destroy; - sepol_ibendport_alloc_ibdev_name; - sepol_ibendport_clone; - sepol_ibendport_compare; - sepol_ibendport_compare2; - sepol_ibendport_count; - sepol_ibendport_create; - sepol_ibendport_exists; - sepol_ibendport_free; - sepol_ibendport_get_con; - sepol_ibendport_get_ibdev_name; - sepol_ibendport_get_port; - sepol_ibendport_iterate; - sepol_ibendport_key_create; - sepol_ibendport_key_extract; - sepol_ibendport_key_free; - sepol_ibendport_key_unpack; - sepol_ibendport_modify; - sepol_ibendport_query; - sepol_ibendport_set_con; - sepol_ibendport_set_ibdev_name; - sepol_ibendport_set_port; - sepol_ibpkey_clone; - sepol_ibpkey_compare; - sepol_ibpkey_compare2; - sepol_ibpkey_count; - sepol_ibpkey_create; - sepol_ibpkey_exists; - sepol_ibpkey_free; - sepol_ibpkey_get_con; - sepol_ibpkey_get_high; - sepol_ibpkey_get_low; - sepol_ibpkey_get_subnet_prefix; - sepol_ibpkey_get_subnet_prefix_bytes; - sepol_ibpkey_iterate; - sepol_ibpkey_key_create; - sepol_ibpkey_key_extract; - sepol_ibpkey_key_free; - sepol_ibpkey_key_unpack; - sepol_ibpkey_modify; - sepol_ibpkey_query; - sepol_ibpkey_set_con; - sepol_ibpkey_set_pkey; - sepol_ibpkey_set_range; - sepol_ibpkey_set_subnet_prefix; - sepol_ibpkey_set_subnet_prefix_bytes; - sepol_iface_clone; - sepol_iface_compare; - sepol_iface_compare2; - sepol_iface_count; - sepol_iface_create; - sepol_iface_exists; - sepol_iface_free; - sepol_iface_get_ifcon; - sepol_iface_get_msgcon; - sepol_iface_get_name; - sepol_iface_iterate; - sepol_iface_key_create; - sepol_iface_key_extract; - sepol_iface_key_free; - sepol_iface_key_unpack; - sepol_iface_modify; - sepol_iface_query; - sepol_iface_set_ifcon; - sepol_iface_set_msgcon; - sepol_iface_set_name; - sepol_link_modules; - sepol_link_packages; - sepol_mls_check; - sepol_mls_contains; - sepol_module_package_create; - sepol_module_package_free; - sepol_module_package_get_file_contexts; - sepol_module_package_get_file_contexts_len; - sepol_module_package_get_netfilter_contexts; - sepol_module_package_get_netfilter_contexts_len; - sepol_module_package_get_policy; - sepol_module_package_get_seusers; - sepol_module_package_get_seusers_len; - sepol_module_package_get_user_extra; - sepol_module_package_get_user_extra_len; - sepol_module_package_info; - sepol_module_package_read; - sepol_module_package_set_file_contexts; - sepol_module_package_set_netfilter_contexts; - sepol_module_package_set_seusers; - sepol_module_package_set_user_extra; - sepol_module_package_write; - sepol_msg_get_channel; - sepol_msg_get_fname; - sepol_msg_get_level; - sepol_msg_set_callback; - sepol_node_clone; - sepol_node_compare; - sepol_node_compare2; - sepol_node_count; - sepol_node_create; - sepol_node_exists; - sepol_node_free; - sepol_node_get_addr; - sepol_node_get_addr_bytes; - sepol_node_get_con; - sepol_node_get_mask; - sepol_node_get_mask_bytes; - sepol_node_get_proto; - sepol_node_get_proto_str; - sepol_node_iterate; - sepol_node_key_create; - sepol_node_key_extract; - sepol_node_key_free; - sepol_node_key_unpack; - sepol_node_modify; - sepol_node_query; - sepol_node_set_addr; - sepol_node_set_addr_bytes; - sepol_node_set_con; - sepol_node_set_mask; - sepol_node_set_mask_bytes; - sepol_node_set_proto; - sepol_policydb_compat_net; - sepol_policydb_create; - sepol_policydb_free; - sepol_policydb_from_image; - sepol_policydb_mls_enabled; - sepol_policydb_read; - sepol_policydb_set_handle_unknown; - sepol_policydb_set_target_platform; - sepol_policydb_set_typevers; - sepol_policydb_set_vers; - sepol_policydb_to_image; - sepol_policydb_write; - sepol_policy_file_create; - sepol_policy_file_free; - sepol_policy_file_get_len; - sepol_policy_file_set_fp; - sepol_policy_file_set_handle; - sepol_policy_file_set_mem; - sepol_policy_kern_vers_max; - sepol_policy_kern_vers_min; - sepol_port_clone; - sepol_port_compare; - sepol_port_compare2; - sepol_port_count; - sepol_port_create; - sepol_port_exists; - sepol_port_free; - sepol_port_get_con; - sepol_port_get_high; - sepol_port_get_low; - sepol_port_get_proto; - sepol_port_get_proto_str; - sepol_port_iterate; - sepol_port_key_create; - sepol_port_key_extract; - sepol_port_key_free; - sepol_port_key_unpack; - sepol_port_modify; - sepol_port_query; - sepol_port_set_con; - sepol_port_set_port; - sepol_port_set_proto; - sepol_port_set_range; - sepol_set_disable_dontaudit; - sepol_set_expand_consume_base; - sepol_set_policydb_from_file; - sepol_set_preserve_tunables; - sepol_user_add_role; - sepol_user_clone; - sepol_user_compare; - sepol_user_compare2; - sepol_user_count; - sepol_user_create; - sepol_user_del_role; - sepol_user_exists; - sepol_user_free; - sepol_user_get_mlslevel; - sepol_user_get_mlsrange; - sepol_user_get_name; - sepol_user_get_num_roles; - sepol_user_get_roles; - sepol_user_has_role; - sepol_user_iterate; - sepol_user_key_create; - sepol_user_key_extract; - sepol_user_key_free; - sepol_user_key_unpack; - sepol_user_modify; - sepol_user_query; - sepol_user_set_mlslevel; - sepol_user_set_mlsrange; - sepol_user_set_name; - sepol_user_set_roles; + cil_set_handle_unknown; + cil_db_destroy; + cil_add_file; + cil_compile; + cil_build_policydb; + cil_userprefixes_to_string; + cil_selinuxusers_to_string; + cil_filecons_to_string; + cil_set_log_level; + cil_set_log_handler; + cil_set_malloc_error_handler; local: *; }; @@ -269,8 +63,4 @@ LIBSEPOL_1.1 { LIBSEPOL_3.0 { global: sepol_policydb_optimize; - cil_write_parse_ast; - cil_write_build_ast; - cil_write_resolve_ast; - cil_set_qualified_names; } LIBSEPOL_1.1; diff --git a/libsepol/src/link.c b/libsepol/src/link.c index 461d2feb..83bbc8a5 100644 --- a/libsepol/src/link.c +++ b/libsepol/src/link.c @@ -78,7 +78,7 @@ typedef struct missing_requirement { uint32_t perm_value; } missing_requirement_t; -static const char * const symtab_names[SYM_NUM] = { +static const char *symtab_names[SYM_NUM] = { "common", "class", "role", "type/attribute", "user", "bool", "level", "category" }; @@ -2573,6 +2573,36 @@ int link_modules(sepol_handle_t * handle, goto cleanup; } + /* copy all types, declared and required */ + for (i = 0; i < len; i++) { + state.cur = modules[i]; + state.cur_mod_name = modules[i]->policy->name; + ret = + hashtab_map(modules[i]->policy->p_types.table, + type_copy_callback, &state); + if (ret) { + retval = ret; + goto cleanup; + } + } + + /* then copy everything else, including aliases, and fixup attributes */ + for (i = 0; i < len; i++) { + state.cur = modules[i]; + state.cur_mod_name = modules[i]->policy->name; + ret = + copy_identifiers(&state, modules[i]->policy->symtab, NULL); + if (ret) { + retval = ret; + goto cleanup; + } + } + + if (policydb_index_others(state.handle, state.base, 0)) { + ERR(state.handle, "Error while indexing others"); + goto cleanup; + } + /* copy and remap the module's data over to base */ for (i = 0; i < len; i++) { state.cur = modules[i]; diff --git a/libsepol/src/mls.c b/libsepol/src/mls.c index 366a1114..6ff9a846 100644 --- a/libsepol/src/mls.c +++ b/libsepol/src/mls.c @@ -27,9 +27,9 @@ * Implementation of the multi-level security (MLS) policy. */ -#include #include #include +#include #include #include @@ -649,7 +649,7 @@ int mls_compute_sid(policydb_t * policydb, /* Fallthrough */ case AVTAB_CHANGE: - if (tclass == policydb->process_class) + if (tclass == SECCLASS_PROCESS) /* Use the process MLS attributes. */ return mls_copy_context(newcontext, scontext); else @@ -665,7 +665,7 @@ int mls_compute_sid(policydb_t * policydb, } int sepol_mls_contains(sepol_handle_t * handle, - const sepol_policydb_t * policydb, + sepol_policydb_t * policydb, const char *mls1, const char *mls2, int *response) { @@ -704,7 +704,7 @@ int sepol_mls_contains(sepol_handle_t * handle, } int sepol_mls_check(sepol_handle_t * handle, - const sepol_policydb_t * policydb, const char *mls) + sepol_policydb_t * policydb, const char *mls) { int ret; diff --git a/libsepol/src/module.c b/libsepol/src/module.c index 02a5de2c..3b8a0a59 100644 --- a/libsepol/src/module.c +++ b/libsepol/src/module.c @@ -82,7 +82,7 @@ static int policy_file_length(struct policy_file *fp, size_t *out) break; case PF_USE_MEMORY: *out = fp->size; - break; + break;; default: *out = 0; break; @@ -132,6 +132,7 @@ int sepol_module_package_create(sepol_module_package_t ** p) return rc; } +hidden_def(sepol_module_package_create) /* Deallocates all memory associated with a module package, including * the pointer itself. Does nothing if p is NULL. @@ -149,6 +150,7 @@ void sepol_module_package_free(sepol_module_package_t * p) free(p); } +hidden_def(sepol_module_package_free) char *sepol_module_package_get_file_contexts(sepol_module_package_t * p) { @@ -796,9 +798,7 @@ int sepol_module_package_info(struct sepol_policy_file *spf, int *type, len = le32_to_cpu(buf[0]); if (str_read(name, file, len)) { - ERR(file->handle, - "cannot read module name (at section %u): %m", - i); + ERR(file->handle, "%s", strerror(errno)); goto cleanup; } @@ -811,9 +811,7 @@ int sepol_module_package_info(struct sepol_policy_file *spf, int *type, } len = le32_to_cpu(buf[0]); if (str_read(version, file, len)) { - ERR(file->handle, - "cannot read module version (at section %u): %m", - i); + ERR(file->handle, "%s", strerror(errno)); goto cleanup; } seen |= SEEN_MOD; diff --git a/libsepol/src/module_internal.h b/libsepol/src/module_internal.h index ac1be36a..cdd5ec65 100644 --- a/libsepol/src/module_internal.h +++ b/libsepol/src/module_internal.h @@ -1,2 +1,5 @@ #include +#include "dso.h" +hidden_proto(sepol_module_package_create) + hidden_proto(sepol_module_package_free) diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c index 9c7e3d3a..e20c3d44 100644 --- a/libsepol/src/module_to_cil.c +++ b/libsepol/src/module_to_cil.c @@ -62,7 +62,7 @@ # define UNUSED(x) UNUSED_ ## x #endif -static FILE *out_file; +FILE *out_file; #define STACK_SIZE 16 #define DEFAULT_LEVEL "systemlow" @@ -107,8 +107,8 @@ static void cil_printf(const char *fmt, ...) { __attribute__ ((format(printf, 2, 3))) static void cil_println(int indent, const char *fmt, ...) { - va_list argptr; cil_indent(indent); + va_list argptr; va_start(argptr, fmt); if (vfprintf(out_file, fmt, argptr) < 0) { log_err("Failed to write to output"); @@ -235,14 +235,12 @@ static void role_list_destroy(void) static void attr_list_destroy(struct list **attr_list) { - struct list_node *curr; - struct attr_list_node *attr; - if (attr_list == NULL || *attr_list == NULL) { return; } - curr = (*attr_list)->head; + struct list_node *curr = (*attr_list)->head; + struct attr_list_node *attr; while (curr != NULL) { attr = curr->data; @@ -719,9 +717,9 @@ exit: return rc; } -static unsigned int num_digits(unsigned int n) +static int num_digits(int n) { - unsigned int num = 1; + int num = 1; while (n >= 10) { n /= 10; num++; @@ -831,8 +829,8 @@ static int cil_print_attr_strs(int indent, struct policydb *pdb, int is_type, vo pos = &ts->types; neg = &ts->negset; flags = ts->flags; - has_positive = pos && !ebitmap_is_empty(pos); - has_negative = neg && !ebitmap_is_empty(neg); + has_positive = pos && (ebitmap_length(pos) > 0); + has_negative = neg && (ebitmap_length(neg) > 0); } else { kind = "role"; val_to_name = pdb->p_role_val_to_name; @@ -840,7 +838,7 @@ static int cil_print_attr_strs(int indent, struct policydb *pdb, int is_type, vo pos = &rs->roles; neg = NULL; flags = rs->flags; - has_positive = pos && !ebitmap_is_empty(pos); + has_positive = pos && (ebitmap_length(pos) > 0); has_negative = 0; } @@ -947,7 +945,7 @@ static char *search_attr_list(struct list *attr_list, int is_type, void *set) return NULL; } -static int set_to_names(struct policydb *pdb, int is_type, void *set, struct list *attr_list, char ***names, unsigned int *num_names) +static int set_to_names(struct policydb *pdb, int is_type, void *set, struct list *attr_list, char ***names, int *num_names) { char *attr_name = NULL; int rc = 0; @@ -984,12 +982,12 @@ exit: return rc; } -static int ebitmap_to_names(struct ebitmap *map, char **vals_to_names, char ***names, unsigned int *num_names) +static int ebitmap_to_names(struct ebitmap *map, char **vals_to_names, char ***names, int *num_names) { int rc = 0; struct ebitmap_node *node; uint32_t i; - unsigned int num; + uint32_t num; char **name_arr; num = 0; @@ -1028,7 +1026,7 @@ exit: return rc; } -static int process_roleset(struct policydb *pdb, struct role_set *rs, struct list *attr_list, char ***names, unsigned int *num_names) +static int process_roleset(struct policydb *pdb, struct role_set *rs, struct list *attr_list, char ***names, int *num_names) { int rc = 0; @@ -1051,14 +1049,14 @@ exit: return rc; } -static int process_typeset(struct policydb *pdb, struct type_set *ts, struct list *attr_list, char ***names, unsigned int *num_names) +static int process_typeset(struct policydb *pdb, struct type_set *ts, struct list *attr_list, char ***names, int *num_names) { int rc = 0; *names = NULL; *num_names = 0; - if (!ebitmap_is_empty(&ts->negset) || ts->flags != 0) { + if (ebitmap_length(&ts->negset) > 0 || ts->flags != 0) { rc = set_to_names(pdb, 1, ts, attr_list, names, num_names); if (rc != 0) { goto exit; @@ -1074,7 +1072,7 @@ exit: return rc; } -static void names_destroy(char ***names, unsigned int *num_names) +static void names_destroy(char ***names, int *num_names) { free(*names); *names = NULL; @@ -1085,7 +1083,7 @@ static int roletype_role_in_ancestor_to_cil(struct policydb *pdb, struct stack * { struct list_node *curr; char **tnames = NULL; - unsigned int num_tnames, i; + int num_tnames, i; struct role_list_node *role_node = NULL; int rc; struct type_set *ts; @@ -1126,24 +1124,26 @@ exit: } -static int name_list_to_string(char **names, unsigned int num_names, char **string) +static int name_list_to_string(char **names, int num_names, char **string) { // create a space separated string of the names int rc = -1; size_t len = 0; - unsigned int i; + int i; char *str; char *strpos; for (i = 0; i < num_names; i++) { - if (__builtin_add_overflow(len, strlen(names[i]), &len)) { + len += strlen(names[i]); + if (len < strlen(names[i])) { log_err("Overflow"); return -1; } } // add spaces + null terminator - if (__builtin_add_overflow(len, (size_t)num_names, &len)) { + len += num_names; + if (len < (size_t)num_names) { log_err("Overflow"); return -1; } @@ -1184,7 +1184,7 @@ static int avrule_list_to_cil(int indent, struct policydb *pdb, struct avrule *a struct avrule *avrule; char **snames = NULL; char **tnames = NULL; - unsigned int s, t, num_snames, num_tnames; + int s, t, num_snames, num_tnames; struct type_set *ts; for (avrule = avrule_list; avrule != NULL; avrule = avrule->next) { @@ -1257,7 +1257,7 @@ static int cond_expr_to_cil(int indent, struct policydb *pdb, struct cond_expr * char *new_val = NULL; char *val1 = NULL; char *val2 = NULL; - unsigned int num_params; + int num_params; const char *op; const char *fmt_str; const char *type; @@ -1432,11 +1432,11 @@ static int role_trans_to_cil(int indent, struct policydb *pdb, struct role_trans int rc = 0; struct role_trans_rule *rule; char **role_names = NULL; - unsigned int num_role_names = 0; - unsigned int role; + int num_role_names = 0; + int role; char **type_names = NULL; - unsigned int num_type_names = 0; - unsigned int type; + int num_type_names = 0; + int type; uint32_t i; struct ebitmap_node *node; struct type_set *ts; @@ -1482,10 +1482,10 @@ static int role_allows_to_cil(int indent, struct policydb *pdb, struct role_allo int rc = -1; struct role_allow_rule *rule; char **roles = NULL; - unsigned int num_roles = 0; + int num_roles = 0; char **new_roles = NULL; - unsigned int num_new_roles = 0; - unsigned int i, j; + int num_new_roles = 0; + int i,j; struct role_set *rs; for (rule = rules; rule != NULL; rule = rule->next) { @@ -1525,11 +1525,11 @@ static int range_trans_to_cil(int indent, struct policydb *pdb, struct range_tra int rc = -1; struct range_trans_rule *rule; char **stypes = NULL; - unsigned int num_stypes = 0; - unsigned int stype; + int num_stypes = 0; + int stype; char **ttypes = NULL; - unsigned int num_ttypes = 0; - unsigned int ttype; + int num_ttypes = 0; + int ttype; struct ebitmap_node *node; uint32_t i; struct type_set *ts; @@ -1594,11 +1594,11 @@ static int filename_trans_to_cil(int indent, struct policydb *pdb, struct filena { int rc = -1; char **stypes = NULL; - unsigned int num_stypes = 0; - unsigned int stype; + int num_stypes = 0; + int stype; char **ttypes = NULL; - unsigned int num_ttypes = 0; - unsigned int ttype; + int num_ttypes = 0; + int ttype; struct type_set *ts; struct filename_trans_rule *rule; @@ -1716,7 +1716,7 @@ static int constraint_expr_to_string(struct policydb *pdb, struct constraint_exp const char *attr2; char *names = NULL; char **name_list = NULL; - unsigned int num_names = 0; + int num_names = 0; struct type_set *ts; rc = stack_init(&stack); @@ -1745,7 +1745,7 @@ static int constraint_expr_to_string(struct policydb *pdb, struct constraint_exp case CEXPR_ROLE: attr1 = "r1"; attr2 = "r2"; break; case CEXPR_ROLE | CEXPR_TARGET: attr1 = "r2"; attr2 = ""; break; case CEXPR_ROLE | CEXPR_XTARGET: attr1 = "r3"; attr2 = ""; break; - case CEXPR_TYPE: attr1 = "t1"; attr2 = "t2"; break; + case CEXPR_TYPE: attr1 = "t1"; attr2 = ""; break; case CEXPR_TYPE | CEXPR_TARGET: attr1 = "t2"; attr2 = ""; break; case CEXPR_TYPE | CEXPR_XTARGET: attr1 = "t3"; attr2 = ""; break; case CEXPR_L1L2: attr1 = "l1"; attr2 = "l2"; break; @@ -1793,31 +1793,20 @@ static int constraint_expr_to_string(struct policydb *pdb, struct constraint_exp goto exit; } } - if (num_names == 0) { - names = strdup("NO_IDENTIFIER"); - } else { - rc = name_list_to_string(name_list, num_names, &names); - if (rc != 0) { - goto exit; - } + rc = name_list_to_string(name_list, num_names, &names); + if (rc != 0) { + goto exit; } // length of values/oper + 2 spaces + 2 parens + null terminator len = strlen(op) + strlen(attr1) + strlen(names) + 2 + 2 + 1; - if (num_names > 1) { - len += 2; // 2 more parens - } new_val = malloc(len); if (new_val == NULL) { log_err("Out of memory"); rc = -1; goto exit; } - if (num_names > 1) { - rlen = snprintf(new_val, len, "(%s %s (%s))", op, attr1, names); - } else { - rlen = snprintf(new_val, len, "(%s %s %s)", op, attr1, names); - } + rlen = snprintf(new_val, len, "(%s %s %s)", op, attr1, names); if (rlen < 0 || rlen >= len) { log_err("Failed to generate constraint expression"); rc = -1; @@ -2080,7 +2069,7 @@ static int class_order_to_cil(int indent, struct policydb *pdb, struct ebitmap o struct ebitmap_node *node; uint32_t i; - if (ebitmap_is_empty(&order)) { + if (ebitmap_cardinality(&order) == 0) { return 0; } @@ -2101,9 +2090,9 @@ static int role_to_cil(int indent, struct policydb *pdb, struct avrule_block *UN int rc = -1; struct ebitmap_node *node; uint32_t i; - unsigned int j; + int j; char **types = NULL; - unsigned int num_types = 0; + int num_types = 0; struct role_datum *role = datum; struct type_set *ts; struct list *attr_list = NULL; @@ -2186,7 +2175,7 @@ static int role_to_cil(int indent, struct policydb *pdb, struct avrule_block *UN cil_println(indent, "(roleattribute %s)", key); } - if (!ebitmap_is_empty(&role->roles)) { + if (ebitmap_cardinality(&role->roles) > 0) { cil_indent(indent); cil_printf("(roleattributeset %s (", key); ebitmap_for_each_positive_bit(&role->roles, node, i) { @@ -2280,7 +2269,7 @@ static int type_to_cil(int indent, struct policydb *pdb, struct avrule_block *UN cil_printf(")\n"); } - if (!ebitmap_is_empty(&type->types)) { + if (ebitmap_cardinality(&type->types) > 0) { cil_indent(indent); cil_printf("(typeattributeset %s (", key); ebitmap_to_cil(pdb, &type->types, SYM_TYPES); @@ -2383,7 +2372,7 @@ static int sens_to_cil(int indent, struct policydb *pdb, struct avrule_block *UN } } - if (!ebitmap_is_empty(&level->level->cat)) { + if (ebitmap_cardinality(&level->level->cat) > 0) { cil_indent(indent); cil_printf("(sensitivitycategory %s (", key); ebitmap_to_cil(pdb, &level->level->cat, SYM_CATS); @@ -2398,7 +2387,7 @@ static int sens_order_to_cil(int indent, struct policydb *pdb, struct ebitmap or struct ebitmap_node *node; uint32_t i; - if (ebitmap_is_empty(&order)) { + if (ebitmap_cardinality(&order) == 0) { return 0; } @@ -2438,7 +2427,7 @@ static int cat_order_to_cil(int indent, struct policydb *pdb, struct ebitmap ord struct ebitmap_node *node; uint32_t i; - if (ebitmap_is_empty(&order)) { + if (ebitmap_cardinality(&order) == 0) { rc = 0; goto exit; } @@ -2489,7 +2478,7 @@ static int level_to_cil(struct policydb *pdb, struct mls_level *level) cil_printf("(%s", pdb->p_sens_val_to_name[level->sens - 1]); - if (!ebitmap_is_empty(map)) { + if (ebitmap_cardinality(map) > 0) { cil_printf("("); ebitmap_to_cil(pdb, map, SYM_CATS); cil_printf(")"); @@ -2668,7 +2657,8 @@ static int ocontext_selinux_ibpkey_to_cil(struct policydb *pdb, if (inet_ntop(AF_INET6, &subnet_prefix.s6_addr, subnet_prefix_str, INET6_ADDRSTRLEN) == NULL) { - log_err("ibpkeycon subnet_prefix is invalid: %m"); + log_err("ibpkeycon subnet_prefix is invalid: %s", + strerror(errno)); rc = -1; goto exit; } @@ -2713,13 +2703,13 @@ static int ocontext_selinux_node_to_cil(struct policydb *pdb, struct ocontext *n for (node = nodes; node != NULL; node = node->next) { if (inet_ntop(AF_INET, &node->u.node.addr, addr, INET_ADDRSTRLEN) == NULL) { - log_err("Nodecon address is invalid: %m"); + log_err("Nodecon address is invalid: %s", strerror(errno)); rc = -1; goto exit; } if (inet_ntop(AF_INET, &node->u.node.mask, mask, INET_ADDRSTRLEN) == NULL) { - log_err("Nodecon mask is invalid: %m"); + log_err("Nodecon mask is invalid: %s", strerror(errno)); rc = -1; goto exit; } @@ -2745,13 +2735,13 @@ static int ocontext_selinux_node6_to_cil(struct policydb *pdb, struct ocontext * for (node = nodes; node != NULL; node = node->next) { if (inet_ntop(AF_INET6, &node->u.node6.addr, addr, INET6_ADDRSTRLEN) == NULL) { - log_err("Nodecon address is invalid: %m"); + log_err("Nodecon address is invalid: %s", strerror(errno)); rc = -1; goto exit; } if (inet_ntop(AF_INET6, &node->u.node6.mask, mask, INET6_ADDRSTRLEN) == NULL) { - log_err("Nodecon mask is invalid: %m"); + log_err("Nodecon mask is invalid: %s", strerror(errno)); rc = -1; goto exit; } @@ -2964,7 +2954,7 @@ static int genfscon_to_cil(struct policydb *pdb) for (genfs = pdb->genfs; genfs != NULL; genfs = genfs->next) { for (ocon = genfs->head; ocon != NULL; ocon = ocon->next) { - cil_printf("(genfscon %s \"%s\" ", genfs->fstype, ocon->u.name); + cil_printf("(genfscon %s %s ", genfs->fstype, ocon->u.name); context_to_cil(pdb, &ocon->context[0]); cil_printf(")\n"); } @@ -3526,12 +3516,12 @@ exit: static int additive_scopes_to_cil(int indent, struct policydb *pdb, struct avrule_block *block, struct stack *decl_stack) { int rc = -1; - struct avrule_decl *decl = stack_peek(decl_stack); struct map_args args; args.pdb = pdb; args.block = block; args.decl_stack = decl_stack; args.indent = indent; + struct avrule_decl *decl = stack_peek(decl_stack); for (args.sym_index = 0; args.sym_index < SYM_NUM; args.sym_index++) { if (func_to_cil[args.sym_index] == NULL) { @@ -3973,7 +3963,7 @@ int sepol_module_policydb_to_cil(FILE *fp, struct policydb *pdb, int linked) if (pdb->policy_type != SEPOL_POLICY_BASE && pdb->policy_type != SEPOL_POLICY_MOD) { - log_err("Policy package is not a base or module"); + log_err("Policy pakcage is not a base or module"); rc = -1; goto exit; } diff --git a/libsepol/src/node_internal.h b/libsepol/src/node_internal.h index 6d3c2505..802cda97 100644 --- a/libsepol/src/node_internal.h +++ b/libsepol/src/node_internal.h @@ -3,5 +3,24 @@ #include #include +#include "dso.h" +hidden_proto(sepol_node_create) + hidden_proto(sepol_node_key_free) + hidden_proto(sepol_node_free) + hidden_proto(sepol_node_get_con) + hidden_proto(sepol_node_get_addr) + hidden_proto(sepol_node_get_addr_bytes) + hidden_proto(sepol_node_get_mask) + hidden_proto(sepol_node_get_mask_bytes) + hidden_proto(sepol_node_get_proto) + hidden_proto(sepol_node_get_proto_str) + hidden_proto(sepol_node_key_create) + hidden_proto(sepol_node_key_unpack) + hidden_proto(sepol_node_set_con) + hidden_proto(sepol_node_set_addr) + hidden_proto(sepol_node_set_addr_bytes) + hidden_proto(sepol_node_set_mask) + hidden_proto(sepol_node_set_mask_bytes) + hidden_proto(sepol_node_set_proto) #endif diff --git a/libsepol/src/node_record.c b/libsepol/src/node_record.c index 2e575bf1..f3e78ff3 100644 --- a/libsepol/src/node_record.c +++ b/libsepol/src/node_record.c @@ -53,7 +53,7 @@ static int node_parse_addr(sepol_handle_t * handle, if (inet_pton(AF_INET, addr_str, &in_addr) <= 0) { ERR(handle, "could not parse IPv4 address " - "%s: %m", addr_str); + "%s: %s", addr_str, strerror(errno)); return STATUS_ERR; } @@ -66,7 +66,7 @@ static int node_parse_addr(sepol_handle_t * handle, if (inet_pton(AF_INET6, addr_str, &in_addr) <= 0) { ERR(handle, "could not parse IPv6 address " - "%s: %m", addr_str); + "%s: %s", addr_str, strerror(errno)); return STATUS_ERR; } @@ -147,7 +147,8 @@ static int node_expand_addr(sepol_handle_t * handle, INET_ADDRSTRLEN) == NULL) { ERR(handle, - "could not expand IPv4 address to string: %m"); + "could not expand IPv4 address to string: %s", + strerror(errno)); return STATUS_ERR; } break; @@ -162,7 +163,8 @@ static int node_expand_addr(sepol_handle_t * handle, INET6_ADDRSTRLEN) == NULL) { ERR(handle, - "could not expand IPv6 address to string: %m"); + "could not expand IPv6 address to string: %s", + strerror(errno)); return STATUS_ERR; } break; @@ -257,6 +259,7 @@ int sepol_node_key_create(sepol_handle_t * handle, return STATUS_ERR; } +hidden_def(sepol_node_key_create) void sepol_node_key_unpack(const sepol_node_key_t * key, const char **addr, const char **mask, int *proto) @@ -267,6 +270,7 @@ void sepol_node_key_unpack(const sepol_node_key_t * key, *proto = key->proto; } +hidden_def(sepol_node_key_unpack) int sepol_node_key_extract(sepol_handle_t * handle, const sepol_node_t * node, @@ -310,6 +314,7 @@ void sepol_node_key_free(sepol_node_key_t * key) free(key); } +hidden_def(sepol_node_key_free) int sepol_node_compare(const sepol_node_t * node, const sepol_node_key_t * key) { @@ -370,6 +375,7 @@ int sepol_node_get_addr(sepol_handle_t * handle, return STATUS_ERR; } +hidden_def(sepol_node_get_addr) int sepol_node_get_addr_bytes(sepol_handle_t * handle, const sepol_node_t * node, @@ -388,6 +394,7 @@ int sepol_node_get_addr_bytes(sepol_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(sepol_node_get_addr_bytes) int sepol_node_set_addr(sepol_handle_t * handle, sepol_node_t * node, int proto, const char *addr) @@ -413,6 +420,7 @@ int sepol_node_set_addr(sepol_handle_t * handle, return STATUS_ERR; } +hidden_def(sepol_node_set_addr) int sepol_node_set_addr_bytes(sepol_handle_t * handle, sepol_node_t * node, @@ -432,6 +440,7 @@ int sepol_node_set_addr_bytes(sepol_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(sepol_node_set_addr_bytes) /* Mask */ int sepol_node_get_mask(sepol_handle_t * handle, @@ -455,6 +464,7 @@ int sepol_node_get_mask(sepol_handle_t * handle, return STATUS_ERR; } +hidden_def(sepol_node_get_mask) int sepol_node_get_mask_bytes(sepol_handle_t * handle, const sepol_node_t * node, @@ -473,6 +483,7 @@ int sepol_node_get_mask_bytes(sepol_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(sepol_node_get_mask_bytes) int sepol_node_set_mask(sepol_handle_t * handle, sepol_node_t * node, int proto, const char *mask) @@ -498,6 +509,7 @@ int sepol_node_set_mask(sepol_handle_t * handle, return STATUS_ERR; } +hidden_def(sepol_node_set_mask) int sepol_node_set_mask_bytes(sepol_handle_t * handle, sepol_node_t * node, @@ -516,6 +528,7 @@ int sepol_node_set_mask_bytes(sepol_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(sepol_node_set_mask_bytes) /* Protocol */ int sepol_node_get_proto(const sepol_node_t * node) @@ -524,6 +537,7 @@ int sepol_node_get_proto(const sepol_node_t * node) return node->proto; } +hidden_def(sepol_node_get_proto) void sepol_node_set_proto(sepol_node_t * node, int proto) { @@ -531,6 +545,7 @@ void sepol_node_set_proto(sepol_node_t * node, int proto) node->proto = proto; } +hidden_def(sepol_node_set_proto) const char *sepol_node_get_proto_str(int proto) { @@ -545,6 +560,7 @@ const char *sepol_node_get_proto_str(int proto) } } +hidden_def(sepol_node_get_proto_str) /* Create */ int sepol_node_create(sepol_handle_t * handle, sepol_node_t ** node) @@ -568,6 +584,7 @@ int sepol_node_create(sepol_handle_t * handle, sepol_node_t ** node) return STATUS_SUCCESS; } +hidden_def(sepol_node_create) /* Deep copy clone */ int sepol_node_clone(sepol_handle_t * handle, @@ -620,6 +637,7 @@ void sepol_node_free(sepol_node_t * node) free(node); } +hidden_def(sepol_node_free) /* Context */ sepol_context_t *sepol_node_get_con(const sepol_node_t * node) @@ -628,6 +646,7 @@ sepol_context_t *sepol_node_get_con(const sepol_node_t * node) return node->con; } +hidden_def(sepol_node_get_con) int sepol_node_set_con(sepol_handle_t * handle, sepol_node_t * node, sepol_context_t * con) @@ -645,3 +664,4 @@ int sepol_node_set_con(sepol_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(sepol_node_set_con) diff --git a/libsepol/src/nodes.c b/libsepol/src/nodes.c index 97a0f959..820346d0 100644 --- a/libsepol/src/nodes.c +++ b/libsepol/src/nodes.c @@ -19,20 +19,20 @@ static int node_from_record(sepol_handle_t * handle, ocontext_t *tmp_node = NULL; context_struct_t *tmp_con = NULL; char *addr_buf = NULL, *mask_buf = NULL; - size_t addr_bsize, mask_bsize; - int proto; tmp_node = (ocontext_t *) calloc(1, sizeof(ocontext_t)); if (!tmp_node) goto omem; + size_t addr_bsize, mask_bsize; + /* Address and netmask */ if (sepol_node_get_addr_bytes(handle, data, &addr_buf, &addr_bsize) < 0) goto err; if (sepol_node_get_mask_bytes(handle, data, &mask_buf, &mask_bsize) < 0) goto err; - proto = sepol_node_get_proto(data); + int proto = sepol_node_get_proto(data); switch (proto) { case SEPOL_PROTO_IP4: diff --git a/libsepol/src/optimize.c b/libsepol/src/optimize.c index 6826155c..1e5e97e8 100644 --- a/libsepol/src/optimize.c +++ b/libsepol/src/optimize.c @@ -31,93 +31,28 @@ #include #include -#define TYPE_VEC_INIT_SIZE 16 - -struct type_vec { - uint32_t *types; - unsigned int count, capacity; -}; - -static int type_vec_init(struct type_vec *v) -{ - v->capacity = TYPE_VEC_INIT_SIZE; - v->count = 0; - v->types = malloc(v->capacity * sizeof(*v->types)); - if (!v->types) - return -1; - return 0; -} - -static void type_vec_destroy(struct type_vec *v) -{ - free(v->types); -} - -static int type_vec_append(struct type_vec *v, uint32_t type) -{ - if (v->capacity == v->count) { - unsigned int new_capacity = v->capacity * 2; - uint32_t *new_types = realloc(v->types, - new_capacity * sizeof(*v->types)); - if (!new_types) - return -1; - - v->types = new_types; - v->capacity = new_capacity; - } - - v->types[v->count++] = type; - return 0; -} - -static int type_vec_contains(const struct type_vec *v, uint32_t type) -{ - unsigned int s = 0, e = v->count; - - while (s != e) { - unsigned int mid = (s + e) / 2; - - if (v->types[mid] == type) - return 1; - - if (v->types[mid] < type) - s = mid + 1; - else - e = mid; - } - return 0; -} - /* builds map: type/attribute -> {all attributes that are a superset of it} */ -static struct type_vec *build_type_map(const policydb_t *p) +static ebitmap_t *build_type_map(const policydb_t *p) { unsigned int i, k; - ebitmap_node_t *n; - struct type_vec *map = malloc(p->p_types.nprim * sizeof(*map)); + ebitmap_t *map = malloc(p->p_types.nprim * sizeof(ebitmap_t)); if (!map) return NULL; for (i = 0; i < p->p_types.nprim; i++) { - if (type_vec_init(&map[i])) - goto err; - - if (p->type_val_to_struct[i]->flavor != TYPE_ATTRIB) { - ebitmap_for_each_positive_bit(&p->type_attr_map[i], - n, k) { - if (type_vec_append(&map[i], k)) - goto err; - } + if (p->type_val_to_struct[i] && + p->type_val_to_struct[i]->flavor != TYPE_ATTRIB) { + if (ebitmap_cpy(&map[i], &p->type_attr_map[i])) + goto err; } else { ebitmap_t *types_i = &p->attr_type_map[i]; + ebitmap_init(&map[i]); for (k = 0; k < p->p_types.nprim; k++) { ebitmap_t *types_k = &p->attr_type_map[k]; - if (p->type_val_to_struct[k]->flavor != TYPE_ATTRIB) - continue; - if (ebitmap_contains(types_k, types_i)) { - if (type_vec_append(&map[i], k)) + if (ebitmap_set_bit(&map[i], k, 1)) goto err; } } @@ -126,16 +61,16 @@ static struct type_vec *build_type_map(const policydb_t *p) return map; err: for (k = 0; k <= i; k++) - type_vec_destroy(&map[k]); + ebitmap_destroy(&map[k]); free(map); return NULL; } -static void destroy_type_map(const policydb_t *p, struct type_vec *type_map) +static void destroy_type_map(const policydb_t *p, ebitmap_t *type_map) { unsigned int i; for (i = 0; i < p->p_types.nprim; i++) - type_vec_destroy(&type_map[i]); + ebitmap_destroy(&type_map[i]); free(type_map); } @@ -188,11 +123,10 @@ static int process_avtab_datum(uint16_t specified, /* checks if avtab contains a rule that covers the given rule */ static int is_avrule_redundant(avtab_ptr_t entry, avtab_t *tab, - const struct type_vec *type_map, - unsigned char not_cond) + const ebitmap_t *type_map, unsigned char not_cond) { unsigned int i, k, s_idx, t_idx; - uint32_t st, tt; + ebitmap_node_t *snode, *tnode; avtab_datum_t *d1, *d2; avtab_key_t key; @@ -208,17 +142,14 @@ static int is_avrule_redundant(avtab_ptr_t entry, avtab_t *tab, d1 = &entry->datum; - for (i = 0; i < type_map[s_idx].count; i++) { - st = type_map[s_idx].types[i]; - key.source_type = st + 1; + ebitmap_for_each_positive_bit(&type_map[s_idx], snode, i) { + key.source_type = i + 1; - for (k = 0; k < type_map[t_idx].count; k++) { - tt = type_map[t_idx].types[k]; - - if (not_cond && s_idx == st && t_idx == tt) + ebitmap_for_each_positive_bit(&type_map[t_idx], tnode, k) { + if (not_cond && s_idx == i && t_idx == k) continue; - key.target_type = tt + 1; + key.target_type = k + 1; d2 = avtab_search(tab, &key); if (!d2) @@ -246,7 +177,7 @@ static int is_avrule_with_attr(avtab_ptr_t entry, policydb_t *p) /* checks if conditional list contains a rule that covers the given rule */ static int is_cond_rule_redundant(avtab_ptr_t e1, cond_av_list_t *list, - const struct type_vec *type_map) + const ebitmap_t *type_map) { unsigned int s1, t1, c1, k1, s2, t2, c2, k2; @@ -272,9 +203,9 @@ static int is_cond_rule_redundant(avtab_ptr_t e1, cond_av_list_t *list, if (s1 == s2 && t1 == t2) continue; - if (!type_vec_contains(&type_map[s1], s2)) + if (!ebitmap_get_bit(&type_map[s1], s2)) continue; - if (!type_vec_contains(&type_map[t1], t2)) + if (!ebitmap_get_bit(&type_map[t1], t2)) continue; if (process_avtab_datum(k1, &e1->datum, &e2->datum)) @@ -283,7 +214,7 @@ static int is_cond_rule_redundant(avtab_ptr_t e1, cond_av_list_t *list, return 0; } -static void optimize_avtab(policydb_t *p, const struct type_vec *type_map) +static void optimize_avtab(policydb_t *p, const ebitmap_t *type_map) { avtab_t *tab = &p->te_avtab; unsigned int i; @@ -312,7 +243,7 @@ static void optimize_avtab(policydb_t *p, const struct type_vec *type_map) /* find redundant rules in (*cond) and put them into (*del) */ static void optimize_cond_av_list(cond_av_list_t **cond, cond_av_list_t **del, - policydb_t *p, const struct type_vec *type_map) + policydb_t *p, const ebitmap_t *type_map) { cond_av_list_t **listp = cond; cond_av_list_t *pcov = NULL; @@ -361,7 +292,7 @@ static void optimize_cond_av_list(cond_av_list_t **cond, cond_av_list_t **del, } } -static void optimize_cond_avtab(policydb_t *p, const struct type_vec *type_map) +static void optimize_cond_avtab(policydb_t *p, const ebitmap_t *type_map) { avtab_t *tab = &p->te_cond_avtab; unsigned int i; @@ -430,7 +361,7 @@ static void optimize_cond_avtab(policydb_t *p, const struct type_vec *type_map) int policydb_optimize(policydb_t *p) { - struct type_vec *type_map; + ebitmap_t *type_map; if (p->policy_type != POLICY_KERN) return -1; diff --git a/libsepol/src/polcaps.c b/libsepol/src/polcaps.c index 6a74ec7d..67ed5786 100644 --- a/libsepol/src/polcaps.c +++ b/libsepol/src/polcaps.c @@ -5,7 +5,7 @@ #include #include -static const char * const polcap_names[] = { +static const char *polcap_names[] = { "network_peer_controls", /* POLICYDB_CAPABILITY_NETPEER */ "open_perms", /* POLICYDB_CAPABILITY_OPENPERM */ "extended_socket_class", /* POLICYDB_CAPABILITY_EXTSOCKCLASS */ diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c index 7093d9b7..2c69a609 100644 --- a/libsepol/src/policydb.c +++ b/libsepol/src/policydb.c @@ -49,18 +49,18 @@ #include #include #include +#include #include "kernel_to_common.h" #include "private.h" #include "debug.h" #include "mls.h" -#include "policydb_validate.h" #define POLICYDB_TARGET_SZ ARRAY_SIZE(policydb_target_strings) -const char * const policydb_target_strings[] = { POLICYDB_STRING, POLICYDB_XEN_STRING }; +const char *policydb_target_strings[] = { POLICYDB_STRING, POLICYDB_XEN_STRING }; /* These need to be updated if SYM_NUM or OCON_NUM changes */ -static const struct policydb_compat_info policydb_compat[] = { +static struct policydb_compat_info policydb_compat[] = { { .type = POLICY_KERN, .version = POLICYDB_VERSION_BOUNDARY, @@ -201,13 +201,6 @@ static const struct policydb_compat_info policydb_compat[] = { .ocon_num = OCON_IBENDPORT + 1, .target_platform = SEPOL_TARGET_SELINUX, }, - { - .type = POLICY_KERN, - .version = POLICYDB_VERSION_COMP_FTRANS, - .sym_num = SYM_NUM, - .ocon_num = OCON_IBENDPORT + 1, - .target_platform = SEPOL_TARGET_SELINUX, - }, { .type = POLICY_BASE, .version = MOD_POLICYDB_VERSION_BASE, @@ -460,7 +453,7 @@ static char *symtab_name[SYM_NUM] = { }; #endif -static const unsigned int symtab_sizes[SYM_NUM] = { +static unsigned int symtab_sizes[SYM_NUM] = { 2, 32, 16, @@ -471,12 +464,12 @@ static const unsigned int symtab_sizes[SYM_NUM] = { 16, }; -const struct policydb_compat_info *policydb_lookup_compat(unsigned int version, - unsigned int type, - unsigned int target_platform) +struct policydb_compat_info *policydb_lookup_compat(unsigned int version, + unsigned int type, + unsigned int target_platform) { unsigned int i; - const struct policydb_compat_info *info = NULL; + struct policydb_compat_info *info = NULL; for (i = 0; i < sizeof(policydb_compat) / sizeof(*info); i++) { if (policydb_compat[i].version == version && @@ -635,7 +628,7 @@ void role_trans_rule_init(role_trans_rule_t * x) ebitmap_init(&x->classes); } -static void role_trans_rule_destroy(role_trans_rule_t * x) +void role_trans_rule_destroy(role_trans_rule_t * x) { if (x != NULL) { role_set_destroy(&x->roles); @@ -789,7 +782,6 @@ static int roles_init(policydb_t * p) goto out; } -ignore_unsigned_overflow_ static inline unsigned long partial_name_hash(unsigned long c, unsigned long prevhash) { @@ -798,12 +790,12 @@ partial_name_hash(unsigned long c, unsigned long prevhash) static unsigned int filenametr_hash(hashtab_t h, const_hashtab_key_t k) { - const filename_trans_key_t *ft = (const filename_trans_key_t *)k; + const struct filename_trans *ft = (const struct filename_trans *)k; unsigned long hash; unsigned int byte_num; unsigned char focus; - hash = ft->ttype ^ ft->tclass; + hash = ft->stype ^ ft->ttype ^ ft->tclass; byte_num = 0; while ((focus = ft->name[byte_num++])) @@ -814,15 +806,19 @@ static unsigned int filenametr_hash(hashtab_t h, const_hashtab_key_t k) static int filenametr_cmp(hashtab_t h __attribute__ ((unused)), const_hashtab_key_t k1, const_hashtab_key_t k2) { - const filename_trans_key_t *ft1 = (const filename_trans_key_t *)k1; - const filename_trans_key_t *ft2 = (const filename_trans_key_t *)k2; + const struct filename_trans *ft1 = (const struct filename_trans *)k1; + const struct filename_trans *ft2 = (const struct filename_trans *)k2; int v; - v = spaceship_cmp(ft1->ttype, ft2->ttype); + v = ft1->stype - ft2->stype; if (v) return v; - v = spaceship_cmp(ft1->tclass, ft2->tclass); + v = ft1->ttype - ft2->ttype; + if (v) + return v; + + v = ft1->tclass - ft2->tclass; if (v) return v; @@ -844,15 +840,15 @@ static int rangetr_cmp(hashtab_t h __attribute__ ((unused)), const struct range_trans *key2 = (const struct range_trans *)k2; int v; - v = spaceship_cmp(key1->source_type, key2->source_type); + v = key1->source_type - key2->source_type; if (v) return v; - v = spaceship_cmp(key1->target_type, key2->target_type); + v = key1->target_type - key2->target_type; if (v) return v; - v = spaceship_cmp(key1->target_class, key2->target_class); + v = key1->target_class - key2->target_class; return v; } @@ -995,7 +991,7 @@ static int common_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) comdatum = (common_datum_t *) datum; p = (policydb_t *) datap; - if (!value_isvalid(comdatum->s.value, p->p_commons.nprim)) + if (!comdatum->s.value || comdatum->s.value > p->p_commons.nprim) return -EINVAL; if (p->p_common_val_to_name[comdatum->s.value - 1] != NULL) return -EINVAL; @@ -1011,7 +1007,7 @@ static int class_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) cladatum = (class_datum_t *) datum; p = (policydb_t *) datap; - if (!value_isvalid(cladatum->s.value, p->p_classes.nprim)) + if (!cladatum->s.value || cladatum->s.value > p->p_classes.nprim) return -EINVAL; if (p->p_class_val_to_name[cladatum->s.value - 1] != NULL) return -EINVAL; @@ -1028,7 +1024,7 @@ static int role_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) role = (role_datum_t *) datum; p = (policydb_t *) datap; - if (!value_isvalid(role->s.value, p->p_roles.nprim)) + if (!role->s.value || role->s.value > p->p_roles.nprim) return -EINVAL; if (p->p_role_val_to_name[role->s.value - 1] != NULL) return -EINVAL; @@ -1047,7 +1043,7 @@ static int type_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) p = (policydb_t *) datap; if (typdatum->primary) { - if (!value_isvalid(typdatum->s.value, p->p_types.nprim)) + if (!typdatum->s.value || typdatum->s.value > p->p_types.nprim) return -EINVAL; if (p->p_type_val_to_name[typdatum->s.value - 1] != NULL) return -EINVAL; @@ -1066,7 +1062,7 @@ static int user_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) usrdatum = (user_datum_t *) datum; p = (policydb_t *) datap; - if (!value_isvalid(usrdatum->s.value, p->p_users.nprim)) + if (!usrdatum->s.value || usrdatum->s.value > p->p_users.nprim) return -EINVAL; if (p->p_user_val_to_name[usrdatum->s.value - 1] != NULL) return -EINVAL; @@ -1085,7 +1081,8 @@ static int sens_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) p = (policydb_t *) datap; if (!levdatum->isalias) { - if (!value_isvalid(levdatum->level->sens, p->p_levels.nprim)) + if (!levdatum->level->sens || + levdatum->level->sens > p->p_levels.nprim) return -EINVAL; if (p->p_sens_val_to_name[levdatum->level->sens - 1] != NULL) return -EINVAL; @@ -1104,7 +1101,7 @@ static int cat_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) p = (policydb_t *) datap; if (!catdatum->isalias) { - if (!value_isvalid(catdatum->s.value, p->p_cats.nprim)) + if (!catdatum->s.value || catdatum->s.value > p->p_cats.nprim) return -EINVAL; if (p->p_cat_val_to_name[catdatum->s.value - 1] != NULL) return -EINVAL; @@ -1167,7 +1164,7 @@ int policydb_index_bools(policydb_t * p) return 0; } -static int policydb_index_decls(sepol_handle_t * handle, policydb_t * p) +int policydb_index_decls(sepol_handle_t * handle, policydb_t * p) { avrule_block_t *curblock; avrule_decl_t *decl; @@ -1191,7 +1188,7 @@ static int policydb_index_decls(sepol_handle_t * handle, policydb_t * p) for (curblock = p->global; curblock != NULL; curblock = curblock->next) { for (decl = curblock->branch_list; decl != NULL; decl = decl->next) { - if (!value_isvalid(decl->decl_id, num_decls)) { + if (decl->decl_id < 1 || decl->decl_id > num_decls) { ERR(handle, "invalid decl ID %u", decl->decl_id); return -1; } @@ -1311,6 +1308,7 @@ static int class_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p { class_datum_t *cladatum; constraint_node_t *constraint, *ctemp; + constraint_expr_t *e, *etmp; if (key) free(key); @@ -1322,7 +1320,12 @@ static int class_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p hashtab_destroy(cladatum->permissions.table); constraint = cladatum->constraints; while (constraint) { - constraint_expr_destroy(constraint->expr); + e = constraint->expr; + while (e) { + etmp = e; + e = e->next; + constraint_expr_destroy(etmp); + } ctemp = constraint; constraint = constraint->next; free(ctemp); @@ -1330,7 +1333,12 @@ static int class_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p constraint = cladatum->validatetrans; while (constraint) { - constraint_expr_destroy(constraint->expr); + e = constraint->expr; + while (e) { + etmp = e; + e = e->next; + constraint_expr_destroy(etmp); + } ctemp = constraint; constraint = constraint->next; free(ctemp); @@ -1402,17 +1410,10 @@ common_destroy, class_destroy, role_destroy, type_destroy, user_destroy, static int filenametr_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p __attribute__ ((unused))) { - filename_trans_key_t *ft = (filename_trans_key_t *)key; - filename_trans_datum_t *fd = datum, *next; - + struct filename_trans *ft = (struct filename_trans *)key; free(ft->name); free(key); - do { - next = fd->next; - ebitmap_destroy(&fd->stypes); - free(fd); - fd = next; - } while (fd); + free(datum); return 0; } @@ -1427,7 +1428,7 @@ static int range_tr_destroy(hashtab_key_t key, hashtab_datum_t datum, return 0; } -static void ocontext_selinux_free(ocontext_t **ocontexts) +void ocontext_selinux_free(ocontext_t **ocontexts) { ocontext_t *c, *ctmp; int i; @@ -1449,7 +1450,7 @@ static void ocontext_selinux_free(ocontext_t **ocontexts) } } -static void ocontext_xen_free(ocontext_t **ocontexts) +void ocontext_xen_free(ocontext_t **ocontexts) { ocontext_t *c, *ctmp; int i; @@ -1748,7 +1749,7 @@ int symtab_insert(policydb_t * pol, uint32_t sym, return retval; } -static int type_set_or(type_set_t * dst, const type_set_t * a, const type_set_t * b) +int type_set_or(type_set_t * dst, type_set_t * a, type_set_t * b) { type_set_init(dst); @@ -1765,7 +1766,7 @@ static int type_set_or(type_set_t * dst, const type_set_t * a, const type_set_t return 0; } -int type_set_cpy(type_set_t * dst, const type_set_t * src) +int type_set_cpy(type_set_t * dst, type_set_t * src) { type_set_init(dst); @@ -1778,7 +1779,7 @@ int type_set_cpy(type_set_t * dst, const type_set_t * src) return 0; } -int type_set_or_eq(type_set_t * dst, const type_set_t * other) +int type_set_or_eq(type_set_t * dst, type_set_t * other) { int ret; type_set_t tmp; @@ -1792,6 +1793,24 @@ int type_set_or_eq(type_set_t * dst, const type_set_t * other) return ret; } +int role_set_get_role(role_set_t * x, uint32_t role) +{ + if (x->flags & ROLE_STAR) + return 1; + + if (ebitmap_get_bit(&x->roles, role - 1)) { + if (x->flags & ROLE_COMP) + return 0; + else + return 1; + } else { + if (x->flags & ROLE_COMP) + return 1; + else + return 0; + } +} + /***********************************************************************/ /* everything below is for policy reads */ @@ -2043,7 +2062,7 @@ static int context_read_and_validate(context_struct_t * c, static int perm_read(policydb_t * p __attribute__ ((unused)), hashtab_t h, - struct policy_file *fp, uint32_t nprim) + struct policy_file *fp) { char *key = 0; perm_datum_t *perdatum; @@ -2064,8 +2083,6 @@ static int perm_read(policydb_t * p goto bad; perdatum->s.value = le32_to_cpu(buf[1]); - if (!value_isvalid(perdatum->s.value, nprim)) - goto bad; if (hashtab_insert(h, key, perdatum)) goto bad; @@ -2114,7 +2131,7 @@ static int common_read(policydb_t * p, hashtab_t h, struct policy_file *fp) key[len] = 0; for (i = 0; i < nel; i++) { - if (perm_read(p, comdatum->permissions.table, fp, comdatum->permissions.nprim)) + if (perm_read(p, comdatum->permissions.table, fp)) goto bad; } @@ -2280,7 +2297,7 @@ static int class_read(policydb_t * p, hashtab_t h, struct policy_file *fp) } } for (i = 0; i < nel; i++) { - if (perm_read(p, cladatum->permissions.table, fp, cladatum->permissions.nprim)) + if (perm_read(p, cladatum->permissions.table, fp)) goto bad; } @@ -2504,7 +2521,7 @@ static int type_read(policydb_t * p, hashtab_t h, struct policy_file *fp) return -1; } -static int role_trans_read(policydb_t *p, struct policy_file *fp) +int role_trans_read(policydb_t *p, struct policy_file *fp) { role_trans_t **t = &p->role_tr; unsigned int i; @@ -2541,13 +2558,13 @@ static int role_trans_read(policydb_t *p, struct policy_file *fp) return -1; tr->tclass = le32_to_cpu(buf[0]); } else - tr->tclass = p->process_class; + tr->tclass = SECCLASS_PROCESS; ltr = tr; } return 0; } -static int role_allow_read(role_allow_t ** r, struct policy_file *fp) +int role_allow_read(role_allow_t ** r, struct policy_file *fp) { unsigned int i; uint32_t buf[2], nel; @@ -2579,277 +2596,90 @@ static int role_allow_read(role_allow_t ** r, struct policy_file *fp) return 0; } -int policydb_filetrans_insert(policydb_t *p, uint32_t stype, uint32_t ttype, - uint32_t tclass, const char *name, - char **name_alloc, uint32_t otype, - uint32_t *present_otype) -{ - filename_trans_key_t *ft, key; - filename_trans_datum_t *datum, *last; - - key.ttype = ttype; - key.tclass = tclass; - key.name = (char *)name; - - last = NULL; - datum = hashtab_search(p->filename_trans, (hashtab_key_t)&key); - while (datum) { - if (ebitmap_get_bit(&datum->stypes, stype - 1)) { - if (present_otype) - *present_otype = datum->otype; - return SEPOL_EEXIST; - } - if (datum->otype == otype) - break; - last = datum; - datum = datum->next; - } - if (!datum) { - datum = malloc(sizeof(*datum)); - if (!datum) - return SEPOL_ENOMEM; - - ebitmap_init(&datum->stypes); - datum->otype = otype; - datum->next = NULL; - - if (last) { - last->next = datum; - } else { - char *name_dup; - - if (name_alloc) { - name_dup = *name_alloc; - *name_alloc = NULL; - } else { - name_dup = strdup(name); - if (!name_dup) { - free(datum); - return SEPOL_ENOMEM; - } - } - - ft = malloc(sizeof(*ft)); - if (!ft) { - free(name_dup); - free(datum); - return SEPOL_ENOMEM; - } - - ft->ttype = ttype; - ft->tclass = tclass; - ft->name = name_dup; - - if (hashtab_insert(p->filename_trans, (hashtab_key_t)ft, - (hashtab_datum_t)datum)) { - free(name_dup); - free(datum); - free(ft); - return SEPOL_ENOMEM; - } - } - } - - p->filename_trans_count++; - return ebitmap_set_bit(&datum->stypes, stype - 1, 1); -} - -static int filename_trans_read_one_compat(policydb_t *p, struct policy_file *fp) -{ - uint32_t buf[4], len, stype, ttype, tclass, otype; - char *name = NULL; - int rc; - - rc = next_entry(buf, fp, sizeof(uint32_t)); - if (rc < 0) - return -1; - len = le32_to_cpu(buf[0]); - if (zero_or_saturated(len)) - return -1; - - name = calloc(len + 1, sizeof(*name)); - if (!name) - return -1; - - rc = next_entry(name, fp, len); - if (rc < 0) - goto err; - - rc = next_entry(buf, fp, sizeof(uint32_t) * 4); - if (rc < 0) - goto err; - - stype = le32_to_cpu(buf[0]); - ttype = le32_to_cpu(buf[1]); - tclass = le32_to_cpu(buf[2]); - otype = le32_to_cpu(buf[3]); - - rc = policydb_filetrans_insert(p, stype, ttype, tclass, name, &name, - otype, NULL); - if (rc) { - if (rc != SEPOL_EEXIST) - goto err; - /* - * Some old policies were wrongly generated with - * duplicate filename transition rules. For backward - * compatibility, do not reject such policies, just - * ignore the duplicate. - */ - } - free(name); - return 0; -err: - free(name); - return -1; -} - -static int filename_trans_check_datum(filename_trans_datum_t *datum) -{ - ebitmap_t stypes, otypes; - int rc = -1; - - ebitmap_init(&stypes); - ebitmap_init(&otypes); - - while (datum) { - if (ebitmap_get_bit(&otypes, datum->otype)) - goto out; - - if (ebitmap_set_bit(&otypes, datum->otype, 1)) - goto out; - - if (ebitmap_match_any(&stypes, &datum->stypes)) - goto out; - - if (ebitmap_union(&stypes, &datum->stypes)) - goto out; - - datum = datum->next; - } - rc = 0; -out: - ebitmap_destroy(&stypes); - ebitmap_destroy(&otypes); - return rc; -} - -static int filename_trans_read_one(policydb_t *p, struct policy_file *fp) -{ - filename_trans_key_t *ft = NULL; - filename_trans_datum_t **dst, *datum, *first = NULL; - unsigned int i; - uint32_t buf[3], len, ttype, tclass, ndatum; - char *name = NULL; - int rc; - - rc = next_entry(buf, fp, sizeof(uint32_t)); - if (rc < 0) - return -1; - len = le32_to_cpu(buf[0]); - if (zero_or_saturated(len)) - return -1; - - name = calloc(len + 1, sizeof(*name)); - if (!name) - return -1; - - rc = next_entry(name, fp, len); - if (rc < 0) - goto err; - - rc = next_entry(buf, fp, sizeof(uint32_t) * 3); - if (rc < 0) - goto err; - - ttype = le32_to_cpu(buf[0]); - tclass = le32_to_cpu(buf[1]); - ndatum = le32_to_cpu(buf[2]); - if (ndatum == 0) - goto err; - - dst = &first; - for (i = 0; i < ndatum; i++) { - datum = malloc(sizeof(*datum)); - if (!datum) - goto err; - - *dst = datum; - - /* ebitmap_read() will at least init the bitmap */ - rc = ebitmap_read(&datum->stypes, fp); - if (rc < 0) - goto err; - - rc = next_entry(buf, fp, sizeof(uint32_t)); - if (rc < 0) - goto err; - - datum->otype = le32_to_cpu(buf[0]); - - p->filename_trans_count += ebitmap_cardinality(&datum->stypes); - - dst = &datum->next; - } - *dst = NULL; - - if (ndatum > 1 && filename_trans_check_datum(first)) - goto err; - - ft = malloc(sizeof(*ft)); - if (!ft) - goto err; - - ft->ttype = ttype; - ft->tclass = tclass; - ft->name = name; - - rc = hashtab_insert(p->filename_trans, (hashtab_key_t)ft, - (hashtab_datum_t)first); - if (rc) - goto err; - - return 0; -err: - free(ft); - free(name); - while (first) { - datum = first; - first = first->next; - - ebitmap_destroy(&datum->stypes); - free(datum); - } - return -1; -} - -static int filename_trans_read(policydb_t *p, struct policy_file *fp) +int filename_trans_read(policydb_t *p, struct policy_file *fp) { unsigned int i; - uint32_t buf[1], nel; + uint32_t buf[4], nel, len; + filename_trans_t *ft; + filename_trans_datum_t *otype; int rc; + char *name; rc = next_entry(buf, fp, sizeof(uint32_t)); if (rc < 0) return -1; nel = le32_to_cpu(buf[0]); - if (p->policyvers < POLICYDB_VERSION_COMP_FTRANS) { - for (i = 0; i < nel; i++) { - rc = filename_trans_read_one_compat(p, fp); - if (rc < 0) - return -1; - } - } else { - for (i = 0; i < nel; i++) { - rc = filename_trans_read_one(p, fp); - if (rc < 0) - return -1; + for (i = 0; i < nel; i++) { + ft = NULL; + otype = NULL; + name = NULL; + + ft = calloc(1, sizeof(*ft)); + if (!ft) + goto err; + otype = calloc(1, sizeof(*otype)); + if (!otype) + goto err; + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + goto err; + len = le32_to_cpu(buf[0]); + if (zero_or_saturated(len)) + goto err; + + name = calloc(len + 1, sizeof(*name)); + if (!name) + goto err; + + ft->name = name; + + rc = next_entry(name, fp, len); + if (rc < 0) + goto err; + + rc = next_entry(buf, fp, sizeof(uint32_t) * 4); + if (rc < 0) + goto err; + + ft->stype = le32_to_cpu(buf[0]); + ft->ttype = le32_to_cpu(buf[1]); + ft->tclass = le32_to_cpu(buf[2]); + otype->otype = le32_to_cpu(buf[3]); + + rc = hashtab_insert(p->filename_trans, (hashtab_key_t) ft, + otype); + if (rc) { + if (rc != SEPOL_EEXIST) + goto err; + /* + * Some old policies were wrongly generated with + * duplicate filename transition rules. For backward + * compatibility, do not reject such policies, just + * issue a warning and ignore the duplicate. + */ + WARN(fp->handle, + "Duplicate name-based type_transition %s %s:%s \"%s\": %s, ignoring", + p->p_type_val_to_name[ft->stype - 1], + p->p_type_val_to_name[ft->ttype - 1], + p->p_class_val_to_name[ft->tclass - 1], + ft->name, + p->p_type_val_to_name[otype->otype - 1]); + free(ft); + free(name); + free(otype); + /* continue, ignoring this one */ } } return 0; +err: + free(ft); + free(otype); + free(name); + return -1; } -static int ocontext_read_xen(const struct policydb_compat_info *info, +static int ocontext_read_xen(struct policydb_compat_info *info, policydb_t *p, struct policy_file *fp) { unsigned int i, j; @@ -2958,7 +2788,7 @@ static int ocontext_read_xen(const struct policydb_compat_info *info, } return 0; } -static int ocontext_read_selinux(const struct policydb_compat_info *info, +static int ocontext_read_selinux(struct policydb_compat_info *info, policydb_t * p, struct policy_file *fp) { unsigned int i, j; @@ -3136,7 +2966,7 @@ static int ocontext_read_selinux(const struct policydb_compat_info *info, return 0; } -static int ocontext_read(const struct policydb_compat_info *info, +static int ocontext_read(struct policydb_compat_info *info, policydb_t *p, struct policy_file *fp) { int rc = -1; @@ -3616,20 +3446,14 @@ static int range_read(policydb_t * p, struct policy_file *fp) if (rc < 0) goto err; rt->source_type = le32_to_cpu(buf[0]); - if (!value_isvalid(rt->source_type, p->p_types.nprim)) - goto err; rt->target_type = le32_to_cpu(buf[1]); - if (!value_isvalid(rt->target_type, p->p_types.nprim)) - goto err; if (new_rangetr) { rc = next_entry(buf, fp, (sizeof(uint32_t))); if (rc < 0) goto err; rt->target_class = le32_to_cpu(buf[0]); - if (!value_isvalid(rt->target_class, p->p_classes.nprim)) - goto err; } else - rt->target_class = p->process_class; + rt->target_class = SECCLASS_PROCESS; r = calloc(1, sizeof(*r)); if (!r) goto err; @@ -3758,9 +3582,7 @@ static int role_trans_rule_read(policydb_t *p, role_trans_rule_t ** r, if (ebitmap_read(&tr->classes, fp)) return -1; } else { - if (!p->process_class) - return -1; - if (ebitmap_set_bit(&tr->classes, p->process_class - 1, 1)) + if (ebitmap_set_bit(&tr->classes, SECCLASS_PROCESS - 1, 1)) return -1; } @@ -4137,51 +3959,6 @@ static int scope_read(policydb_t * p, int symnum, struct policy_file *fp) return -1; } -static sepol_security_class_t policydb_string_to_security_class( - struct policydb *policydb, - const char *class_name) -{ - class_datum_t *tclass_datum; - - tclass_datum = hashtab_search(policydb->p_classes.table, - (hashtab_key_t) class_name); - if (!tclass_datum) - return 0; - return tclass_datum->s.value; -} - -static sepol_access_vector_t policydb_string_to_av_perm( - struct policydb *policydb, - sepol_security_class_t tclass, - const char *perm_name) -{ - class_datum_t *tclass_datum; - perm_datum_t *perm_datum; - - if (!tclass || tclass > policydb->p_classes.nprim) - return 0; - tclass_datum = policydb->class_val_to_struct[tclass - 1]; - - perm_datum = (perm_datum_t *) - hashtab_search(tclass_datum->permissions.table, - (hashtab_key_t)perm_name); - if (perm_datum != NULL) - return 0x1U << (perm_datum->s.value - 1); - - if (tclass_datum->comdatum == NULL) - return 0; - - perm_datum = (perm_datum_t *) - hashtab_search(tclass_datum->comdatum->permissions.table, - (hashtab_key_t)perm_name); - - if (perm_datum != NULL) - return 0x1U << (perm_datum->s.value - 1); - - return 0; -} - - /* * Read the configuration data from a policy database binary * representation file into a policy database structure. @@ -4193,7 +3970,7 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose) uint32_t buf[5]; size_t len, nprim, nel; char *policydb_str; - const struct policydb_compat_info *info; + struct policydb_compat_info *info; unsigned int policy_type, bufindex; ebitmap_node_t *tnode; int rc; @@ -4409,18 +4186,6 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose) p->symtab[i].nprim = nprim; } - switch (p->target_platform) { - case SEPOL_TARGET_SELINUX: - p->process_class = policydb_string_to_security_class(p, "process"); - p->dir_class = policydb_string_to_security_class(p, "dir"); - break; - case SEPOL_TARGET_XEN: - p->process_class = policydb_string_to_security_class(p, "domain"); - break; - default: - break; - } - if (policy_type == POLICY_KERN) { if (avtab_read(&p->te_avtab, fp, r_policyvers)) goto bad; @@ -4464,20 +4229,6 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose) if (policydb_index_classes(p)) goto bad; - switch (p->target_platform) { - case SEPOL_TARGET_SELINUX: - /* fall through */ - case SEPOL_TARGET_XEN: - p->process_trans = policydb_string_to_av_perm(p, p->process_class, - "transition"); - p->process_trans_dyntrans = p->process_trans | - policydb_string_to_av_perm(p, p->process_class, - "dyntransition"); - break; - default: - break; - } - if (policydb_index_others(fp->handle, p, verbose)) goto bad; @@ -4535,9 +4286,6 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose) } } - if (validate_policydb(fp->handle, p)) - goto bad; - return POLICYDB_SUCCESS; bad: return POLICYDB_ERROR; diff --git a/libsepol/src/policydb_internal.h b/libsepol/src/policydb_internal.h index dd8f25d0..f7bcdfa3 100644 --- a/libsepol/src/policydb_internal.h +++ b/libsepol/src/policydb_internal.h @@ -2,6 +2,9 @@ #define _SEPOL_POLICYDB_INTERNAL_H_ #include +#include "dso.h" -extern const char * const policydb_target_strings[]; +hidden_proto(sepol_policydb_create) + hidden_proto(sepol_policydb_free) +extern const char *policydb_target_strings[]; #endif diff --git a/libsepol/src/policydb_public.c b/libsepol/src/policydb_public.c index 0218c940..747a43ff 100644 --- a/libsepol/src/policydb_public.c +++ b/libsepol/src/policydb_public.c @@ -68,12 +68,12 @@ int sepol_policydb_create(sepol_policydb_t ** sp) p = &(*sp)->p; if (policydb_init(p)) { free(*sp); - *sp = NULL; return -1; } return 0; } +hidden_def(sepol_policydb_create) void sepol_policydb_free(sepol_policydb_t * p) { @@ -83,6 +83,7 @@ void sepol_policydb_free(sepol_policydb_t * p) free(p); } +hidden_def(sepol_policydb_free) int sepol_policy_kern_vers_min(void) { diff --git a/libsepol/src/policydb_validate.c b/libsepol/src/policydb_validate.c deleted file mode 100644 index 246aa6e3..00000000 --- a/libsepol/src/policydb_validate.c +++ /dev/null @@ -1,764 +0,0 @@ - -#include -#include -#include - -#include "debug.h" -#include "policydb_validate.h" - -typedef struct validate { - uint32_t nprim; - ebitmap_t gaps; -} validate_t; - - -static int create_gap_ebitmap(char **val_to_name, uint32_t nprim, ebitmap_t *gaps) -{ - unsigned int i; - - ebitmap_init(gaps); - - for (i = 0; i < nprim; i++) { - if (!val_to_name[i]) { - if (ebitmap_set_bit(gaps, i, 1)) - return -1; - } - } - - return 0; -} - -static int validate_init(validate_t *flavor, char **val_to_name, uint32_t nprim) -{ - flavor->nprim = nprim; - if (create_gap_ebitmap(val_to_name, nprim, &flavor->gaps)) - return -1; - - return 0; -} - -static int validate_array_init(policydb_t *p, validate_t flavors[]) -{ - if (validate_init(&flavors[SYM_CLASSES], p->p_class_val_to_name, p->p_classes.nprim)) - goto bad; - if (validate_init(&flavors[SYM_ROLES], p->p_role_val_to_name, p->p_roles.nprim)) - goto bad; - if (p->policyvers < POLICYDB_VERSION_AVTAB || p->policyvers > POLICYDB_VERSION_PERMISSIVE) { - if (validate_init(&flavors[SYM_TYPES], p->p_type_val_to_name, p->p_types.nprim)) - goto bad; - } else { - /* - * For policy versions between 20 and 23, attributes exist in the policy, - * but they only exist in the type_attr_map, so there will be references - * to gaps and we just have to treat this case as if there were no gaps. - */ - flavors[SYM_TYPES].nprim = p->p_types.nprim; - ebitmap_init(&flavors[SYM_TYPES].gaps); - } - if (validate_init(&flavors[SYM_USERS], p->p_user_val_to_name, p->p_users.nprim)) - goto bad; - if (validate_init(&flavors[SYM_BOOLS], p->p_bool_val_to_name, p->p_bools.nprim)) - goto bad; - if (validate_init(&flavors[SYM_LEVELS], p->p_sens_val_to_name, p->p_levels.nprim)) - goto bad; - if (validate_init(&flavors[SYM_CATS], p->p_cat_val_to_name, p->p_cats.nprim)) - goto bad; - - return 0; - -bad: - return -1; -} - -/* - * Functions to validate both kernel and module policydbs - */ - -int value_isvalid(uint32_t value, uint32_t nprim) -{ - if (!value || value > nprim) - return 0; - - return 1; -} - -static int validate_value(uint32_t value, validate_t *flavor) -{ - if (!value || value > flavor->nprim) - goto bad; - if (ebitmap_get_bit(&flavor->gaps, value-1)) - goto bad; - - return 0; - -bad: - return -1; -} - -static int validate_ebitmap(ebitmap_t *map, validate_t *flavor) -{ - if (ebitmap_length(map) > 0 && ebitmap_highest_set_bit(map) >= flavor->nprim) - goto bad; - if (ebitmap_match_any(map, &flavor->gaps)) - goto bad; - - return 0; - -bad: - return -1; -} - -static int validate_type_set(type_set_t *type_set, validate_t *type) -{ - if (validate_ebitmap(&type_set->types, type)) - goto bad; - if (validate_ebitmap(&type_set->negset, type)) - goto bad; - - return 0; - -bad: - return -1; -} - -static int validate_role_set(role_set_t *role_set, validate_t *role) -{ - if (validate_ebitmap(&role_set->roles, role)) - return -1; - - return 0; -} - -static int validate_scope(__attribute__ ((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) -{ - scope_datum_t *scope_datum = (scope_datum_t *)d; - uint32_t *nprim = (uint32_t *)args; - unsigned int i; - - for (i = 0; i < scope_datum->decl_ids_len; i++) { - if (!value_isvalid(scope_datum->decl_ids[i], *nprim)) - return -1; - } - - return 0; -} - -static int validate_scopes(sepol_handle_t *handle, symtab_t scopes[], avrule_block_t *block) -{ - avrule_decl_t *decl; - unsigned int i; - unsigned int num_decls = 0; - - for (; block != NULL; block = block->next) { - for (decl = block->branch_list; decl; decl = decl->next) { - num_decls++; - } - } - - for (i = 0; i < SYM_NUM; i++) { - if (hashtab_map(scopes[i].table, validate_scope, &num_decls)) - goto bad; - } - - return 0; - -bad: - ERR(handle, "Invalid scope"); - return -1; -} - -static int validate_constraint_nodes(sepol_handle_t *handle, constraint_node_t *cons, validate_t flavors[]) -{ - constraint_expr_t *cexp; - - for (; cons; cons = cons->next) { - for (cexp = cons->expr; cexp; cexp = cexp->next) { - if (cexp->attr & CEXPR_USER) { - if (validate_ebitmap(&cexp->names, &flavors[SYM_USERS])) - goto bad; - } else if (cexp->attr & CEXPR_ROLE) { - if (validate_ebitmap(&cexp->names, &flavors[SYM_ROLES])) - goto bad; - } else if (cexp->attr & CEXPR_TYPE) { - if (validate_ebitmap(&cexp->names, &flavors[SYM_TYPES])) - goto bad; - if (validate_type_set(cexp->type_names, &flavors[SYM_TYPES])) - goto bad; - } - } - } - - return 0; - -bad: - ERR(handle, "Invalid constraint expr"); - return -1; -} - -static int validate_class_datum(sepol_handle_t *handle, class_datum_t *class, validate_t flavors[]) -{ - if (validate_value(class->s.value, &flavors[SYM_CLASSES])) - goto bad; - if (validate_constraint_nodes(handle, class->constraints, flavors)) - goto bad; - if (validate_constraint_nodes(handle, class->validatetrans, flavors)) - goto bad; - - return 0; - -bad: - ERR(handle, "Invalid class datum"); - return -1; -} - -static int validate_role_datum(sepol_handle_t *handle, role_datum_t *role, validate_t flavors[]) -{ - if (validate_value(role->s.value, &flavors[SYM_ROLES])) - goto bad; - if (validate_ebitmap(&role->dominates, &flavors[SYM_ROLES])) - goto bad; - if (validate_type_set(&role->types, &flavors[SYM_TYPES])) - goto bad; - if (role->bounds && validate_value(role->bounds, &flavors[SYM_ROLES])) - goto bad; - if (validate_ebitmap(&role->roles, &flavors[SYM_ROLES])) - goto bad; - - return 0; - -bad: - ERR(handle, "Invalid class datum"); - return -1; -} - -static int validate_type_datum(sepol_handle_t *handle, type_datum_t *type, validate_t flavors[]) -{ - if (validate_value(type->s.value, &flavors[SYM_TYPES])) - goto bad; - if (validate_ebitmap(&type->types, &flavors[SYM_TYPES])) - goto bad; - if (type->bounds && validate_value(type->bounds, &flavors[SYM_TYPES])) - goto bad; - - return 0; - -bad: - ERR(handle, "Invalid type datum"); - return -1; -} - -static int validate_mls_semantic_cat(mls_semantic_cat_t *cat, validate_t *cats) -{ - for (; cat; cat = cat->next) { - if (validate_value(cat->low, cats)) - goto bad; - if (validate_value(cat->high, cats)) - goto bad; - } - - return 0; - -bad: - return -1; -} - -static int validate_mls_semantic_level(mls_semantic_level_t *level, validate_t *sens, validate_t *cats) -{ - if (level->sens == 0) - return 0; - if (validate_value(level->sens, sens)) - goto bad; - if (validate_mls_semantic_cat(level->cat, cats)) - goto bad; - - return 0; - -bad: - return -1; -} - -static int validate_mls_semantic_range(mls_semantic_range_t *range, validate_t *sens, validate_t *cats) -{ - if (validate_mls_semantic_level(&range->level[0], sens, cats)) - goto bad; - if (validate_mls_semantic_level(&range->level[1], sens, cats)) - goto bad; - - return 0; - -bad: - return -1; -} - -static int validate_user_datum(sepol_handle_t *handle, user_datum_t *user, validate_t flavors[]) -{ - if (validate_value(user->s.value, &flavors[SYM_USERS])) - goto bad; - if (validate_role_set(&user->roles, &flavors[SYM_ROLES])) - goto bad; - if (validate_mls_semantic_range(&user->range, &flavors[SYM_LEVELS], &flavors[SYM_CATS])) - goto bad; - if (validate_mls_semantic_level(&user->dfltlevel, &flavors[SYM_LEVELS], &flavors[SYM_CATS])) - goto bad; - if (user->bounds && validate_value(user->bounds, &flavors[SYM_USERS])) - goto bad; - - return 0; - -bad: - ERR(handle, "Invalid user datum"); - return -1; -} - -static int validate_datum_arrays(sepol_handle_t *handle, policydb_t *p, validate_t flavors[]) -{ - unsigned int i; - - for (i = 0; i < p->p_classes.nprim; i++) { - if (p->class_val_to_struct[i]) { - if (ebitmap_get_bit(&flavors[SYM_CLASSES].gaps, i)) - goto bad; - if (validate_class_datum(handle, p->class_val_to_struct[i], flavors)) - goto bad; - } else { - if (!ebitmap_get_bit(&flavors[SYM_CLASSES].gaps, i)) - goto bad; - } - } - - for (i = 0; i < p->p_roles.nprim; i++) { - if (p->role_val_to_struct[i]) { - if (ebitmap_get_bit(&flavors[SYM_ROLES].gaps, i)) - goto bad; - if (validate_role_datum(handle, p->role_val_to_struct[i], flavors)) - goto bad; - } else { - if (!ebitmap_get_bit(&flavors[SYM_ROLES].gaps, i)) - goto bad; - } - } - - /* - * For policy versions between 20 and 23, attributes exist in the policy, - * but only in the type_attr_map, so all gaps must be assumed to be valid. - */ - if (p->policyvers < POLICYDB_VERSION_AVTAB || p->policyvers > POLICYDB_VERSION_PERMISSIVE) { - for (i = 0; i < p->p_types.nprim; i++) { - if (p->type_val_to_struct[i]) { - if (ebitmap_get_bit(&flavors[SYM_TYPES].gaps, i)) - goto bad; - if (validate_type_datum(handle, p->type_val_to_struct[i], flavors)) - goto bad; - } else { - if (!ebitmap_get_bit(&flavors[SYM_TYPES].gaps, i)) - goto bad; - } - } - } - - for (i = 0; i < p->p_users.nprim; i++) { - if (p->user_val_to_struct[i]) { - if (ebitmap_get_bit(&flavors[SYM_USERS].gaps, i)) - goto bad; - if (validate_user_datum(handle, p->user_val_to_struct[i], flavors)) - goto bad; - } else { - if (!ebitmap_get_bit(&flavors[SYM_USERS].gaps, i)) - goto bad; - } - } - - return 0; - -bad: - ERR(handle, "Invalid datum arrays"); - return -1; -} - -/* - * Functions to validate a kernel policydb - */ - -static int validate_avtab_key(avtab_key_t *key, validate_t flavors[]) -{ - if (validate_value(key->source_type, &flavors[SYM_TYPES])) - goto bad; - if (validate_value(key->target_type, &flavors[SYM_TYPES])) - goto bad; - if (validate_value(key->target_class, &flavors[SYM_CLASSES])) - goto bad; - - return 0; - -bad: - return -1; -} - -static int validate_avtab_key_wrapper(avtab_key_t *k, __attribute__ ((unused)) avtab_datum_t *d, void *args) -{ - validate_t *flavors = (validate_t *)args; - return validate_avtab_key(k, flavors); -} - -static int validate_avtab(sepol_handle_t *handle, avtab_t *avtab, validate_t flavors[]) -{ - if (avtab_map(avtab, validate_avtab_key_wrapper, flavors)) { - ERR(handle, "Invalid avtab"); - return -1; - } - - return 0; -} - -static int validate_cond_av_list(sepol_handle_t *handle, cond_av_list_t *cond_av, validate_t flavors[]) -{ - avtab_ptr_t avtab_ptr; - - for (; cond_av; cond_av = cond_av->next) { - for (avtab_ptr = cond_av->node; avtab_ptr; avtab_ptr = avtab_ptr->next) { - if (validate_avtab_key(&avtab_ptr->key, flavors)) { - ERR(handle, "Invalid cond av list"); - return -1; - } - } - } - - return 0; -} - -static int validate_avrules(sepol_handle_t *handle, avrule_t *avrule, validate_t flavors[]) -{ - class_perm_node_t *class; - - for (; avrule; avrule = avrule->next) { - if (validate_type_set(&avrule->stypes, &flavors[SYM_TYPES])) - goto bad; - if (validate_type_set(&avrule->ttypes, &flavors[SYM_TYPES])) - goto bad; - class = avrule->perms; - for (; class; class = class->next) { - if (validate_value(class->tclass, &flavors[SYM_CLASSES])) - goto bad; - } - } - - return 0; - -bad: - ERR(handle, "Invalid avrule"); - return -1; -} - -static int validate_bool_id_array(sepol_handle_t *handle, uint32_t bool_ids[], unsigned int nbools, validate_t *bool) -{ - unsigned int i; - - if (nbools >= COND_MAX_BOOLS) - goto bad; - - for (i=0; i < nbools; i++) { - if (validate_value(bool_ids[i], bool)) - goto bad; - } - - return 0; - -bad: - ERR(handle, "Invalid bool id array"); - return -1; -} - -static int validate_cond_list(sepol_handle_t *handle, cond_list_t *cond, validate_t flavors[]) -{ - for (; cond; cond = cond->next) { - if (validate_cond_av_list(handle, cond->true_list, flavors)) - goto bad; - if (validate_cond_av_list(handle, cond->false_list, flavors)) - goto bad; - if (validate_avrules(handle, cond->avtrue_list, flavors)) - goto bad; - if (validate_avrules(handle, cond->avfalse_list, flavors)) - goto bad; - if (validate_bool_id_array(handle, cond->bool_ids, cond->nbools, &flavors[SYM_BOOLS])) - goto bad; - } - - return 0; - -bad: - ERR(handle, "Invalid cond list"); - return -1; -} - -static int validate_role_transes(sepol_handle_t *handle, role_trans_t *role_trans, validate_t flavors[]) -{ - for (; role_trans; role_trans = role_trans->next) { - if (validate_value(role_trans->role, &flavors[SYM_ROLES])) - goto bad; - if (validate_value(role_trans->type, &flavors[SYM_TYPES])) - goto bad; - if (validate_value(role_trans->tclass, &flavors[SYM_CLASSES])) - goto bad; - if (validate_value(role_trans->new_role, &flavors[SYM_ROLES])) - goto bad; - } - - return 0; - -bad: - ERR(handle, "Invalid role trans"); - return -1; -} - -static int validate_role_allows(sepol_handle_t *handle, role_allow_t *role_allow, validate_t flavors[]) -{ - for (; role_allow; role_allow = role_allow->next) { - if (validate_value(role_allow->role, &flavors[SYM_ROLES])) - goto bad; - if (validate_value(role_allow->new_role, &flavors[SYM_ROLES])) - goto bad; - } - - return 0; - -bad: - ERR(handle, "Invalid role allow"); - return -1; -} - -static int validate_filename_trans(hashtab_key_t k, hashtab_datum_t d, void *args) -{ - filename_trans_key_t *ftk = (filename_trans_key_t *)k; - filename_trans_datum_t *ftd = d; - validate_t *flavors = (validate_t *)args; - - if (validate_value(ftk->ttype, &flavors[SYM_TYPES])) - goto bad; - if (validate_value(ftk->tclass, &flavors[SYM_CLASSES])) - goto bad; - for (; ftd; ftd = ftd->next) { - if (validate_ebitmap(&ftd->stypes, &flavors[SYM_TYPES])) - goto bad; - if (validate_value(ftd->otype, &flavors[SYM_TYPES])) - goto bad; - } - - return 0; - -bad: - return -1; -} - -static int validate_filename_trans_hashtab(sepol_handle_t *handle, hashtab_t filename_trans, validate_t flavors[]) -{ - if (hashtab_map(filename_trans, validate_filename_trans, flavors)) { - ERR(handle, "Invalid filename trans"); - return -1; - } - - return 0; -} - -/* - * Functions to validate a module policydb - */ - -static int validate_role_trans_rules(sepol_handle_t *handle, role_trans_rule_t *role_trans, validate_t flavors[]) -{ - for (; role_trans; role_trans = role_trans->next) { - if (validate_role_set(&role_trans->roles, &flavors[SYM_ROLES])) - goto bad; - if (validate_type_set(&role_trans->types, &flavors[SYM_TYPES])) - goto bad; - if (validate_ebitmap(&role_trans->classes, &flavors[SYM_CLASSES])) - goto bad; - if (validate_value(role_trans->new_role, &flavors[SYM_ROLES])) - goto bad; - } - - return 0; - -bad: - ERR(handle, "Invalid role trans rule"); - return -1; -} - -static int validate_role_allow_rules(sepol_handle_t *handle, role_allow_rule_t *role_allow, validate_t flavors[]) -{ - for (; role_allow; role_allow = role_allow->next) { - if (validate_role_set(&role_allow->roles, &flavors[SYM_ROLES])) - goto bad; - if (validate_role_set(&role_allow->new_roles, &flavors[SYM_ROLES])) - goto bad; - } - - return 0; - -bad: - ERR(handle, "Invalid role allow rule"); - return -1; -} - -static int validate_range_trans_rules(sepol_handle_t *handle, range_trans_rule_t *range_trans, validate_t flavors[]) -{ - for (; range_trans; range_trans = range_trans->next) { - if (validate_type_set(&range_trans->stypes, &flavors[SYM_TYPES])) - goto bad; - if (validate_type_set(&range_trans->ttypes, &flavors[SYM_TYPES])) - goto bad; - if (validate_ebitmap(&range_trans->tclasses, &flavors[SYM_CLASSES])) - goto bad; - if (validate_mls_semantic_range(&range_trans->trange, &flavors[SYM_LEVELS], &flavors[SYM_CATS])) - goto bad; - } - - return 0; - -bad: - ERR(handle, "Invalid range trans rule"); - return -1; -} - -static int validate_scope_index(sepol_handle_t *handle, scope_index_t *scope_index, validate_t flavors[]) -{ - if (validate_ebitmap(&scope_index->p_classes_scope, &flavors[SYM_CLASSES])) - goto bad; - if (validate_ebitmap(&scope_index->p_roles_scope, &flavors[SYM_ROLES])) - goto bad; - if (validate_ebitmap(&scope_index->p_types_scope, &flavors[SYM_TYPES])) - goto bad; - if (validate_ebitmap(&scope_index->p_users_scope, &flavors[SYM_USERS])) - goto bad; - if (validate_ebitmap(&scope_index->p_bools_scope, &flavors[SYM_BOOLS])) - goto bad; - if (validate_ebitmap(&scope_index->p_sens_scope, &flavors[SYM_LEVELS])) - goto bad; - if (validate_ebitmap(&scope_index->p_cat_scope, &flavors[SYM_CATS])) - goto bad; - if (scope_index->class_perms_len > flavors[SYM_CLASSES].nprim) - goto bad; - - return 0; - -bad: - ERR(handle, "Invalid scope"); - return -1; -} - - -static int validate_filename_trans_rules(sepol_handle_t *handle, filename_trans_rule_t *filename_trans, validate_t flavors[]) -{ - for (; filename_trans; filename_trans = filename_trans->next) { - if (validate_type_set(&filename_trans->stypes, &flavors[SYM_TYPES])) - goto bad; - if (validate_type_set(&filename_trans->ttypes, &flavors[SYM_TYPES])) - goto bad; - if (validate_value(filename_trans->tclass,&flavors[SYM_CLASSES] )) - goto bad; - if (validate_value(filename_trans->otype, &flavors[SYM_TYPES])) - goto bad; - } - - return 0; - -bad: - ERR(handle, "Invalid filename trans rule list"); - return -1; -} - -static int validate_datum(__attribute__ ((unused))hashtab_key_t k, hashtab_datum_t d, void *args) -{ - symtab_datum_t *s = d; - uint32_t *nprim = (uint32_t *)args; - - return !value_isvalid(s->value, *nprim); -} - -static int validate_symtabs(sepol_handle_t *handle, symtab_t symtabs[], validate_t flavors[]) -{ - unsigned int i; - - for (i = 0; i < SYM_NUM; i++) { - if (hashtab_map(symtabs[i].table, validate_datum, &flavors[i].nprim)) { - ERR(handle, "Invalid symtab"); - return -1; - } - } - - return 0; -} - -static int validate_avrule_blocks(sepol_handle_t *handle, avrule_block_t *avrule_block, validate_t flavors[]) -{ - avrule_decl_t *decl; - - for (; avrule_block; avrule_block = avrule_block->next) { - for (decl = avrule_block->branch_list; decl != NULL; decl = decl->next) { - if (validate_cond_list(handle, decl->cond_list, flavors)) - goto bad; - if (validate_avrules(handle, decl->avrules, flavors)) - goto bad; - if (validate_role_trans_rules(handle, decl->role_tr_rules, flavors)) - goto bad; - if (validate_role_allow_rules(handle, decl->role_allow_rules, flavors)) - goto bad; - if (validate_range_trans_rules(handle, decl->range_tr_rules, flavors)) - goto bad; - if (validate_scope_index(handle, &decl->required, flavors)) - goto bad; - if (validate_scope_index(handle, &decl->declared, flavors)) - goto bad; - if (validate_filename_trans_rules(handle, decl->filename_trans_rules, flavors)) - goto bad; - if (validate_symtabs(handle, decl->symtab, flavors)) - goto bad; - } - } - - return 0; - -bad: - ERR(handle, "Invalid avrule block"); - return -1; -} - -/* - * Validate policydb - */ -int validate_policydb(sepol_handle_t *handle, policydb_t *p) -{ - validate_t flavors[SYM_NUM]; - - if (validate_array_init(p, flavors)) - goto bad; - - if (p->policy_type == POLICY_KERN) { - if (validate_avtab(handle, &p->te_avtab, flavors)) - goto bad; - if (p->policyvers >= POLICYDB_VERSION_BOOL) - if (validate_cond_list(handle, p->cond_list, flavors)) - goto bad; - if (validate_role_transes(handle, p->role_tr, flavors)) - goto bad; - if (validate_role_allows(handle, p->role_allow, flavors)) - goto bad; - if (p->policyvers >= POLICYDB_VERSION_FILENAME_TRANS) - if (validate_filename_trans_hashtab(handle, p->filename_trans, flavors)) - goto bad; - } else { - if (validate_avrule_blocks(handle, p->global, flavors)) - goto bad; - } - - if (validate_scopes(handle, p->scope, p->global)) - goto bad; - - if (validate_datum_arrays(handle, p, flavors)) - goto bad; - - return 0; - -bad: - ERR(handle, "Invalid policydb"); - return -1; -} diff --git a/libsepol/src/policydb_validate.h b/libsepol/src/policydb_validate.h deleted file mode 100644 index d9f7229b..00000000 --- a/libsepol/src/policydb_validate.h +++ /dev/null @@ -1,7 +0,0 @@ -#include - -#include -#include - -int value_isvalid(uint32_t value, uint32_t nprim); -int validate_policydb(sepol_handle_t *handle, policydb_t *p); diff --git a/libsepol/src/port_internal.h b/libsepol/src/port_internal.h index 80cf5c25..ffb5f65a 100644 --- a/libsepol/src/port_internal.h +++ b/libsepol/src/port_internal.h @@ -3,5 +3,18 @@ #include #include +#include "dso.h" +hidden_proto(sepol_port_create) + hidden_proto(sepol_port_free) + hidden_proto(sepol_port_get_con) + hidden_proto(sepol_port_get_high) + hidden_proto(sepol_port_get_low) + hidden_proto(sepol_port_get_proto) + hidden_proto(sepol_port_get_proto_str) + hidden_proto(sepol_port_key_create) + hidden_proto(sepol_port_key_unpack) + hidden_proto(sepol_port_set_con) + hidden_proto(sepol_port_set_proto) + hidden_proto(sepol_port_set_range) #endif diff --git a/libsepol/src/port_record.c b/libsepol/src/port_record.c index 7054dbc2..15fb198f 100644 --- a/libsepol/src/port_record.c +++ b/libsepol/src/port_record.c @@ -46,6 +46,7 @@ int sepol_port_key_create(sepol_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(sepol_port_key_create) void sepol_port_key_unpack(const sepol_port_key_t * key, int *low, int *high, int *proto) @@ -56,6 +57,7 @@ void sepol_port_key_unpack(const sepol_port_key_t * key, *proto = key->proto; } +hidden_def(sepol_port_key_unpack) int sepol_port_key_extract(sepol_handle_t * handle, const sepol_port_t * port, @@ -139,6 +141,7 @@ int sepol_port_get_low(const sepol_port_t * port) return port->low; } +hidden_def(sepol_port_get_low) int sepol_port_get_high(const sepol_port_t * port) { @@ -146,6 +149,7 @@ int sepol_port_get_high(const sepol_port_t * port) return port->high; } +hidden_def(sepol_port_get_high) void sepol_port_set_port(sepol_port_t * port, int port_num) { @@ -161,6 +165,7 @@ void sepol_port_set_range(sepol_port_t * port, int low, int high) port->high = high; } +hidden_def(sepol_port_set_range) /* Protocol */ int sepol_port_get_proto(const sepol_port_t * port) @@ -169,6 +174,7 @@ int sepol_port_get_proto(const sepol_port_t * port) return port->proto; } +hidden_def(sepol_port_get_proto) const char *sepol_port_get_proto_str(int proto) { @@ -187,6 +193,7 @@ const char *sepol_port_get_proto_str(int proto) } } +hidden_def(sepol_port_get_proto_str) void sepol_port_set_proto(sepol_port_t * port, int proto) { @@ -194,6 +201,7 @@ void sepol_port_set_proto(sepol_port_t * port, int proto) port->proto = proto; } +hidden_def(sepol_port_set_proto) /* Create */ int sepol_port_create(sepol_handle_t * handle, sepol_port_t ** port) @@ -215,6 +223,7 @@ int sepol_port_create(sepol_handle_t * handle, sepol_port_t ** port) return STATUS_SUCCESS; } +hidden_def(sepol_port_create) /* Deep copy clone */ int sepol_port_clone(sepol_handle_t * handle, @@ -253,6 +262,7 @@ void sepol_port_free(sepol_port_t * port) free(port); } +hidden_def(sepol_port_free) /* Context */ sepol_context_t *sepol_port_get_con(const sepol_port_t * port) @@ -261,6 +271,7 @@ sepol_context_t *sepol_port_get_con(const sepol_port_t * port) return port->con; } +hidden_def(sepol_port_get_con) int sepol_port_set_con(sepol_handle_t * handle, sepol_port_t * port, sepol_context_t * con) @@ -278,3 +289,4 @@ int sepol_port_set_con(sepol_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(sepol_port_set_con) diff --git a/libsepol/src/private.h b/libsepol/src/private.h index 71287282..b884c23b 100644 --- a/libsepol/src/private.h +++ b/libsepol/src/private.h @@ -14,6 +14,7 @@ #endif #include +#include #ifdef __APPLE__ #define __BYTE_ORDER BYTE_ORDER @@ -47,19 +48,6 @@ #define is_saturated(x) (x == (typeof(x))-1) #define zero_or_saturated(x) ((x == 0) || is_saturated(x)) -#define spaceship_cmp(a, b) (((a) > (b)) - ((a) < (b))) - -/* Use to ignore intentional unsigned under- and overflows while running under UBSAN. */ -#if defined(__clang__) && defined(__clang_major__) && (__clang_major__ >= 4) -#if (__clang_major__ >= 12) -#define ignore_unsigned_overflow_ __attribute__((no_sanitize("unsigned-integer-overflow", "unsigned-shift-base"))) -#else -#define ignore_unsigned_overflow_ __attribute__((no_sanitize("unsigned-integer-overflow"))) -#endif -#else -#define ignore_unsigned_overflow_ -#endif - /* Policy compatibility information. */ struct policydb_compat_info { unsigned int type; @@ -69,12 +57,12 @@ struct policydb_compat_info { unsigned int target_platform; }; -extern const struct policydb_compat_info *policydb_lookup_compat(unsigned int version, - unsigned int type, - unsigned int target_platform); +extern struct policydb_compat_info *policydb_lookup_compat(unsigned int version, + unsigned int type, + unsigned int target_platform); /* Reading from a policy "file". */ -extern int next_entry(void *buf, struct policy_file *fp, size_t bytes); +extern int next_entry(void *buf, struct policy_file *fp, size_t bytes) hidden; extern size_t put_entry(const void *ptr, size_t size, size_t n, - struct policy_file *fp); -extern int str_read(char **strp, struct policy_file *fp, size_t len); + struct policy_file *fp) hidden; +extern int str_read(char **strp, struct policy_file *fp, size_t len) hidden; diff --git a/libsepol/src/roles.c b/libsepol/src/roles.c new file mode 100644 index 00000000..4540cee8 --- /dev/null +++ b/libsepol/src/roles.c @@ -0,0 +1,53 @@ +#include +#include + +#include +#include + +#include "debug.h" +#include "handle.h" + +/* Check if a role exists */ +int sepol_role_exists(sepol_handle_t * handle __attribute__ ((unused)), + sepol_policydb_t * p, const char *role, int *response) +{ + + policydb_t *policydb = &p->p; + *response = (hashtab_search(policydb->p_roles.table, role) != NULL); + + return STATUS_SUCCESS; +} + +/* Fill an array with all valid roles */ +int sepol_role_list(sepol_handle_t * handle, + sepol_policydb_t * p, char ***roles, unsigned int *nroles) +{ + + policydb_t *policydb = &p->p; + unsigned int tmp_nroles = policydb->p_roles.nprim; + char **tmp_roles = (char **)malloc(tmp_nroles * sizeof(char *)); + char **ptr; + unsigned int i; + if (!tmp_roles) + goto omem; + + for (i = 0; i < tmp_nroles; i++) { + tmp_roles[i] = strdup(policydb->p_role_val_to_name[i]); + if (!tmp_roles[i]) + goto omem; + } + + *nroles = tmp_nroles; + *roles = tmp_roles; + + return STATUS_SUCCESS; + + omem: + ERR(handle, "out of memory, could not list roles"); + + ptr = tmp_roles; + while (ptr && *ptr) + free(*ptr++); + free(tmp_roles); + return STATUS_ERR; +} diff --git a/libsepol/src/services.c b/libsepol/src/services.c index 673b3971..3758436f 100644 --- a/libsepol/src/services.c +++ b/libsepol/src/services.c @@ -1,3 +1,4 @@ + /* * Author : Stephen Smalley, */ @@ -58,16 +59,18 @@ #include #include #include +#include #include -#include #include "debug.h" #include "private.h" #include "context.h" +#include "av_permissions.h" +#include "dso.h" #include "mls.h" -#include "flask.h" #define BUG() do { ERR(NULL, "Badness at %s:%d", __FILE__, __LINE__); } while (0) +#define BUG_ON(x) do { if (x) ERR(NULL, "Badness at %s:%d", __FILE__, __LINE__); } while (0) static int selinux_enforcing = 1; @@ -86,7 +89,7 @@ static int next_stack_entry; static void push(char *expr_ptr) { if (next_stack_entry >= stack_len) { - char **new_stack; + char **new_stack = stack; int new_stack_len; if (stack_len == 0) @@ -118,13 +121,13 @@ static char *pop(void) } /* End Stack services */ -int sepol_set_sidtab(sidtab_t * s) +int hidden sepol_set_sidtab(sidtab_t * s) { sidtab = s; return 0; } -int sepol_set_policydb(policydb_t * p) +int hidden sepol_set_policydb(policydb_t * p) { policydb = p; return 0; @@ -145,7 +148,7 @@ int sepol_set_policydb_from_file(FILE * fp) } if (policydb_read(&mypolicydb, &pf, 0)) { policydb_destroy(&mypolicydb); - ERR(NULL, "can't read binary policy: %m"); + ERR(NULL, "can't read binary policy: %s", strerror(errno)); return -1; } policydb = &mypolicydb; @@ -175,7 +178,7 @@ static int expr_buf_len; static void cat_expr_buf(char *e_buf, const char *string) { int len, new_buf_len; - char *p, *new_buf; + char *p, *new_buf = e_buf; while (1) { p = e_buf + expr_buf_used; @@ -290,19 +293,6 @@ static char *get_class_info(sepol_security_class_t tclass, { constraint_expr_t *e; int mls, state_num; - /* Determine statement type */ - const char *statements[] = { - "constrain ", /* 0 */ - "mlsconstrain ", /* 1 */ - "validatetrans ", /* 2 */ - "mlsvalidatetrans ", /* 3 */ - 0 }; - size_t class_buf_len = 0; - size_t new_class_buf_len; - size_t buf_used; - int len; - char *class_buf = NULL, *p; - char *new_class_buf = NULL; /* Find if MLS statement or not */ mls = 0; @@ -313,18 +303,30 @@ static char *get_class_info(sepol_security_class_t tclass, } } + /* Determine statement type */ + const char *statements[] = { + "constrain ", /* 0 */ + "mlsconstrain ", /* 1 */ + "validatetrans ", /* 2 */ + "mlsvalidatetrans ", /* 3 */ + 0 }; + if (xcontext == NULL) state_num = mls + 0; else state_num = mls + 2; + int class_buf_len = 0; + int new_class_buf_len; + int len, buf_used; + char *class_buf = NULL, *p; + char *new_class_buf = NULL; + while (1) { new_class_buf_len = class_buf_len + EXPR_BUF_SIZE; new_class_buf = realloc(class_buf, new_class_buf_len); - if (!new_class_buf) { - free(class_buf); - return NULL; - } + if (!new_class_buf) + return NULL; class_buf_len = new_class_buf_len; class_buf = new_class_buf; buf_used = 0; @@ -332,7 +334,7 @@ static char *get_class_info(sepol_security_class_t tclass, /* Add statement type */ len = snprintf(p, class_buf_len - buf_used, "%s", statements[state_num]); - if (len < 0 || (size_t)len >= class_buf_len - buf_used) + if (len < 0 || len >= class_buf_len - buf_used) continue; /* Add class entry */ @@ -340,7 +342,7 @@ static char *get_class_info(sepol_security_class_t tclass, buf_used += len; len = snprintf(p, class_buf_len - buf_used, "%s ", policydb->p_class_val_to_name[tclass - 1]); - if (len < 0 || (size_t)len >= class_buf_len - buf_used) + if (len < 0 || len >= class_buf_len - buf_used) continue; /* Add permission entries (validatetrans does not have perms) */ @@ -353,7 +355,7 @@ static char *get_class_info(sepol_security_class_t tclass, } else { len = snprintf(p, class_buf_len - buf_used, "("); } - if (len < 0 || (size_t)len >= class_buf_len - buf_used) + if (len < 0 || len >= class_buf_len - buf_used) continue; break; } @@ -406,7 +408,7 @@ static int constraint_expr_eval_reason(context_struct_t *scontext, #define TARGET 2 #define XTARGET 3 - int s_t_x_num; + int s_t_x_num = SOURCE; /* Set 0 = fail, u = CEXPR_USER, r = CEXPR_ROLE, t = CEXPR_TYPE */ int u_r_t = 0; @@ -415,8 +417,6 @@ static int constraint_expr_eval_reason(context_struct_t *scontext, char *tgt = NULL; int rc = 0, x; char *class_buf = NULL; - int expr_list_len = 0; - int expr_count; /* * The array of expression answer buffer pointers and counter. @@ -424,11 +424,6 @@ static int constraint_expr_eval_reason(context_struct_t *scontext, char **answer_list = NULL; int answer_counter = 0; - /* The pop operands */ - char *a; - char *b; - int a_len, b_len; - class_buf = get_class_info(tclass, constraint, xcontext); if (!class_buf) { ERR(NULL, "failed to allocate class buffer"); @@ -436,12 +431,13 @@ static int constraint_expr_eval_reason(context_struct_t *scontext, } /* Original function but with buffer support */ + int expr_list_len = 0; expr_counter = 0; expr_list = NULL; for (e = constraint->expr; e; e = e->next) { /* Allocate a stack to hold expression buffer entries */ if (expr_counter >= expr_list_len) { - char **new_expr_list; + char **new_expr_list = expr_list; int new_expr_list_len; if (expr_list_len == 0) @@ -476,30 +472,18 @@ static int constraint_expr_eval_reason(context_struct_t *scontext, /* Now process each expression of the constraint */ switch (e->expr_type) { case CEXPR_NOT: - if (sp < 0) { - BUG(); - rc = -EINVAL; - goto out; - } + BUG_ON(sp < 0); s[sp] = !s[sp]; cat_expr_buf(expr_list[expr_counter], "not"); break; case CEXPR_AND: - if (sp < 1) { - BUG(); - rc = -EINVAL; - goto out; - } + BUG_ON(sp < 1); sp--; s[sp] &= s[sp + 1]; cat_expr_buf(expr_list[expr_counter], "and"); break; case CEXPR_OR: - if (sp < 1) { - BUG(); - rc = -EINVAL; - goto out; - } + BUG_ON(sp < 1); sp--; s[sp] |= s[sp + 1]; cat_expr_buf(expr_list[expr_counter], "or"); @@ -705,7 +689,7 @@ mls_ops: * expr_list malloc's. Normally they are released by the RPN to * infix code. */ - expr_count = expr_counter; + int expr_count = expr_counter; expr_counter = 0; /* @@ -719,6 +703,11 @@ mls_ops: goto out; } + /* The pop operands */ + char *a; + char *b; + int a_len, b_len; + /* Convert constraint from RPN to infix notation. */ for (x = 0; x != expr_count; x++) { if (strncmp(expr_list[x], "and", 3) == 0 || strncmp(expr_list[x], @@ -777,6 +766,14 @@ mls_ops: xcontext ? "Validatetrans" : "Constraint", s[0] ? "GRANTED" : "DENIED"); + int len, new_buf_len; + char *p, **new_buf = r_buf; + /* + * These contain the constraint components that are added to the + * callers reason buffer. + */ + const char *buffers[] = { class_buf, a, "); ", tmp_buf, 0 }; + /* * This will add the constraints to the callers reason buffer (who is * responsible for freeing the memory). It will handle any realloc's @@ -787,14 +784,6 @@ mls_ops: if (r_buf && ((s[0] == 0) || ((s[0] == 1 && (flags & SHOW_GRANTED) == SHOW_GRANTED)))) { - int len, new_buf_len; - char *p, **new_buf = r_buf; - /* - * These contain the constraint components that are added to the - * callers reason buffer. - */ - const char *buffers[] = { class_buf, a, "); ", tmp_buf, 0 }; - for (x = 0; buffers[x] != NULL; x++) { while (1) { p = *r_buf + reason_buf_used; @@ -1000,8 +989,8 @@ static int context_struct_compute_av(context_struct_t * scontext, * role is changing, then check the (current_role, new_role) * pair. */ - if (tclass == policydb->process_class && - (avd->allowed & policydb->process_trans_dyntrans) && + if (tclass == SECCLASS_PROCESS && + (avd->allowed & (PROCESS__TRANSITION | PROCESS__DYNTRANSITION)) && scontext->role != tcontext->role) { for (ra = policydb->role_allow; ra; ra = ra->next) { if (scontext->role == ra->role && @@ -1009,7 +998,8 @@ static int context_struct_compute_av(context_struct_t * scontext, break; } if (!ra) - avd->allowed &= ~policydb->process_trans_dyntrans; + avd->allowed = (avd->allowed) & ~(PROCESS__TRANSITION | + PROCESS__DYNTRANSITION); } if (requested & ~avd->allowed) { @@ -1023,11 +1013,58 @@ static int context_struct_compute_av(context_struct_t * scontext, return 0; } +int hidden sepol_validate_transition(sepol_security_id_t oldsid, + sepol_security_id_t newsid, + sepol_security_id_t tasksid, + sepol_security_class_t tclass) +{ + context_struct_t *ocontext; + context_struct_t *ncontext; + context_struct_t *tcontext; + class_datum_t *tclass_datum; + constraint_node_t *constraint; + + if (!tclass || tclass > policydb->p_classes.nprim) { + ERR(NULL, "unrecognized class %d", tclass); + return -EINVAL; + } + tclass_datum = policydb->class_val_to_struct[tclass - 1]; + + ocontext = sepol_sidtab_search(sidtab, oldsid); + if (!ocontext) { + ERR(NULL, "unrecognized SID %d", oldsid); + return -EINVAL; + } + + ncontext = sepol_sidtab_search(sidtab, newsid); + if (!ncontext) { + ERR(NULL, "unrecognized SID %d", newsid); + return -EINVAL; + } + + tcontext = sepol_sidtab_search(sidtab, tasksid); + if (!tcontext) { + ERR(NULL, "unrecognized SID %d", tasksid); + return -EINVAL; + } + + constraint = tclass_datum->validatetrans; + while (constraint) { + if (!constraint_expr_eval_reason(ocontext, ncontext, tcontext, + 0, constraint, NULL, 0)) { + return -EPERM; + } + constraint = constraint->next; + } + + return 0; +} + /* * sepol_validate_transition_reason_buffer - the reason buffer is realloc'd * in the constraint_expr_eval_reason() function. */ -int sepol_validate_transition_reason_buffer(sepol_security_id_t oldsid, +int hidden sepol_validate_transition_reason_buffer(sepol_security_id_t oldsid, sepol_security_id_t newsid, sepol_security_id_t tasksid, sepol_security_class_t tclass, @@ -1085,7 +1122,7 @@ int sepol_validate_transition_reason_buffer(sepol_security_id_t oldsid, return 0; } -int sepol_compute_av_reason(sepol_security_id_t ssid, +int hidden sepol_compute_av_reason(sepol_security_id_t ssid, sepol_security_id_t tsid, sepol_security_class_t tclass, sepol_access_vector_t requested, @@ -1119,7 +1156,7 @@ int sepol_compute_av_reason(sepol_security_id_t ssid, * REASON_BUF_SIZE. If the buffer size is exceeded, then it is realloc'd * in the constraint_expr_eval_reason() function. */ -int sepol_compute_av_reason_buffer(sepol_security_id_t ssid, +int hidden sepol_compute_av_reason_buffer(sepol_security_id_t ssid, sepol_security_id_t tsid, sepol_security_class_t tclass, sepol_access_vector_t requested, @@ -1161,7 +1198,7 @@ out: return rc; } -int sepol_compute_av(sepol_security_id_t ssid, +int hidden sepol_compute_av(sepol_security_id_t ssid, sepol_security_id_t tsid, sepol_security_class_t tclass, sepol_access_vector_t requested, @@ -1176,13 +1213,13 @@ int sepol_compute_av(sepol_security_id_t ssid, * Return a class ID associated with the class string specified by * class_name. */ -int sepol_string_to_security_class(const char *class_name, +int hidden sepol_string_to_security_class(const char *class_name, sepol_security_class_t *tclass) { class_datum_t *tclass_datum; tclass_datum = hashtab_search(policydb->p_classes.table, - class_name); + (hashtab_key_t) class_name); if (!tclass_datum) { ERR(NULL, "unrecognized class %s", class_name); return STATUS_ERR; @@ -1195,7 +1232,7 @@ int sepol_string_to_security_class(const char *class_name, * Return access vector bit associated with the class ID and permission * string. */ -int sepol_string_to_av_perm(sepol_security_class_t tclass, +int hidden sepol_string_to_av_perm(sepol_security_class_t tclass, const char *perm_name, sepol_access_vector_t *av) { @@ -1211,7 +1248,7 @@ int sepol_string_to_av_perm(sepol_security_class_t tclass, /* Check for unique perms then the common ones (if any) */ perm_datum = (perm_datum_t *) hashtab_search(tclass_datum->permissions.table, - perm_name); + (hashtab_key_t)perm_name); if (perm_datum != NULL) { *av = 0x1 << (perm_datum->s.value - 1); return STATUS_SUCCESS; @@ -1222,7 +1259,7 @@ int sepol_string_to_av_perm(sepol_security_class_t tclass, perm_datum = (perm_datum_t *) hashtab_search(tclass_datum->comdatum->permissions.table, - perm_name); + (hashtab_key_t)perm_name); if (perm_datum != NULL) { *av = 0x1 << (perm_datum->s.value - 1); @@ -1240,7 +1277,7 @@ out: * to point to this string and set `*scontext_len' to * the length of the string. */ -int sepol_sid_to_context(sepol_security_id_t sid, +int hidden sepol_sid_to_context(sepol_security_id_t sid, sepol_security_context_t * scontext, size_t * scontext_len) { @@ -1263,7 +1300,7 @@ int sepol_sid_to_context(sepol_security_id_t sid, * Return a SID associated with the security context that * has the string representation specified by `scontext'. */ -int sepol_context_to_sid(const sepol_security_context_t scontext, +int hidden sepol_context_to_sid(const sepol_security_context_t scontext, size_t scontext_len, sepol_security_id_t * sid) { @@ -1324,7 +1361,6 @@ static int sepol_compute_sid(sepol_security_id_t ssid, sepol_security_class_t tclass, uint32_t specified, sepol_security_id_t * out_sid) { - struct class_datum *cladatum = NULL; context_struct_t *scontext = 0, *tcontext = 0, newcontext; struct role_trans *roletr = 0; avtab_key_t avkey; @@ -1345,22 +1381,14 @@ static int sepol_compute_sid(sepol_security_id_t ssid, goto out; } - if (tclass && tclass <= policydb->p_classes.nprim) - cladatum = policydb->class_val_to_struct[tclass - 1]; - context_init(&newcontext); /* Set the user identity. */ switch (specified) { case AVTAB_TRANSITION: case AVTAB_CHANGE: - if (cladatum && cladatum->default_user == DEFAULT_TARGET) { - newcontext.user = tcontext->user; - } else { - /* notice this gets both DEFAULT_SOURCE and unset */ - /* Use the process user identity. */ - newcontext.user = scontext->user; - } + /* Use the process user identity. */ + newcontext.user = scontext->user; break; case AVTAB_MEMBER: /* Use the related object owner. */ @@ -1368,31 +1396,18 @@ static int sepol_compute_sid(sepol_security_id_t ssid, break; } - /* Set the role to default values. */ - if (cladatum && cladatum->default_role == DEFAULT_SOURCE) { + /* Set the role and type to default values. */ + switch (tclass) { + case SECCLASS_PROCESS: + /* Use the current role and type of process. */ newcontext.role = scontext->role; - } else if (cladatum && cladatum->default_role == DEFAULT_TARGET) { - newcontext.role = tcontext->role; - } else { - if (tclass == policydb->process_class) - newcontext.role = scontext->role; - else - newcontext.role = OBJECT_R_VAL; - } - - /* Set the type to default values. */ - if (cladatum && cladatum->default_type == DEFAULT_SOURCE) { newcontext.type = scontext->type; - } else if (cladatum && cladatum->default_type == DEFAULT_TARGET) { + break; + default: + /* Use the well-defined object role. */ + newcontext.role = OBJECT_R_VAL; + /* Use the type of the related object. */ newcontext.type = tcontext->type; - } else { - if (tclass == policydb->process_class) { - /* Use the type of process. */ - newcontext.type = scontext->type; - } else { - /* Use the type of the related object. */ - newcontext.type = tcontext->type; - } } /* Look for a type transition/member/change rule. */ @@ -1420,18 +1435,23 @@ static int sepol_compute_sid(sepol_security_id_t ssid, } /* Check for class-specific changes. */ - if (specified & AVTAB_TRANSITION) { - /* Look for a role transition rule. */ - for (roletr = policydb->role_tr; roletr; - roletr = roletr->next) { - if (roletr->role == scontext->role && - roletr->type == tcontext->type && - roletr->tclass == tclass) { - /* Use the role transition rule. */ - newcontext.role = roletr->new_role; - break; + switch (tclass) { + case SECCLASS_PROCESS: + if (specified & AVTAB_TRANSITION) { + /* Look for a role transition rule. */ + for (roletr = policydb->role_tr; roletr; + roletr = roletr->next) { + if (roletr->role == scontext->role && + roletr->type == tcontext->type) { + /* Use the role transition rule. */ + newcontext.role = roletr->new_role; + break; + } } } + break; + default: + break; } /* Set the MLS attributes. @@ -1460,7 +1480,7 @@ static int sepol_compute_sid(sepol_security_id_t ssid, * Compute a SID to use for labeling a new object in the * class `tclass' based on a SID pair. */ -int sepol_transition_sid(sepol_security_id_t ssid, +int hidden sepol_transition_sid(sepol_security_id_t ssid, sepol_security_id_t tsid, sepol_security_class_t tclass, sepol_security_id_t * out_sid) @@ -1473,7 +1493,7 @@ int sepol_transition_sid(sepol_security_id_t ssid, * polyinstantiated object of class `tclass' based on * a SID pair. */ -int sepol_member_sid(sepol_security_id_t ssid, +int hidden sepol_member_sid(sepol_security_id_t ssid, sepol_security_id_t tsid, sepol_security_class_t tclass, sepol_security_id_t * out_sid) @@ -1485,7 +1505,7 @@ int sepol_member_sid(sepol_security_id_t ssid, * Compute a SID to use for relabeling an object in the * class `tclass' based on a SID pair. */ -int sepol_change_sid(sepol_security_id_t ssid, +int hidden sepol_change_sid(sepol_security_id_t ssid, sepol_security_id_t tsid, sepol_security_class_t tclass, sepol_security_id_t * out_sid) @@ -1671,7 +1691,7 @@ static int convert_context(sepol_security_id_t key __attribute__ ((unused)), } /* Reading from a policy "file". */ -int next_entry(void *buf, struct policy_file *fp, size_t bytes) +int hidden next_entry(void *buf, struct policy_file *fp, size_t bytes) { size_t nread; @@ -1698,7 +1718,7 @@ int next_entry(void *buf, struct policy_file *fp, size_t bytes) return 0; } -size_t put_entry(const void *ptr, size_t size, size_t n, +size_t hidden put_entry(const void *ptr, size_t size, size_t n, struct policy_file *fp) { size_t bytes = size * n; @@ -1733,7 +1753,7 @@ size_t put_entry(const void *ptr, size_t size, size_t n, * 0 - Success * -1 - Failure with errno set */ -int str_read(char **strp, struct policy_file *fp, size_t len) +int hidden str_read(char **strp, struct policy_file *fp, size_t len) { int rc; char *str; @@ -1776,7 +1796,7 @@ int str_read(char **strp, struct policy_file *fp, size_t len) * * Reset the access vector cache. */ -int sepol_load_policy(void *data, size_t len) +int hidden sepol_load_policy(void *data, size_t len) { policydb_t oldpolicydb, newpolicydb; sidtab_t oldsidtab, newsidtab; @@ -1849,7 +1869,7 @@ int sepol_load_policy(void *data, size_t len) * the file system and the `file_sid' SID is returned * for all files within that file system. */ -int sepol_fs_sid(char *name, +int hidden sepol_fs_sid(char *name, sepol_security_id_t * fs_sid, sepol_security_id_t * file_sid) { @@ -1891,7 +1911,7 @@ int sepol_fs_sid(char *name, * Return the SID of the ibpkey specified by * `subnet prefix', and `pkey number'. */ -int sepol_ibpkey_sid(uint64_t subnet_prefix, +int hidden sepol_ibpkey_sid(uint64_t subnet_prefix, uint16_t pkey, sepol_security_id_t *out_sid) { ocontext_t *c; @@ -1927,7 +1947,7 @@ out: * Return the SID of the subnet management interface specified by * `device name', and `port'. */ -int sepol_ibendport_sid(char *dev_name, +int hidden sepol_ibendport_sid(char *dev_name, uint8_t port, sepol_security_id_t *out_sid) { @@ -1964,7 +1984,7 @@ out: * Return the SID of the port specified by * `domain', `type', `protocol', and `port'. */ -int sepol_port_sid(uint16_t domain __attribute__ ((unused)), +int hidden sepol_port_sid(uint16_t domain __attribute__ ((unused)), uint16_t type __attribute__ ((unused)), uint8_t protocol, uint16_t port, sepol_security_id_t * out_sid) @@ -2004,7 +2024,7 @@ int sepol_port_sid(uint16_t domain __attribute__ ((unused)), * the default SID for messages received on the * interface. */ -int sepol_netif_sid(char *name, +int hidden sepol_netif_sid(char *name, sepol_security_id_t * if_sid, sepol_security_id_t * msg_sid) { @@ -2062,7 +2082,7 @@ static int match_ipv6_addrmask(uint32_t * input, uint32_t * addr, * in bytes and `domain' is the communications domain or * address family in which the address should be interpreted. */ -int sepol_node_sid(uint16_t domain, +int hidden sepol_node_sid(uint16_t domain, void *addrp, size_t addrlen, sepol_security_id_t * out_sid) { @@ -2135,7 +2155,7 @@ int sepol_node_sid(uint16_t domain, */ #define SIDS_NEL 25 -int sepol_get_user_sids(sepol_security_id_t fromsid, +int hidden sepol_get_user_sids(sepol_security_id_t fromsid, char *username, sepol_security_id_t ** sids, uint32_t * nel) { @@ -2183,10 +2203,10 @@ int sepol_get_user_sids(sepol_security_id_t fromsid, continue; rc = context_struct_compute_av(fromcon, &usercon, - policydb->process_class, - policydb->process_trans, + SECCLASS_PROCESS, + PROCESS__TRANSITION, &avd, &reason, NULL, 0); - if (rc || !(avd.allowed & policydb->process_trans)) + if (rc || !(avd.allowed & PROCESS__TRANSITION)) continue; rc = sepol_sidtab_context_to_sid(sidtab, &usercon, &sid); @@ -2230,7 +2250,7 @@ int sepol_get_user_sids(sepol_security_id_t fromsid, * that cannot support a persistent label mapping or use another * fixed labeling behavior like transition SIDs or task SIDs. */ -int sepol_genfs_sid(const char *fstype, +int hidden sepol_genfs_sid(const char *fstype, const char *path, sepol_security_class_t sclass, sepol_security_id_t * sid) @@ -2277,7 +2297,7 @@ int sepol_genfs_sid(const char *fstype, return rc; } -int sepol_fs_use(const char *fstype, +int hidden sepol_fs_use(const char *fstype, unsigned int *behavior, sepol_security_id_t * sid) { int rc = 0; @@ -2301,7 +2321,7 @@ int sepol_fs_use(const char *fstype, } *sid = c->sid[0]; } else { - rc = sepol_genfs_sid(fstype, "/", policydb->dir_class, sid); + rc = sepol_genfs_sid(fstype, "/", SECCLASS_DIR, sid); if (rc) { *behavior = SECURITY_FS_USE_NONE; rc = 0; diff --git a/libsepol/src/sidtab.c b/libsepol/src/sidtab.c index 255e0725..23b2e8f3 100644 --- a/libsepol/src/sidtab.c +++ b/libsepol/src/sidtab.c @@ -14,7 +14,7 @@ #include -#include "flask.h" +#include #define SIDTAB_HASH(sid) \ (sid & SIDTAB_HASH_MASK) @@ -84,6 +84,37 @@ int sepol_sidtab_insert(sidtab_t * s, sepol_security_id_t sid, return 0; } +int sepol_sidtab_remove(sidtab_t * s, sepol_security_id_t sid) +{ + int hvalue; + sidtab_node_t *cur, *last; + + if (!s || !s->htable) + return -ENOENT; + + hvalue = SIDTAB_HASH(sid); + last = NULL; + cur = s->htable[hvalue]; + while (cur != NULL && sid > cur->sid) { + last = cur; + cur = cur->next; + } + + if (cur == NULL || sid != cur->sid) + return -ENOENT; + + if (last == NULL) + s->htable[hvalue] = cur->next; + else + last->next = cur->next; + + context_destroy(&cur->context); + + free(cur); + s->nel--; + return 0; +} + context_struct_t *sepol_sidtab_search(sidtab_t * s, sepol_security_id_t sid) { int hvalue; diff --git a/libsepol/src/symtab.c b/libsepol/src/symtab.c index a6061851..9a417ca2 100644 --- a/libsepol/src/symtab.c +++ b/libsepol/src/symtab.c @@ -8,13 +8,9 @@ */ #include - -#include "private.h" - #include #include -ignore_unsigned_overflow_ static unsigned int symhash(hashtab_t h, const_hashtab_key_t key) { const char *p, *keyp; diff --git a/libsepol/src/user_internal.h b/libsepol/src/user_internal.h index f5b22b02..7523b7d5 100644 --- a/libsepol/src/user_internal.h +++ b/libsepol/src/user_internal.h @@ -3,5 +3,18 @@ #include #include +#include "dso.h" +hidden_proto(sepol_user_add_role) + hidden_proto(sepol_user_create) + hidden_proto(sepol_user_free) + hidden_proto(sepol_user_get_mlslevel) + hidden_proto(sepol_user_get_mlsrange) + hidden_proto(sepol_user_get_roles) + hidden_proto(sepol_user_has_role) + hidden_proto(sepol_user_key_create) + hidden_proto(sepol_user_key_unpack) + hidden_proto(sepol_user_set_mlslevel) + hidden_proto(sepol_user_set_mlsrange) + hidden_proto(sepol_user_set_name) #endif diff --git a/libsepol/src/user_record.c b/libsepol/src/user_record.c index ac520060..fa95f2d1 100644 --- a/libsepol/src/user_record.c +++ b/libsepol/src/user_record.c @@ -51,6 +51,7 @@ int sepol_user_key_create(sepol_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(sepol_user_key_create) void sepol_user_key_unpack(const sepol_user_key_t * key, const char **name) { @@ -58,6 +59,7 @@ void sepol_user_key_unpack(const sepol_user_key_t * key, const char **name) *name = key->name; } +hidden_def(sepol_user_key_unpack) int sepol_user_key_extract(sepol_handle_t * handle, const sepol_user_t * user, @@ -113,6 +115,7 @@ int sepol_user_set_name(sepol_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(sepol_user_set_name) /* MLS */ const char *sepol_user_get_mlslevel(const sepol_user_t * user) @@ -121,6 +124,7 @@ const char *sepol_user_get_mlslevel(const sepol_user_t * user) return user->mls_level; } +hidden_def(sepol_user_get_mlslevel) int sepol_user_set_mlslevel(sepol_handle_t * handle, sepol_user_t * user, const char *mls_level) @@ -137,6 +141,7 @@ int sepol_user_set_mlslevel(sepol_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(sepol_user_set_mlslevel) const char *sepol_user_get_mlsrange(const sepol_user_t * user) { @@ -144,6 +149,7 @@ const char *sepol_user_get_mlsrange(const sepol_user_t * user) return user->mls_range; } +hidden_def(sepol_user_get_mlsrange) int sepol_user_set_mlsrange(sepol_handle_t * handle, sepol_user_t * user, const char *mls_range) @@ -160,6 +166,7 @@ int sepol_user_set_mlsrange(sepol_handle_t * handle, return STATUS_SUCCESS; } +hidden_def(sepol_user_set_mlsrange) /* Roles */ int sepol_user_get_num_roles(const sepol_user_t * user) @@ -200,6 +207,7 @@ int sepol_user_add_role(sepol_handle_t * handle, return STATUS_ERR; } +hidden_def(sepol_user_add_role) int sepol_user_has_role(const sepol_user_t * user, const char *role) { @@ -212,6 +220,7 @@ int sepol_user_has_role(const sepol_user_t * user, const char *role) return 0; } +hidden_def(sepol_user_has_role) int sepol_user_set_roles(sepol_handle_t * handle, sepol_user_t * user, @@ -283,6 +292,7 @@ int sepol_user_get_roles(sepol_handle_t * handle, return STATUS_ERR; } +hidden_def(sepol_user_get_roles) void sepol_user_del_role(sepol_user_t * user, const char *role) { @@ -320,6 +330,7 @@ int sepol_user_create(sepol_handle_t * handle, sepol_user_t ** user_ptr) return STATUS_SUCCESS; } +hidden_def(sepol_user_create) /* Deep copy clone */ int sepol_user_clone(sepol_handle_t * handle, @@ -375,3 +386,4 @@ void sepol_user_free(sepol_user_t * user) free(user); } +hidden_def(sepol_user_free) diff --git a/libsepol/src/util.c b/libsepol/src/util.c index a47cae87..a4008882 100644 --- a/libsepol/src/util.c +++ b/libsepol/src/util.c @@ -27,6 +27,7 @@ #include #include #include +#include struct val_to_name { unsigned int val; @@ -129,9 +130,9 @@ char *sepol_extended_perms_to_string(avtab_extended_perms_t *xperms) unsigned int bit; unsigned int in_range = 0; static char xpermsbuf[2048]; + xpermsbuf[0] = '\0'; char *p; int len, xpermslen = 0; - xpermsbuf[0] = '\0'; p = xpermsbuf; if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION) @@ -249,7 +250,7 @@ static inline int tokenize_str(char delim, char **str, char **ptr, size_t *len) * contain the remaining content of line_buf. If the delimiter is any whitespace * character, then all whitespace will be squashed. */ -int tokenize(char *line_buf, char delim, int num_args, ...) +int hidden tokenize(char *line_buf, char delim, int num_args, ...) { char **arg, *buf_p; int rc, items; diff --git a/libsepol/src/write.c b/libsepol/src/write.c index b09551f7..cffd75e7 100644 --- a/libsepol/src/write.c +++ b/libsepol/src/write.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "debug.h" #include "private.h" @@ -513,7 +514,7 @@ static int role_trans_write(policydb_t *p, struct policy_file *fp) nel = 0; for (tr = r; tr; tr = tr->next) - if(new_roletr || tr->tclass == p->process_class) + if(new_roletr || tr->tclass == SECCLASS_PROCESS) nel++; buf[0] = cpu_to_le32(nel); @@ -521,7 +522,7 @@ static int role_trans_write(policydb_t *p, struct policy_file *fp) if (items != 1) return POLICYDB_ERROR; for (tr = r; tr; tr = tr->next) { - if (!new_roletr && tr->tclass != p->process_class) { + if (!new_roletr && tr->tclass != SECCLASS_PROCESS) { if (!warning_issued) WARN(fp->handle, "Discarding role_transition " "rules for security classes other than " @@ -569,48 +570,12 @@ static int role_allow_write(role_allow_t * r, struct policy_file *fp) return POLICYDB_SUCCESS; } -static int filename_write_one_compat(hashtab_key_t key, void *data, void *ptr) +static int filename_write_helper(hashtab_key_t key, void *data, void *ptr) { - uint32_t bit, buf[4]; + uint32_t buf[4]; size_t items, len; - filename_trans_key_t *ft = (filename_trans_key_t *)key; - filename_trans_datum_t *datum = data; - ebitmap_node_t *node; - void *fp = ptr; - - len = strlen(ft->name); - do { - ebitmap_for_each_positive_bit(&datum->stypes, node, bit) { - buf[0] = cpu_to_le32(len); - items = put_entry(buf, sizeof(uint32_t), 1, fp); - if (items != 1) - return POLICYDB_ERROR; - - items = put_entry(ft->name, sizeof(char), len, fp); - if (items != len) - return POLICYDB_ERROR; - - buf[0] = cpu_to_le32(bit + 1); - buf[1] = cpu_to_le32(ft->ttype); - buf[2] = cpu_to_le32(ft->tclass); - buf[3] = cpu_to_le32(datum->otype); - items = put_entry(buf, sizeof(uint32_t), 4, fp); - if (items != 4) - return POLICYDB_ERROR; - } - - datum = datum->next; - } while (datum); - - return 0; -} - -static int filename_write_one(hashtab_key_t key, void *data, void *ptr) -{ - uint32_t buf[3]; - size_t items, len, ndatum; - filename_trans_key_t *ft = (filename_trans_key_t *)key; - filename_trans_datum_t *datum; + struct filename_trans *ft = (struct filename_trans *)key; + struct filename_trans_datum *otype = data; void *fp = ptr; len = strlen(ft->name); @@ -623,62 +588,37 @@ static int filename_write_one(hashtab_key_t key, void *data, void *ptr) if (items != len) return POLICYDB_ERROR; - ndatum = 0; - datum = data; - do { - ndatum++; - datum = datum->next; - } while (datum); - - buf[0] = cpu_to_le32(ft->ttype); - buf[1] = cpu_to_le32(ft->tclass); - buf[2] = cpu_to_le32(ndatum); - items = put_entry(buf, sizeof(uint32_t), 3, fp); - if (items != 3) + buf[0] = cpu_to_le32(ft->stype); + buf[1] = cpu_to_le32(ft->ttype); + buf[2] = cpu_to_le32(ft->tclass); + buf[3] = cpu_to_le32(otype->otype); + items = put_entry(buf, sizeof(uint32_t), 4, fp); + if (items != 4) return POLICYDB_ERROR; - datum = data; - do { - if (ebitmap_write(&datum->stypes, fp)) - return POLICYDB_ERROR; - - buf[0] = cpu_to_le32(datum->otype); - items = put_entry(buf, sizeof(uint32_t), 1, fp); - if (items != 1) - return POLICYDB_ERROR; - - datum = datum->next; - } while (datum); - return 0; } static int filename_trans_write(struct policydb *p, void *fp) { - size_t items; + size_t nel, items; uint32_t buf[1]; int rc; if (p->policyvers < POLICYDB_VERSION_FILENAME_TRANS) return 0; - if (p->policyvers < POLICYDB_VERSION_COMP_FTRANS) { - buf[0] = cpu_to_le32(p->filename_trans_count); - items = put_entry(buf, sizeof(uint32_t), 1, fp); - if (items != 1) - return POLICYDB_ERROR; + nel = p->filename_trans->nel; + buf[0] = cpu_to_le32(nel); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; - rc = hashtab_map(p->filename_trans, filename_write_one_compat, - fp); - } else { - buf[0] = cpu_to_le32(p->filename_trans->nel); - items = put_entry(buf, sizeof(uint32_t), 1, fp); - if (items != 1) - return POLICYDB_ERROR; + rc = hashtab_map(p->filename_trans, filename_write_helper, fp); + if (rc) + return rc; - rc = hashtab_map(p->filename_trans, filename_write_one, fp); - } - return rc; + return 0; } static int role_set_write(role_set_t * x, struct policy_file *fp) @@ -1345,7 +1285,7 @@ static int (*write_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum, common_write, class_write, role_write, type_write, user_write, cond_write_bool, sens_write, cat_write,}; -static int ocontext_write_xen(const struct policydb_compat_info *info, policydb_t *p, +static int ocontext_write_xen(struct policydb_compat_info *info, policydb_t *p, struct policy_file *fp) { unsigned int i, j; @@ -1453,7 +1393,7 @@ static int ocontext_write_xen(const struct policydb_compat_info *info, policydb_ return POLICYDB_SUCCESS; } -static int ocontext_write_selinux(const struct policydb_compat_info *info, +static int ocontext_write_selinux(struct policydb_compat_info *info, policydb_t *p, struct policy_file *fp) { unsigned int i, j; @@ -1583,7 +1523,7 @@ static int ocontext_write_selinux(const struct policydb_compat_info *info, return POLICYDB_SUCCESS; } -static int ocontext_write(const struct policydb_compat_info *info, policydb_t * p, +static int ocontext_write(struct policydb_compat_info *info, policydb_t * p, struct policy_file *fp) { int rc = POLICYDB_ERROR; @@ -1652,7 +1592,6 @@ struct rangetrans_write_args { size_t nel; int new_rangetr; struct policy_file *fp; - struct policydb *p; }; static int rangetrans_count(hashtab_key_t key, @@ -1661,12 +1600,11 @@ static int rangetrans_count(hashtab_key_t key, { struct range_trans *rt = (struct range_trans *)key; struct rangetrans_write_args *args = ptr; - struct policydb *p = args->p; /* all range_transitions are written for the new format, only process related range_transitions are written for the old format, so count accordingly */ - if (args->new_rangetr || rt->target_class == p->process_class) + if (args->new_rangetr || rt->target_class == SECCLASS_PROCESS) args->nel++; return 0; } @@ -1678,13 +1616,12 @@ static int range_write_helper(hashtab_key_t key, void *data, void *ptr) struct mls_range *r = data; struct rangetrans_write_args *args = ptr; struct policy_file *fp = args->fp; - struct policydb *p = args->p; int new_rangetr = args->new_rangetr; size_t items; static int warning_issued = 0; int rc; - if (!new_rangetr && rt->target_class != p->process_class) { + if (!new_rangetr && rt->target_class != SECCLASS_PROCESS) { if (!warning_issued) WARN(fp->handle, "Discarding range_transition " "rules for security classes other than " @@ -1723,7 +1660,6 @@ static int range_write(policydb_t * p, struct policy_file *fp) args.nel = 0; args.new_rangetr = new_rangetr; args.fp = fp; - args.p = p; rc = hashtab_map(p->range_tr, rangetrans_count, &args); if (rc) return rc; @@ -1848,18 +1784,13 @@ static int avrule_write_list(policydb_t *p, avrule_t * avrules, return POLICYDB_SUCCESS; } -static int only_process(ebitmap_t *in, struct policydb *p) +static int only_process(ebitmap_t *in) { - unsigned int i, value; + unsigned int i; ebitmap_node_t *node; - if (!p->process_class) - return 0; - - value = p->process_class - 1; - ebitmap_for_each_positive_bit(in, node, i) { - if (i != value) + if (i != SECCLASS_PROCESS - 1) return 0; } return 1; @@ -1876,7 +1807,7 @@ static int role_trans_rule_write(policydb_t *p, role_trans_rule_t * t, int new_role = p->policyvers >= MOD_POLICYDB_VERSION_ROLETRANS; for (tr = t; tr; tr = tr->next) - if (new_role || only_process(&tr->classes, p)) + if (new_role || only_process(&tr->classes)) nel++; buf[0] = cpu_to_le32(nel); @@ -1884,7 +1815,7 @@ static int role_trans_rule_write(policydb_t *p, role_trans_rule_t * t, if (items != 1) return POLICYDB_ERROR; for (tr = t; tr; tr = tr->next) { - if (!new_role && !only_process(&tr->classes, p)) { + if (!new_role && !only_process(&tr->classes)) { if (!warned) WARN(fp->handle, "Discarding role_transition " "rules for security classes other than " @@ -2179,7 +2110,7 @@ int policydb_write(policydb_t * p, struct policy_file *fp) unsigned int i, num_syms; uint32_t buf[32], config; size_t items, items2, len; - const struct policydb_compat_info *info; + struct policydb_compat_info *info; struct policy_data pd; const char *policydb_str; diff --git a/libsepol/tests/Makefile b/libsepol/tests/Makefile index fc9bd1a3..e7e305e8 100644 --- a/libsepol/tests/Makefile +++ b/libsepol/tests/Makefile @@ -32,7 +32,7 @@ all: $(EXE) $(policies) policies: $(policies) $(EXE): $(objs) $(parserobjs) $(LIBSEPOL) - $(CC) $(LDFLAGS) $(objs) $(parserobjs) -lcunit $(LIBSEPOL) -o $@ + $(CC) $(LDFLAGS) $(objs) $(parserobjs) -lcunit -lcurses $(LIBSEPOL) -o $@ %.conf.std: $(m4support) %.conf $(M4) $(M4PARAMS) $^ > $@ diff --git a/libsepol/tests/libsepol-tests.c b/libsepol/tests/libsepol-tests.c index dc8fd5ce..544c792d 100644 --- a/libsepol/tests/libsepol-tests.c +++ b/libsepol/tests/libsepol-tests.c @@ -36,17 +36,13 @@ int mls; #define DECLARE_SUITE(name) \ - do { \ - suite = CU_add_suite(#name, name##_test_init, name##_test_cleanup); \ - if (NULL == suite) { \ - CU_cleanup_registry(); \ - return CU_get_error(); \ - } \ - if (name##_add_tests(suite)) { \ - CU_cleanup_registry(); \ - return CU_get_error(); \ - } \ - } while (0) + suite = CU_add_suite(#name, name##_test_init, name##_test_cleanup); \ + if (NULL == suite) { \ + CU_cleanup_registry(); \ + return CU_get_error(); } \ + if (name##_add_tests(suite)) { \ + CU_cleanup_registry(); \ + return CU_get_error(); } static void usage(char *progname) { diff --git a/mcstrans/VERSION b/mcstrans/VERSION index e6852d8a..9f55b2cc 100644 --- a/mcstrans/VERSION +++ b/mcstrans/VERSION @@ -1 +1 @@ -3.3-rc1 +3.0 diff --git a/mcstrans/share/util/mlstrans-test b/mcstrans/share/util/mlstrans-test index df34e0e6..085fa82d 100644 --- a/mcstrans/share/util/mlstrans-test +++ b/mcstrans/share/util/mlstrans-test @@ -15,7 +15,7 @@ def untrans(trans, val): errors += 1 else: if verbose: - print("untrans: '%s' -> '%s' == '%s' SUCCESS" % (trans, raw, val)) + print("untrans: %s -> %s != %s SUCCESS" % (trans, raw, val)) def trans(raw, val): @@ -26,7 +26,7 @@ def trans(raw, val): errors += 1 else: if verbose: - print("trans: '%s' -> '%s' == '%s' SUCCESS" % (raw, trans, val)) + print("trans: %s -> %s != %s SUCCESS" % (raw, trans, val)) if len(sys.argv) > 1 and sys.argv[1] == "-v": diff --git a/mcstrans/src/mcscolor.c b/mcstrans/src/mcscolor.c index a3838850..4ee0db50 100644 --- a/mcstrans/src/mcscolor.c +++ b/mcstrans/src/mcscolor.c @@ -44,7 +44,7 @@ static setab_t *clist[N_COLOR]; static setab_t *cend[N_COLOR]; static semnemonic_t *mnemonics; -static char *my_context; +static security_context_t my_context; void finish_context_colors(void) { setab_t *cur, *next; @@ -76,7 +76,7 @@ void finish_context_colors(void) { } static int check_dominance(const char *pattern, const char *raw) { - char *ctx; + security_context_t ctx; context_t con; struct av_decision avd; int rc = -1; @@ -109,7 +109,7 @@ static int check_dominance(const char *pattern, const char *raw) { if (!raw) goto out; - rc = security_compute_av_raw(ctx, raw, context_class, context_contains_perm, &avd); + rc = security_compute_av_raw(ctx, (security_context_t)raw, context_class, context_contains_perm, &avd); if (rc) goto out; @@ -282,7 +282,7 @@ static int parse_components(context_t con, char **components) { /* Look up colors. */ -int raw_color(const char *raw, char **color_str) { +int raw_color(const security_context_t raw, char **color_str) { #define CHARS_PER_COLOR 16 context_t con; uint32_t i, j, mask = 0; diff --git a/mcstrans/src/mcstrans.c b/mcstrans/src/mcstrans.c index e92dfddb..96bdbdff 100644 --- a/mcstrans/src/mcstrans.c +++ b/mcstrans/src/mcstrans.c @@ -7,8 +7,8 @@ int init_translations(void); void finish_context_translations(void); - int trans_context(const char *, char **); - int untrans_context(const char *, char **); + int trans_context(const security_context_t, security_context_t *); + int untrans_context(const security_context_t, security_context_t *); */ @@ -43,7 +43,7 @@ #ifdef DEBUG #define log_debug(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) #else -#define log_debug(fmt, ...) do {} while (0) +#define log_debug(fmt, ...) ; #endif static unsigned int maxbit=0; @@ -888,7 +888,7 @@ init_translations(void) { } char * -extract_range(const char *incon) { +extract_range(const security_context_t incon) { context_t con = context_new(incon); if (!con) { syslog(LOG_ERR, "extract_range context_new(%s) failed: %s", incon, strerror(errno)); @@ -911,7 +911,7 @@ extract_range(const char *incon) { } char * -new_context_str(const char *incon, const char *range) { +new_context_str(const security_context_t incon, const char *range) { char *rcon = NULL; context_t con = context_new(incon); if (!con) { @@ -919,7 +919,6 @@ new_context_str(const char *incon, const char *range) { } context_range_set(con, range); rcon = strdup(context_str(con)); - context_free(con); if (!rcon) { goto exit; } @@ -1490,7 +1489,7 @@ err: } int -trans_context(const char *incon, char **rcon) { +trans_context(const security_context_t incon, security_context_t *rcon) { char *trans = NULL; *rcon = NULL; @@ -1613,7 +1612,7 @@ trans_context(const char *incon, char **rcon) { } int -untrans_context(const char *incon, char **rcon) { +untrans_context(const security_context_t incon, security_context_t *rcon) { char *raw = NULL; *rcon = NULL; diff --git a/mcstrans/src/mcstrans.h b/mcstrans/src/mcstrans.h index e5cda93b..a2f68c18 100644 --- a/mcstrans/src/mcstrans.h +++ b/mcstrans/src/mcstrans.h @@ -4,6 +4,6 @@ extern int init_translations(void); extern void finish_context_translations(void); -extern int trans_context(const char *, char **); -extern int untrans_context(const char *, char **); +extern int trans_context(const security_context_t, security_context_t *); +extern int untrans_context(const security_context_t, security_context_t *); diff --git a/mcstrans/src/mcstrans.service b/mcstrans/src/mcstrans.service index c13cd09a..09529432 100644 --- a/mcstrans/src/mcstrans.service +++ b/mcstrans/src/mcstrans.service @@ -2,9 +2,6 @@ Description=Translates SELinux MCS/MLS labels to human readable form Documentation=man:mcstransd(8) ConditionSecurity=selinux -DefaultDependencies=no -Before=shutdown.target sysinit.target -Conflicts=shutdown.target [Service] ExecStart=/sbin/mcstransd -f diff --git a/mcstrans/src/mcstransd.c b/mcstrans/src/mcstransd.c index 59c152e7..85899493 100644 --- a/mcstrans/src/mcstransd.c +++ b/mcstrans/src/mcstransd.c @@ -40,17 +40,17 @@ //#define log_debug(fmt, ...) syslog(LOG_DEBUG, fmt, __VA_ARGS__) #define log_debug(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) #else -#define log_debug(fmt, ...) do {} while (0) +#define log_debug(fmt, ...) ; #endif extern int init_translations(void); extern void finish_context_translations(void); -extern int trans_context(const char *, char **); -extern int untrans_context(const char *, char **); +extern int trans_context(const security_context_t, security_context_t *); +extern int untrans_context(const security_context_t, security_context_t *); extern int init_colors(void); extern void finish_context_colors(void); -extern int raw_color(const char *, char **); +extern int raw_color(const security_context_t, char **); #define SETRANSD_PATHNAME "/sbin/mcstransd" diff --git a/mcstrans/utils/transcon.c b/mcstrans/utils/transcon.c index 4bf1bd56..f4ded53e 100644 --- a/mcstrans/utils/transcon.c +++ b/mcstrans/utils/transcon.c @@ -14,7 +14,7 @@ static __attribute__((__noreturn__)) void usage(const char *progname) } int main(int argc, char **argv) { - char *scon; + security_context_t scon; if ( argc != 2 ) usage(argv[0]); if (init_translations()==0) { if(trans_context(argv[1],&scon) == 0) { diff --git a/mcstrans/utils/untranscon.c b/mcstrans/utils/untranscon.c index 81668746..85cea294 100644 --- a/mcstrans/utils/untranscon.c +++ b/mcstrans/utils/untranscon.c @@ -13,7 +13,7 @@ static __attribute__((__noreturn__)) void usage(const char *progname) exit(1); } int main(int argc, char **argv) { - char *scon; + security_context_t scon; if ( argc != 2 ) usage(argv[0]); if (init_translations()==0) { if(untrans_context(argv[1],&scon) == 0) { diff --git a/policycoreutils/VERSION b/policycoreutils/VERSION index e6852d8a..9f55b2cc 100644 --- a/policycoreutils/VERSION +++ b/policycoreutils/VERSION @@ -1 +1 @@ -3.3-rc1 +3.0 diff --git a/policycoreutils/man/man5/selinux_config.5 b/policycoreutils/man/man5/selinux_config.5 index 58b42a0e..1ffade15 100644 --- a/policycoreutils/man/man5/selinux_config.5 +++ b/policycoreutils/man/man5/selinux_config.5 @@ -48,7 +48,7 @@ SELinux security policy is enforced. .IP \fIpermissive\fR 4 SELinux security policy is not enforced but logs the warnings (i.e. the action is allowed to proceed). .IP \fIdisabled\fR -No SELinux policy is loaded. This option was used to disable SELinux completely, which is now deprecated. Use the \fBselinux=0\fR kernel boot option instead (see \fBselinux\fR(8)). +SELinux is disabled and no policy is loaded. .RE .sp The entry can be determined using the \fBsestatus\fR(8) command or \fBselinux_getenforcemode\fR(3). diff --git a/policycoreutils/newrole/Makefile b/policycoreutils/newrole/Makefile index 0e7ebce3..73ebd413 100644 --- a/policycoreutils/newrole/Makefile +++ b/policycoreutils/newrole/Makefile @@ -5,9 +5,8 @@ BINDIR ?= $(PREFIX)/bin MANDIR ?= $(PREFIX)/share/man ETCDIR ?= /etc LOCALEDIR = $(DESTDIR)$(PREFIX)/share/locale -INCLUDEDIR ?= $(PREFIX)/include -PAMH ?= $(shell test -f $(INCLUDEDIR)/security/pam_appl.h && echo y) -AUDITH ?= $(shell test -f $(INCLUDEDIR)/libaudit.h && echo y) +PAMH ?= $(shell test -f /usr/include/security/pam_appl.h && echo y) +AUDITH ?= $(shell test -f /usr/include/libaudit.h && echo y) # Enable capabilities to permit newrole to generate audit records. # This will make newrole a setuid root program. # The capabilities used are: CAP_AUDIT_WRITE. diff --git a/policycoreutils/newrole/hashtab.c b/policycoreutils/newrole/hashtab.c index bc502836..24c65c49 100644 --- a/policycoreutils/newrole/hashtab.c +++ b/policycoreutils/newrole/hashtab.c @@ -112,6 +112,48 @@ int hashtab_remove(hashtab_t h, hashtab_key_t key, return HASHTAB_SUCCESS; } +int hashtab_replace(hashtab_t h, hashtab_key_t key, hashtab_datum_t datum, + void (*destroy) (hashtab_key_t k, + hashtab_datum_t d, void *args), void *args) +{ + int hvalue; + hashtab_ptr_t prev, cur, newnode; + + if (!h) + return HASHTAB_OVERFLOW; + + hvalue = h->hash_value(h, key); + prev = NULL; + cur = h->htable[hvalue]; + while (cur != NULL && h->keycmp(h, key, cur->key) > 0) { + prev = cur; + cur = cur->next; + } + + if (cur && (h->keycmp(h, key, cur->key) == 0)) { + if (destroy) + destroy(cur->key, cur->datum, args); + cur->key = key; + cur->datum = datum; + } else { + newnode = (hashtab_ptr_t) malloc(sizeof(hashtab_node_t)); + if (newnode == NULL) + return HASHTAB_OVERFLOW; + memset(newnode, 0, sizeof(struct hashtab_node)); + newnode->key = key; + newnode->datum = datum; + if (prev) { + newnode->next = prev->next; + prev->next = newnode; + } else { + newnode->next = h->htable[hvalue]; + h->htable[hvalue] = newnode; + } + } + + return HASHTAB_SUCCESS; +} + hashtab_datum_t hashtab_search(hashtab_t h, const_hashtab_key_t key) { @@ -178,6 +220,49 @@ int hashtab_map(hashtab_t h, return HASHTAB_SUCCESS; } +void hashtab_map_remove_on_error(hashtab_t h, + int (*apply) (hashtab_key_t k, + hashtab_datum_t d, + void *args), + void (*destroy) (hashtab_key_t k, + hashtab_datum_t d, + void *args), void *args) +{ + unsigned int i; + int ret; + hashtab_ptr_t last, cur, temp; + + if (!h) + return; + + for (i = 0; i < h->size; i++) { + last = NULL; + cur = h->htable[i]; + while (cur != NULL) { + ret = apply(cur->key, cur->datum, args); + if (ret) { + if (last) { + last->next = cur->next; + } else { + h->htable[i] = cur->next; + } + + temp = cur; + cur = cur->next; + if (destroy) + destroy(temp->key, temp->datum, args); + free(temp); + h->nel--; + } else { + last = cur; + cur = cur->next; + } + } + } + + return; +} + void hashtab_hash_eval(hashtab_t h, char *tag) { unsigned int i; diff --git a/policycoreutils/newrole/hashtab.h b/policycoreutils/newrole/hashtab.h index 092b96a9..ad5559ba 100644 --- a/policycoreutils/newrole/hashtab.h +++ b/policycoreutils/newrole/hashtab.h @@ -81,6 +81,20 @@ extern int hashtab_remove(hashtab_t h, hashtab_key_t k, hashtab_datum_t d, void *args), void *args); +/* + Insert or replace the specified (key, datum) pair in the specified + hash table. If an entry for the specified key already exists, + then the specified destroy function is applied to (key,datum,args) + for the entry prior to replacing the entry's contents. + + Returns HASHTAB_OVERFLOW if insufficient space is available or + HASHTAB_SUCCESS otherwise. + */ +extern int hashtab_replace(hashtab_t h, hashtab_key_t k, hashtab_datum_t d, + void (*destroy) (hashtab_key_t k, + hashtab_datum_t d, + void *args), void *args); + /* Searches for the entry with the specified key in the hash table. @@ -110,6 +124,20 @@ extern int hashtab_map(hashtab_t h, hashtab_datum_t d, void *args), void *args); +/* + Same as hashtab_map, except that if apply returns a non-zero status, + then the (key,datum) pair will be removed from the hashtab and the + destroy function will be applied to (key,datum,args). + */ +extern void hashtab_map_remove_on_error(hashtab_t h, + int (*apply) (hashtab_key_t k, + hashtab_datum_t d, + void *args), + void (*destroy) (hashtab_key_t k, + hashtab_datum_t d, + void *args), + void *args); + extern void hashtab_hash_eval(hashtab_t h, char *tag); #endif diff --git a/policycoreutils/newrole/newrole.c b/policycoreutils/newrole/newrole.c index 7c1f062f..e70051b1 100644 --- a/policycoreutils/newrole/newrole.c +++ b/policycoreutils/newrole/newrole.c @@ -96,7 +96,7 @@ #define USAGE_STRING "USAGE: newrole [ -r role ] [ -t type ] [ -l level ] [ -p ] [ -V ] [ -- args ]" #ifdef USE_PAM -#define PAM_SERVICE_CONFIG "/etc/selinux/newrole_pam.conf" +#define PAM_SERVICE_CONFIG "/etc/selinux/newrole_pam.conf"; #endif #define DEFAULT_PATH "/usr/bin:/bin" @@ -643,8 +643,8 @@ static int transition_to_caller_uid() #ifdef AUDIT_LOG_PRIV /* Send audit message */ static -int send_audit_message(int success, const char *old_context, - const char *new_context, const char *ttyn) +int send_audit_message(int success, security_context_t old_context, + security_context_t new_context, const char *ttyn) { char *msg = NULL; int rc; @@ -677,9 +677,9 @@ int send_audit_message(int success, const char *old_context, #else static inline int send_audit_message(int success __attribute__ ((unused)), - const char *old_context + security_context_t old_context __attribute__ ((unused)), - const char *new_context + security_context_t new_context __attribute__ ((unused)), const char *ttyn __attribute__ ((unused))) { @@ -695,14 +695,14 @@ static inline * This function will not fail if it can not relabel the tty when selinux is * in permissive mode. */ -static int relabel_tty(const char *ttyn, const char *new_context, - char **tty_context, - char **new_tty_context) +static int relabel_tty(const char *ttyn, security_context_t new_context, + security_context_t * tty_context, + security_context_t * new_tty_context) { int fd, rc; int enforcing = security_getenforce(); - char *tty_con = NULL; - char *new_tty_con = NULL; + security_context_t tty_con = NULL; + security_context_t new_tty_con = NULL; if (!ttyn) return 0; @@ -775,11 +775,11 @@ static int relabel_tty(const char *ttyn, const char *new_context, * Returns zero on success, non-zero otherwise */ static int restore_tty_label(int fd, const char *ttyn, - const char *tty_context, - const char *new_tty_context) + security_context_t tty_context, + security_context_t new_tty_context) { int rc = 0; - char *chk_tty_context = NULL; + security_context_t chk_tty_context = NULL; if (!ttyn) goto skip_relabel; @@ -816,8 +816,8 @@ static int restore_tty_label(int fd, const char *ttyn, * Returns zero on success, non-zero otherwise. */ static int parse_command_line_arguments(int argc, char **argv, char *ttyn, - const char *old_context, - char **new_context, + security_context_t old_context, + security_context_t * new_context, int *preserve_environment) { int flag_index; /* flag index in argv[] */ @@ -827,8 +827,8 @@ static int parse_command_line_arguments(int argc, char **argv, char *ttyn, char *type_ptr = NULL; /* stores malloc'd data from get_default_type */ char *level_s = NULL; /* level spec'd by user in argv[] */ char *range_ptr = NULL; - char *new_con = NULL; - char *tty_con = NULL; + security_context_t new_con = NULL; + security_context_t tty_con = NULL; context_t context = NULL; /* manipulatable form of new_context */ const struct option long_options[] = { {"role", 1, 0, 'r'}, @@ -1021,10 +1021,10 @@ static int set_signal_handles(void) int main(int argc, char *argv[]) { - char *new_context = NULL; /* target security context */ - char *old_context = NULL; /* original securiy context */ - char *tty_context = NULL; /* current context of tty */ - char *new_tty_context = NULL; /* new context of tty */ + security_context_t new_context = NULL; /* target security context */ + security_context_t old_context = NULL; /* original securiy context */ + security_context_t tty_context = NULL; /* current context of tty */ + security_context_t new_tty_context = NULL; /* new context of tty */ struct passwd pw; /* struct derived from passwd file line */ char *ttyn = NULL; /* tty path */ @@ -1239,7 +1239,6 @@ int main(int argc, char *argv[]) free(pw.pw_dir); free(pw.pw_shell); free(shell_argv0); - free(new_context); return exit_code; } diff --git a/policycoreutils/run_init/run_init.c b/policycoreutils/run_init/run_init.c index 545490a2..a007ce49 100644 --- a/policycoreutils/run_init/run_init.c +++ b/policycoreutils/run_init/run_init.c @@ -303,7 +303,7 @@ int authenticate_user(void) * out: The CONTEXT associated with the context. * return: 0 on success, -1 on failure. */ -int get_init_context(char **context) +int get_init_context(security_context_t * context) { FILE *fp; @@ -354,7 +354,7 @@ int main(int argc, char *argv[]) extern char *optarg; /* used by getopt() for arg strings */ extern int opterr; /* controls getopt() error messages */ - char *new_context; /* context for the init script context */ + security_context_t new_context; /* context for the init script context */ #ifdef USE_NLS setlocale(LC_ALL, ""); @@ -406,19 +406,14 @@ int main(int argc, char *argv[]) if (chdir("/")) { perror("chdir"); - free(new_context); exit(-1); } if (setexeccon(new_context) < 0) { fprintf(stderr, _("Could not set exec context to %s.\n"), new_context); - free(new_context); exit(-1); } - - free(new_context); - if (access("/usr/sbin/open_init_pty", X_OK) != 0) { if (execvp(argv[1], argv + 1)) { perror("execvp"); diff --git a/policycoreutils/scripts/fixfiles b/policycoreutils/scripts/fixfiles index 6fb12e04..5d777034 100755 --- a/policycoreutils/scripts/fixfiles +++ b/policycoreutils/scripts/fixfiles @@ -112,7 +112,6 @@ FORCEFLAG="" RPMFILES="" PREFC="" RESTORE_MODE="" -BIND_MOUNT_FILESYSTEMS="" SETFILES=/sbin/setfiles RESTORECON=/sbin/restorecon FILESYSTEMSRW=`get_rw_labeled_mounts` @@ -162,7 +161,7 @@ newer() { # diff_filecontext() { EXCLUDEDIRS="`exclude_dirs_from_relabelling`" -for i in /sys /proc /mnt /var/tmp /var/lib/BackupPC /home /root /tmp; do +for i in /sys /proc /dev /run /mnt /var/tmp /var/lib/BackupPC /home /tmp /dev; do [ -e $i ] && EXCLUDEDIRS="${EXCLUDEDIRS} -e $i"; done LogExcluded @@ -175,7 +174,7 @@ if [ -f ${PREFC} -a -x /usr/bin/diff ]; then sed -r -e 's,:s0, ,g' $FC | sort -u | \ /usr/bin/diff -b ${PREFCTEMPFILE} - | \ grep '^[<>]'|cut -c3-| grep ^/ | \ - egrep -v '(^/home|^/root|^/tmp)' |\ + egrep -v '(^/home|^/root|^/tmp|^/dev)' |\ sed -r -e 's,[[:blank:]].*,,g' \ -e 's|\(([/[:alnum:]]+)\)\?|{\1,}|g' \ -e 's|([/[:alnum:]])\?|{\1,}|g' \ @@ -244,23 +243,7 @@ case "$RESTORE_MODE" in if [ -n "${FILESYSTEMSRW}" ]; then LogReadOnly echo "${OPTION}ing `echo ${FILESYSTEMSRW}`" - - if [ -z "$BIND_MOUNT_FILESYSTEMS" ]; then - ${SETFILES} ${VERBOSE} ${EXCLUDEDIRS} ${FORCEFLAG} $* -q ${FC} ${FILESYSTEMSRW} - else - # we bind mount so we can fix the labels of files that have already been - # mounted over - for m in `echo $FILESYSTEMSRW`; do - TMP_MOUNT="$(mktemp -d)" - test -z ${TMP_MOUNT+x} && echo "Unable to find temporary directory!" && exit 1 - - mkdir -p "${TMP_MOUNT}${m}" || exit 1 - mount --bind "${m}" "${TMP_MOUNT}${m}" || exit 1 - ${SETFILES} ${VERBOSE} ${EXCLUDEDIRS} ${FORCEFLAG} $* -q ${FC} -r "${TMP_MOUNT}" "${TMP_MOUNT}${m}" - umount "${TMP_MOUNT}${m}" || exit 1 - rm -rf "${TMP_MOUNT}" || echo "Error cleaning up." - done; - fi + ${SETFILES} ${VERBOSE} ${EXCLUDEDIRS} ${FORCEFLAG} $* -q ${FC} ${FILESYSTEMSRW} else echo >&2 "fixfiles: No suitable file systems found" fi @@ -330,7 +313,6 @@ case "$1" in > /.autorelabel || exit $? [ -z "$FORCEFLAG" ] || echo -n "$FORCEFLAG " >> /.autorelabel [ -z "$BOOTTIME" ] || echo -N $BOOTTIME >> /.autorelabel - [ -z "$BIND_MOUNT_FILESYSTEMS" ] || echo "-M" >> /.autorelabel # Force full relabel if SELinux is not enabled selinuxenabled || echo -F > /.autorelabel echo "System will relabel on next boot" @@ -342,7 +324,7 @@ esac } usage() { echo $""" -Usage: $0 [-v] [-F] [-M] [-f] relabel +Usage: $0 [-v] [-F] [-f] relabel or Usage: $0 [-v] [-F] [-B | -N time ] { check | restore | verify } or @@ -352,7 +334,7 @@ Usage: $0 [-v] [-F] -R rpmpackage[,rpmpackage...] { check | restore | verify } or Usage: $0 [-v] [-F] -C PREVIOUS_FILECONTEXT { check | restore | verify } or -Usage: $0 [-F] [-M] [-B] onboot +Usage: $0 [-F] [-B] onboot """ } @@ -371,7 +353,7 @@ set_restore_mode() { } # See how we were called. -while getopts "N:BC:FfR:l:vM" i; do +while getopts "N:BC:FfR:l:v" i; do case "$i" in B) BOOTTIME=`/bin/who -b | awk '{print $3}'` @@ -397,9 +379,6 @@ while getopts "N:BC:FfR:l:vM" i; do echo "Redirecting output to $OPTARG" exec >>"$OPTARG" 2>&1 ;; - M) - BIND_MOUNT_FILESYSTEMS="-M" - ;; F) FORCEFLAG="-F" ;; diff --git a/policycoreutils/scripts/fixfiles.8 b/policycoreutils/scripts/fixfiles.8 index c4e894e5..9f447f03 100644 --- a/policycoreutils/scripts/fixfiles.8 +++ b/policycoreutils/scripts/fixfiles.8 @@ -6,7 +6,7 @@ fixfiles \- fix file SELinux security contexts. .na .B fixfiles -.I [\-v] [\-F] [-M] [\-f] relabel +.I [\-v] [\-F] [\-f] relabel .B fixfiles .I [\-v] [\-F] { check | restore | verify } dir/file ... @@ -21,7 +21,7 @@ fixfiles \- fix file SELinux security contexts. .I [\-v] [\-F] \-C PREVIOUS_FILECONTEXT { check | restore | verify } .B fixfiles -.I [-F] [-M] [-B] onboot +.I [-F] [-B] onboot .ad @@ -35,8 +35,8 @@ database (extended attributes) on filesystems. .P It can also be run at any time to relabel when adding support for new policy, or just check whether the file contexts are all -as you expect. By default it will relabel all mounted ext2, ext3, ext4, gfs2, xfs, -jfs and btrfs file systems as long as they do not have a security context mount +as you expect. By default it will relabel all mounted ext2, ext3, xfs and +jfs file systems as long as they do not have a security context mount option. You can use the \-R flag to use rpmpackages as an alternative. The file /etc/selinux/fixfiles_exclude_dirs can contain a list of directories excluded from relabeling. @@ -68,10 +68,6 @@ Run a diff on the PREVIOUS_FILECONTEXT file to the currently installed one, and Only act on files created after the specified date. Date must be specified in "YYYY\-MM\-DD HH:MM" format. Date field will be passed to find \-\-newermt command. -.TP -.B \-M -Bind mount filesystems before relabeling them, this allows fixing the context of files or directories that have been mounted over. - .TP .B -v Modify verbosity from progress to verbose. (Run restorecon with \-v instead of \-p) @@ -79,7 +75,7 @@ Modify verbosity from progress to verbose. (Run restorecon with \-v instead of \ .SH "ARGUMENTS" One of: .TP -.B check | verify +.B check print any incorrect file context labels, showing old and new context, but do not change them. .TP .B restore @@ -88,6 +84,9 @@ change any incorrect file context labels. .B relabel Prompt for removal of contents of /tmp directory and then change any incorrect file context labels to match the install file_contexts file. .TP +.B verify +List out files with incorrect file context labels, but do not change them. +.TP .B [[dir/file] ... ] List of files or directories trees that you wish to check file context on. diff --git a/policycoreutils/secon/secon.c b/policycoreutils/secon/secon.c index a0957d09..477057a6 100644 --- a/policycoreutils/secon/secon.c +++ b/policycoreutils/secon/secon.c @@ -341,7 +341,7 @@ static void cmd_line(int argc, char *argv[]) errx(EXIT_FAILURE, "SELinux is not enabled"); } -static int my_getXcon_raw(pid_t pid, char **con, const char *val) +static int my_getXcon_raw(pid_t pid, security_context_t * con, const char *val) { char buf[4096]; FILE *fp = NULL; @@ -371,23 +371,23 @@ static int my_getXcon_raw(pid_t pid, char **con, const char *val) return (0); } -static int my_getpidexeccon_raw(pid_t pid, char **con) +static int my_getpidexeccon_raw(pid_t pid, security_context_t * con) { return (my_getXcon_raw(pid, con, "exec")); } -static int my_getpidfscreatecon_raw(pid_t pid, char **con) +static int my_getpidfscreatecon_raw(pid_t pid, security_context_t * con) { return (my_getXcon_raw(pid, con, "fscreate")); } -static int my_getpidkeycreatecon_raw(pid_t pid, char **con) +static int my_getpidkeycreatecon_raw(pid_t pid, security_context_t * con) { return (my_getXcon_raw(pid, con, "keycreate")); } -static char *get_scon(void) +static security_context_t get_scon(void) { static char dummy_NIL[1] = ""; - char *con = NULL, *con_tmp; + security_context_t con = NULL, con_tmp; int ret = -1; switch (opts->from_type) { @@ -620,10 +620,9 @@ static void disp__con_val(const char *name, const char *val, done = TRUE; } -static void disp_con(const char *scon_raw) +static void disp_con(security_context_t scon_raw) { - char *scon_trans; - const char *scon; + security_context_t scon_trans, scon; context_t con = NULL; char *color_str = NULL; struct context_color_t color = { .valid = 0 }; @@ -683,7 +682,7 @@ static void disp_con(const char *scon_raw) color.range_bg = strtok(NULL, " "); color.valid = 1; - } + }; if (!(con = context_new(scon))) errx(EXIT_FAILURE, "Couldn't create context from: %s", scon); @@ -749,7 +748,7 @@ static void disp_con(const char *scon_raw) int main(int argc, char *argv[]) { - char *scon_raw = NULL; + security_context_t scon_raw = NULL; cmd_line(argc, argv); diff --git a/policycoreutils/semodule/genhomedircon.8 b/policycoreutils/semodule/genhomedircon.8 index ecab7ba3..2a3315b5 100644 --- a/policycoreutils/semodule/genhomedircon.8 +++ b/policycoreutils/semodule/genhomedircon.8 @@ -16,9 +16,6 @@ This script is usually executed by although this default behavior can be optionally modified by setting to "true" the "disable-genhomedircon" in /etc/selinux/semanage.conf. -Directories can be excluded from the list of home directories by the setting "ignoredirs" -in /etc/selinux/semanage.conf. - .SH AUTHOR This manual page was written by .I Dan Walsh diff --git a/policycoreutils/sestatus/Makefile b/policycoreutils/sestatus/Makefile index 3dbb792b..8c4f45f8 100644 --- a/policycoreutils/sestatus/Makefile +++ b/policycoreutils/sestatus/Makefile @@ -1,7 +1,6 @@ # Installation directories. LINGUAS ?= ru PREFIX ?= /usr -BINDIR ?= $(PREFIX)/bin SBINDIR ?= $(PREFIX)/sbin MANDIR = $(PREFIX)/share/man ETCDIR ?= /etc @@ -17,13 +16,8 @@ sestatus: sestatus.o install: all [ -d $(DESTDIR)$(MANDIR)/man8 ] || mkdir -p $(DESTDIR)$(MANDIR)/man8 [ -d $(DESTDIR)$(MANDIR)/man5 ] || mkdir -p $(DESTDIR)$(MANDIR)/man5 - -mkdir -p $(DESTDIR)$(BINDIR) -mkdir -p $(DESTDIR)$(SBINDIR) - # Some tools hard code /usr/sbin/sestatus ; add a compatibility symlink - # install will overwrite a symlink, so create the symlink before calling - # install to allow distributions with BINDIR == SBINDIR - ln -sf --relative $(DESTDIR)$(BINDIR)/sestatus $(DESTDIR)$(SBINDIR) - install -m 755 sestatus $(DESTDIR)$(BINDIR) + install -m 755 sestatus $(DESTDIR)$(SBINDIR) install -m 644 sestatus.8 $(DESTDIR)$(MANDIR)/man8 install -m 644 sestatus.conf.5 $(DESTDIR)$(MANDIR)/man5 for lang in $(LINGUAS) ; do \ diff --git a/policycoreutils/sestatus/sestatus.c b/policycoreutils/sestatus/sestatus.c index ceee0d52..b37f0353 100644 --- a/policycoreutils/sestatus/sestatus.c +++ b/policycoreutils/sestatus/sestatus.c @@ -461,7 +461,6 @@ int main(int argc, char **argv) ("%s (could not check link status (%s)!)\n", context, strerror(errno)); freecon(context); - free(fc[i]); continue; } if (S_ISLNK(m.st_mode)) { diff --git a/policycoreutils/setfiles/.gitignore b/policycoreutils/setfiles/.gitignore new file mode 100644 index 00000000..5e899c95 --- /dev/null +++ b/policycoreutils/setfiles/.gitignore @@ -0,0 +1 @@ +setfiles.8.man diff --git a/policycoreutils/setfiles/Makefile b/policycoreutils/setfiles/Makefile index 63d81850..bc5a8db7 100644 --- a/policycoreutils/setfiles/Makefile +++ b/policycoreutils/setfiles/Makefile @@ -5,6 +5,8 @@ SBINDIR ?= /sbin MANDIR = $(PREFIX)/share/man AUDITH ?= $(shell test -f /usr/include/libaudit.h && echo y) +ABORT_ON_ERRORS=$(shell grep "^\#define ABORT_ON_ERRORS" setfiles.c | awk -S '{ print $$3 }') + CFLAGS ?= -g -Werror -Wall -W override LDLIBS += -lselinux -lsepol @@ -13,7 +15,7 @@ ifeq ($(AUDITH), y) override LDLIBS += -laudit endif -all: setfiles restorecon restorecon_xattr +all: setfiles restorecon restorecon_xattr man setfiles: setfiles.o restore.o @@ -22,13 +24,17 @@ restorecon: setfiles restorecon_xattr: restorecon_xattr.o restore.o +man: + @cp -af setfiles.8 setfiles.8.man + @sed -i "s/ABORT_ON_ERRORS/$(ABORT_ON_ERRORS)/g" setfiles.8.man + install: all [ -d $(DESTDIR)$(MANDIR)/man8 ] || mkdir -p $(DESTDIR)$(MANDIR)/man8 -mkdir -p $(DESTDIR)$(SBINDIR) install -m 755 setfiles $(DESTDIR)$(SBINDIR) (cd $(DESTDIR)$(SBINDIR) && ln -sf setfiles restorecon) install -m 755 restorecon_xattr $(DESTDIR)$(SBINDIR) - install -m 644 setfiles.8 $(DESTDIR)$(MANDIR)/man8/setfiles.8 + install -m 644 setfiles.8.man $(DESTDIR)$(MANDIR)/man8/setfiles.8 install -m 644 restorecon.8 $(DESTDIR)$(MANDIR)/man8/restorecon.8 install -m 644 restorecon_xattr.8 $(DESTDIR)$(MANDIR)/man8/restorecon_xattr.8 for lang in $(LINGUAS) ; do \ @@ -39,7 +45,7 @@ install: all done clean: - rm -f setfiles restorecon restorecon_xattr *.o + rm -f setfiles restorecon restorecon_xattr *.o setfiles.8.man indent: ../../scripts/Lindent $(wildcard *.[ch]) diff --git a/policycoreutils/setfiles/restore.c b/policycoreutils/setfiles/restore.c index 9d688c60..d3335d1a 100644 --- a/policycoreutils/setfiles/restore.c +++ b/policycoreutils/setfiles/restore.c @@ -41,7 +41,7 @@ void restore_init(struct restore_opts *opts) opts->xdev | opts->abort_on_error | opts->syslog_changes | opts->log_matches | opts->ignore_noent | opts->ignore_mounts | - opts->mass_relabel | opts->conflict_error; + opts->mass_relabel; /* Use setfiles, restorecon and restorecond own handles */ selinux_restorecon_set_sehandle(opts->hnd); diff --git a/policycoreutils/setfiles/restore.h b/policycoreutils/setfiles/restore.h index ac6ad680..b64042a6 100644 --- a/policycoreutils/setfiles/restore.h +++ b/policycoreutils/setfiles/restore.h @@ -34,7 +34,6 @@ struct restore_opts { unsigned int log_matches; unsigned int ignore_noent; unsigned int ignore_mounts; - unsigned int conflict_error; /* restorecon_flags holds | of above for restore_init() */ unsigned int restorecon_flags; char *rootpath; diff --git a/policycoreutils/setfiles/restorecon.8 b/policycoreutils/setfiles/restorecon.8 index 668486f6..bbfc83fe 100644 --- a/policycoreutils/setfiles/restorecon.8 +++ b/policycoreutils/setfiles/restorecon.8 @@ -13,7 +13,6 @@ restorecon \- restore file(s) default SELinux security contexts. .RB [ \-F ] .RB [ \-W ] .RB [ \-I | \-D ] -.RB [ \-x ] .RB [ \-e .IR directory ] .IR pathname \ ... @@ -32,7 +31,6 @@ restorecon \- restore file(s) default SELinux security contexts. .RB [ \-F ] .RB [ \-W ] .RB [ \-I | \-D ] -.RB [ \-x ] .SH "DESCRIPTION" This manual page describes the @@ -155,21 +153,14 @@ option of GNU .B find produces input suitable for this mode. .TP -.B \-x -prevent -.B restorecon -from crossing file system boundaries. -.TP .SH "ARGUMENTS" .IR pathname \ ... The pathname for the file(s) to be relabeled. .SH "NOTES" .IP "1." 4 .B restorecon -by default does not operate recursively on directories. Paths leading up the -final component of the file(s) are canonicalized using -.BR realpath (3) -before labeling. +does not follow symbolic links and by default it does not +operate recursively on directories. .IP "2." 4 If the .I pathname diff --git a/policycoreutils/setfiles/restorecon_xattr.c b/policycoreutils/setfiles/restorecon_xattr.c index 31fb82fd..59b1f748 100644 --- a/policycoreutils/setfiles/restorecon_xattr.c +++ b/policycoreutils/setfiles/restorecon_xattr.c @@ -38,7 +38,7 @@ int main(int argc, char **argv) unsigned int xattr_flags = 0, delete_digest = 0, recurse = 0; unsigned int delete_all_digests = 0, ignore_mounts = 0; bool display_digest = false; - char *sha1_buf, **specfiles, *fc_file = NULL, *pathname = NULL; + char *sha1_buf, **specfiles, *fc_file = NULL; unsigned char *fc_digest = NULL; size_t i, fc_digest_len = 0, num_specfiles; @@ -163,16 +163,7 @@ int main(int argc, char **argv) xattr_flags = delete_digest | delete_all_digests | ignore_mounts | recurse; - pathname = realpath(argv[optind], NULL); - if (!pathname) { - fprintf(stderr, - "restorecon_xattr: realpath(%s) failed: %s\n", - argv[optind], strerror(errno)); - rc = -1; - goto out; - } - - if (selinux_restorecon_xattr(pathname, xattr_flags, &xattr_list)) { + if (selinux_restorecon_xattr(argv[optind], xattr_flags, &xattr_list)) { fprintf(stderr, "Error selinux_restorecon_xattr: %s\n", strerror(errno)); @@ -224,7 +215,6 @@ int main(int argc, char **argv) rc = 0; out: - free(pathname); selabel_close(hnd); restore_finish(); return rc; diff --git a/policycoreutils/setfiles/ru/setfiles.8 b/policycoreutils/setfiles/ru/setfiles.8 index 91010145..27815a3f 100644 --- a/policycoreutils/setfiles/ru/setfiles.8 +++ b/policycoreutils/setfiles/ru/setfiles.8 @@ -47,7 +47,7 @@ setfiles \- установить SELinux-контексты безопаснос проверить действительность контекстов относительно указанной двоичной политики. .TP .B \-d -показать, какая спецификация соответствует каждому из файлов. +показать, какая спецификация соответствует каждому из файлов (не прекращать проверку после получения ошибок ABORT_ON_ERRORS). .TP .BI \-e \ directory исключить каталог (чтобы исключить более одного каталога, этот параметр необходимо использовать соответствующее количество раз). diff --git a/policycoreutils/setfiles/setfiles.8 b/policycoreutils/setfiles/setfiles.8 index 4d28bc9a..c9f8be06 100644 --- a/policycoreutils/setfiles/setfiles.8 +++ b/policycoreutils/setfiles/setfiles.8 @@ -12,7 +12,6 @@ setfiles \- set SELinux file security contexts. .RB [ \-n ] .RB [ \-e .IR directory ] -.RB [ \-E ] .RB [ \-p ] .RB [ \-s ] .RB [ \-v ] @@ -57,15 +56,12 @@ option will force a replacement of the entire context. check the validity of the contexts against the specified binary policy. .TP .B \-d -show what specification matched each file. +show what specification matched each file (do not abort validation +after ABORT_ON_ERRORS errors). .TP .BI \-e \ directory directory to exclude (repeat option for more than one directory). .TP -.BI \-E -treat conflicting specifications as errors, such as where two hardlinks for -the same inode have different contexts. -.TP .BI \-f \ infilename .I infilename contains a list of files to be processed. Use @@ -213,8 +209,7 @@ option is used. .SH "NOTES" .IP "1." 4 .B setfiles -operates recursively on directories. Paths leading up the final -component of the file(s) are not canonicalized before labeling. +follows symbolic links and operates recursively on directories. .IP "2." 4 If the .I pathname diff --git a/policycoreutils/setfiles/setfiles.c b/policycoreutils/setfiles/setfiles.c index f018d161..bc83c27b 100644 --- a/policycoreutils/setfiles/setfiles.c +++ b/policycoreutils/setfiles/setfiles.c @@ -19,9 +19,18 @@ static int warn_no_match; static int null_terminated; static int request_digest; static struct restore_opts r_opts; +static int nerr; #define STAT_BLOCK_SIZE 1 +/* setfiles will abort its operation after reaching the + * following number of errors (e.g. invalid contexts), + * unless it is used in "debug" mode (-d option). + */ +#ifndef ABORT_ON_ERRORS +#define ABORT_ON_ERRORS 10 +#endif + #define SETFILES "setfiles" #define RESTORECON "restorecon" static int iamrestorecon; @@ -34,19 +43,29 @@ static __attribute__((__noreturn__)) void usage(const char *const name) { if (iamrestorecon) { fprintf(stderr, - "usage: %s [-iIDFmnprRv0x] [-e excludedir] pathname...\n" - "usage: %s [-iIDFmnprRv0x] [-e excludedir] -f filename\n", + "usage: %s [-iIDFmnprRv0] [-e excludedir] pathname...\n" + "usage: %s [-iIDFmnprRv0] [-e excludedir] -f filename\n", name, name); } else { fprintf(stderr, - "usage: %s [-diIDlmnpqvEFW] [-e excludedir] [-r alt_root_path] [-c policyfile] spec_file pathname...\n" - "usage: %s [-diIDlmnpqvEFW] [-e excludedir] [-r alt_root_path] [-c policyfile] spec_file -f filename\n" - "usage: %s -s [-diIDlmnpqvFW] spec_file\n", - name, name, name); + "usage: %s [-diIDlmnpqvFW] [-e excludedir] [-r alt_root_path] spec_file pathname...\n" + "usage: %s [-diIDlmnpqvFW] [-e excludedir] [-r alt_root_path] spec_file -f filename\n" + "usage: %s -s [-diIDlmnpqvFW] spec_file\n" + "usage: %s -c policyfile spec_file\n", + name, name, name, name); } exit(-1); } +void inc_err(void) +{ + nerr++; + if (nerr > ABORT_ON_ERRORS - 1 && !r_opts.debug) { + fprintf(stderr, "Exiting after %d errors.\n", ABORT_ON_ERRORS); + exit(-1); + } +} + void set_rootpath(const char *arg) { if (strlen(arg) == 1 && strncmp(arg, "/", 1) == 0) { @@ -79,6 +98,7 @@ int canoncon(char **contextp) *contextp = tmpcon; } else if (errno != ENOENT) { rc = -1; + inc_err(); } return rc; @@ -148,8 +168,8 @@ int main(int argc, char **argv) size_t buf_len; const char *base; int errors = 0; - const char *ropts = "e:f:hiIDlmno:pqrsvFRW0x"; - const char *sopts = "c:de:f:hiIDlmno:pqr:svEFR:W0"; + const char *ropts = "e:f:hiIDlmno:pqrsvFRW0"; + const char *sopts = "c:de:f:hiIDlmno:pqr:svFR:W0"; const char *opts; union selinux_callback cb; @@ -160,8 +180,8 @@ int main(int argc, char **argv) warn_no_match = 0; request_digest = 0; policyfile = NULL; + nerr = 0; - r_opts.abort_on_error = 0; r_opts.progname = strdup(argv[0]); if (!r_opts.progname) { fprintf(stderr, "%s: Out of memory!\n", argv[0]); @@ -174,6 +194,7 @@ int main(int argc, char **argv) * setfiles: * Recursive descent, * Does not expand paths via realpath, + * Aborts on errors during the file tree walk, * Try to track inode associations for conflict detection, * Does not follow mounts (sets SELINUX_RESTORECON_XDEV), * Validates all file contexts at init time. @@ -181,6 +202,7 @@ int main(int argc, char **argv) iamrestorecon = 0; r_opts.recurse = SELINUX_RESTORECON_RECURSE; r_opts.userealpath = 0; /* SELINUX_RESTORECON_REALPATH */ + r_opts.abort_on_error = SELINUX_RESTORECON_ABORT_ON_ERROR; r_opts.add_assoc = SELINUX_RESTORECON_ADD_ASSOC; /* FTS_PHYSICAL and FTS_NOCHDIR are always set by selinux_restorecon(3) */ r_opts.xdev = SELINUX_RESTORECON_XDEV; @@ -204,6 +226,7 @@ int main(int argc, char **argv) iamrestorecon = 1; r_opts.recurse = 0; r_opts.userealpath = SELINUX_RESTORECON_REALPATH; + r_opts.abort_on_error = 0; r_opts.add_assoc = 0; r_opts.xdev = 0; r_opts.ignore_mounts = 0; @@ -290,10 +313,6 @@ int main(int argc, char **argv) r_opts.syslog_changes = SELINUX_RESTORECON_SYSLOG_CHANGES; break; - case 'E': - r_opts.conflict_error = - SELINUX_RESTORECON_CONFLICT_ERROR; - break; case 'F': r_opts.set_specctx = SELINUX_RESTORECON_SET_SPECFILE_CTX; @@ -363,13 +382,6 @@ int main(int argc, char **argv) case '0': null_terminated = 1; break; - case 'x': - if (iamrestorecon) { - r_opts.xdev = SELINUX_RESTORECON_XDEV; - } else { - usage(argv[0]); - } - break; case 'h': case '?': usage(argv[0]); @@ -386,7 +398,7 @@ int main(int argc, char **argv) if (!iamrestorecon) { if (policyfile) { - if (optind > (argc - 1)) + if (optind != (argc - 1)) usage(argv[0]); } else if (use_input_file) { if (optind != (argc - 1)) { @@ -425,6 +437,9 @@ int main(int argc, char **argv) r_opts.selabel_opt_digest = (request_digest ? (char *)1 : NULL); r_opts.selabel_opt_path = altpath; + if (nerr) + exit(-1); + restore_init(&r_opts); if (use_input_file) { diff --git a/policycoreutils/setsebool/setsebool.c b/policycoreutils/setsebool/setsebool.c index 60da5df1..9d8abfac 100644 --- a/policycoreutils/setsebool/setsebool.c +++ b/policycoreutils/setsebool/setsebool.c @@ -200,10 +200,8 @@ static int semanage_set_boolean_list(size_t boolcnt, if (no_reload) semanage_set_reload(handle, 0); - if (semanage_commit(handle) < 0) { - fprintf(stderr, "Failed to commit changes to booleans: %m\n"); + if (semanage_commit(handle) < 0) goto err; - } semanage_disconnect(handle); semanage_handle_destroy(handle); diff --git a/python/VERSION b/python/VERSION index e6852d8a..9f55b2cc 100644 --- a/python/VERSION +++ b/python/VERSION @@ -1 +1 @@ -3.3-rc1 +3.0 diff --git a/python/audit2allow/Makefile b/python/audit2allow/Makefile index 76bf4e37..15db5490 100644 --- a/python/audit2allow/Makefile +++ b/python/audit2allow/Makefile @@ -19,7 +19,7 @@ endif all: audit2why sepolgen-ifgen-attr-helper sepolgen-ifgen-attr-helper: sepolgen-ifgen-attr-helper.o $(LIBSEPOLA) - $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS_LIBSEPOLA) -lselinux + $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS_LIBSEPOLA) audit2why: ln -sf audit2allow audit2why diff --git a/python/audit2allow/sepolgen-ifgen b/python/audit2allow/sepolgen-ifgen index b7a04c71..4a71cda4 100644 --- a/python/audit2allow/sepolgen-ifgen +++ b/python/audit2allow/sepolgen-ifgen @@ -27,6 +27,7 @@ import sys +import os import tempfile import subprocess @@ -64,18 +65,37 @@ def parse_options(): return options +def get_policy(): + p = selinux.selinux_current_policy_path() + if p and os.path.exists(p): + return p + i = selinux.security_policyvers() + p = selinux.selinux_binary_policy_path() + "." + str(i) + while i > 0 and not os.path.exists(p): + i = i - 1 + p = selinux.selinux_binary_policy_path() + "." + str(i) + if i > 0: + return p + return None + + def get_attrs(policy_path, attr_helper): try: + if not policy_path: + policy_path = get_policy() + if not policy_path: + sys.stderr.write("No installed policy to check\n") + return None outfile = tempfile.NamedTemporaryFile() except IOError as e: sys.stderr.write("could not open attribute output file\n") return None + except OSError: + # SELinux Disabled Machine + return None fd = open("/dev/null", "w") - if policy_path: - ret = subprocess.Popen([attr_helper, outfile.name, policy_path], stdout=fd).wait() - else: - ret = subprocess.Popen([attr_helper, outfile.name], stdout=fd).wait() + ret = subprocess.Popen([attr_helper, policy_path, outfile.name], stdout=fd).wait() fd.close() if ret != 0: sys.stderr.write("could not run attribute helper\n") diff --git a/python/audit2allow/sepolgen-ifgen-attr-helper.c b/python/audit2allow/sepolgen-ifgen-attr-helper.c index f010c958..1ce37b0d 100644 --- a/python/audit2allow/sepolgen-ifgen-attr-helper.c +++ b/python/audit2allow/sepolgen-ifgen-attr-helper.c @@ -26,9 +26,6 @@ #include #include -#include - -#include #include #include #include @@ -150,36 +147,8 @@ static policydb_t *load_policy(const char *filename) policydb_t *policydb; struct policy_file pf; FILE *fp; - char pathname[PATH_MAX]; - int suffix_ver; int ret; - /* no explicit policy name given, try loaded policy on a SELinux enabled system */ - if (!filename) { - filename = selinux_current_policy_path(); - } - - /* - * Fallback to default store paths with version suffixes, - * starting from the maximum supported policy version. - */ - if (!filename) { - for (suffix_ver = sepol_policy_kern_vers_max(); suffix_ver > 0; suffix_ver--) { - snprintf(pathname, sizeof(pathname), "%s.%d", selinux_binary_policy_path(), suffix_ver); - - if (access(pathname, F_OK) == 0) { - filename = pathname; - break; - } - } - - if (!filename) { - fprintf(stderr, "Can't find any policy at '%s'\n", - selinux_binary_policy_path()); - return NULL; - } - } - fp = fopen(filename, "r"); if (fp == NULL) { fprintf(stderr, "Can't open '%s': %s\n", @@ -219,7 +188,7 @@ static policydb_t *load_policy(const char *filename) void usage(char *progname) { - printf("usage: %s out_file [policy_file]\n", progname); + printf("usage: %s policy_file out_file\n", progname); } int main(int argc, char **argv) @@ -228,18 +197,18 @@ int main(int argc, char **argv) struct callback_data cb_data; FILE *fp; - if (argc != 2 && argc != 3) { + if (argc != 3) { usage(argv[0]); return -1; } /* Open the policy. */ - p = load_policy(argv[2]); + p = load_policy(argv[1]); if (p == NULL) return -1; /* Open the output policy. */ - fp = fopen(argv[1], "w"); + fp = fopen(argv[2], "w"); if (fp == NULL) { fprintf(stderr, "error opening output file\n"); policydb_destroy(p); diff --git a/python/semanage/semanage b/python/semanage/semanage index 18a27105..b2fabea6 100644 --- a/python/semanage/semanage +++ b/python/semanage/semanage @@ -23,13 +23,10 @@ # # +import traceback import argparse -import os -import re import seobject import sys -import traceback - PROGNAME = "policycoreutils" try: import gettext @@ -379,7 +376,7 @@ If you do not specify a file type, the file type will default to "all files". parser_add_seuser(fcontextParser, "fcontext") parser_add_type(fcontextParser, "fcontext") parser_add_range(fcontextParser, "fcontext") - fcontextParser.add_argument('file_spec', nargs='?', default=None, help=_('Path to be labeled (may be in the form of a Perl compatible regular expression)')) + fcontextParser.add_argument('file_spec', nargs='?', default=None, help=_('file_spec')) fcontextParser.set_defaults(func=handleFcontext) @@ -800,6 +797,8 @@ def setupExportParser(subparsers): exportParser.add_argument('-f', '--output_file', dest='output_file', action=SetExportFile, help=_('Output file')) exportParser.set_defaults(func=handleExport) +import re + def mkargv(line): dquote = "\"" @@ -946,13 +945,6 @@ def do_parser(): args = commandParser.parse_args(make_args(sys.argv)) args.func(args) sys.exit(0) - except BrokenPipeError as e: - sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e))) - # Python flushes standard streams on exit; redirect remaining output - # to devnull to avoid another BrokenPipeError at shutdown - devnull = os.open(os.devnull, os.O_WRONLY) - os.dup2(devnull, sys.stdout.fileno()) - sys.exit(1) except IOError as e: sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e))) sys.exit(1) diff --git a/python/semanage/semanage-bash-completion.sh b/python/semanage/semanage-bash-completion.sh index d0dd139f..2d811c98 100644 --- a/python/semanage/semanage-bash-completion.sh +++ b/python/semanage/semanage-bash-completion.sh @@ -54,9 +54,6 @@ __get_all_roles () { __get_all_stores () { dir -1 -F /etc/selinux/ | grep '/' | cut -d'/' -f 1 } -__get_all_modules () { - semodule -l -} __get_import_opts () { echo '$ALL_OPTS --f --input_file' ; } __get_export_opts () { echo '$ALL_OPTS --f --output_file' ; } __get_boolean_opts () { echo '$ALL_OPTS --on -off -1 -0' ; } @@ -91,13 +88,6 @@ _semanage () { if [ "$prev" = "-a" -a "$command" = "permissive" ]; then COMPREPLY=( $(compgen -W "$( __get_all_domains ) " -- "$cur") ) return 0 - elif [ "$command" = "module" ]; then - if [ "$prev" = "-d" ] || [ "$prev" = "--disable" ] \ - || [ "$prev" = "-e" ] || [ "$prev" = "--enable" ] \ - || [ "$prev" = "-r" ] || [ "$prev" = "--remove" ]; then - COMPREPLY=( $(compgen -W "$( __get_all_modules ) " -- "$cur") ) - return 0 - fi fi if [ "$verb" = "" -a "$prev" = "semanage" ]; then comps="${VERBS[*]}" diff --git a/python/semanage/semanage-fcontext.8 b/python/semanage/semanage-fcontext.8 index 49635ba7..561123af 100644 --- a/python/semanage/semanage-fcontext.8 +++ b/python/semanage/semanage-fcontext.8 @@ -11,24 +11,6 @@ SELinux policy without requiring modification to or recompilation from policy sources. semanage fcontext is used to manage the default file system labeling on an SELinux system. This command maps file paths using regular expressions to SELinux labels. -FILE_SPEC may contain either a fully qualified path, -or a Perl compatible regular expression (PCRE), -describing fully qualified path(s). The only PCRE flag in use is PCRE2_DOTALL, -which causes a wildcard '.' to match anything, including a new line. -Strings representing paths are processed as bytes (as opposed to Unicode), -meaning that non-ASCII characters are not matched by a single wildcard. - -Note, that file context definitions specified using 'semanage fcontext' -(i.e. local file context modifications stored in file_contexts.local) -have higher priority than those specified in policy modules. -This means that whenever a match for given file path is found in -file_contexts.local, no other file context definitions are considered. -Entries in file_contexts.local are processed from most recent one to the oldest, -with first match being used (as opposed to the most specific match, -which is used when matching other file context definitions). -All regular expressions should therefore be as specific as possible, -to avoid unintentionally impacting other parts of the filesystem. - .SH "OPTIONS" .TP .I \-h, \-\-help diff --git a/python/semanage/semanage-node.8 b/python/semanage/semanage-node.8 index a0098221..e0b0e56c 100644 --- a/python/semanage/semanage-node.8 +++ b/python/semanage/semanage-node.8 @@ -45,7 +45,7 @@ Extract customizable commands, for use within a transaction Remove all local customizations .TP .I \-M NETMASK, \-\-netmask NETMASK -Network Mask, either in CIDR (/16) or address mask notation (255.255.0.0, ffff::) +Network Mask .TP .I \-t TYPE, \-\-type TYPE SELinux type for the object diff --git a/python/semanage/seobject.py b/python/semanage/seobject.py index 21adbf6e..0e9ce290 100644 --- a/python/semanage/seobject.py +++ b/python/semanage/seobject.py @@ -31,9 +31,8 @@ import socket from semanage import * PROGNAME = "policycoreutils" import sepolicy -from setools.policyrep import SELinuxPolicy -from setools.typequery import TypeQuery -import ipaddress +import setools +from IPy import IP try: import gettext @@ -1340,7 +1339,7 @@ class ibpkeyRecords(semanageRecords): def __init__(self, args = None): semanageRecords.__init__(self, args) try: - q = TypeQuery(SELinuxPolicy(sepolicy.get_store_policy(self.store)), attrs=["ibpkey_type"]) + q = setools.TypeQuery(setools.SELinuxPolicy(sepolicy.get_store_policy(self.store)), attrs=["ibpkey_type"]) self.valid_types = sorted(str(t) for t in q.results()) except: pass @@ -1600,7 +1599,7 @@ class ibendportRecords(semanageRecords): def __init__(self, args = None): semanageRecords.__init__(self, args) try: - q = TypeQuery(SELinuxPolicy(sepolicy.get_store_policy(self.store)), attrs=["ibendport_type"]) + q = setools.TypeQuery(setools.SELinuxPolicy(sepolicy.get_store_policy(self.store)), attrs=["ibendport_type"]) self.valid_types = set(str(t) for t in q.results()) except: pass @@ -1859,34 +1858,25 @@ class nodeRecords(semanageRecords): if addr == "": raise ValueError(_("Node Address is required")) - # verify that (addr, mask) is either a IP address (without a mask) or a valid network mask + # verify valid combination if len(mask) == 0 or mask[0] == "/": - i = ipaddress.ip_network(addr + mask) - newaddr = str(i.network_address) - newmask = str(i.netmask) - protocol = "ipv%d" % i.version + i = IP(addr + mask) + newaddr = i.strNormal(0) + newmask = str(i.netmask()) + if newmask == "0.0.0.0" and i.version() == 6: + newmask = "::" + + protocol = "ipv%d" % i.version() try: newprotocol = self.protocol.index(protocol) except: raise ValueError(_("Unknown or missing protocol")) - try: - audit_protocol = socket.getprotobyname(protocol) - except: - # Entry for "ipv4" not found in /etc/protocols on (at - # least) Debian? To ensure audit log compatibility, let's - # use the same numeric value as Fedora: 4, which is - # actually understood by kernel as IP over IP. - if (protocol == "ipv4"): - audit_protocol = socket.IPPROTO_IPIP - else: - raise ValueError(_("Unknown or missing protocol")) - - return newaddr, newmask, newprotocol, audit_protocol + return newaddr, newmask, newprotocol def __add(self, addr, mask, proto, serange, ctype): - addr, mask, proto, audit_proto = self.validate(addr, mask, proto) + addr, mask, proto = self.validate(addr, mask, proto) if is_mls_enabled == 1: if serange == "": @@ -1905,10 +1895,10 @@ class nodeRecords(semanageRecords): (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto) if rc < 0: raise ValueError(_("Could not create key for %s") % addr) - - (rc, exists) = semanage_node_exists(self.sh, k) if rc < 0: raise ValueError(_("Could not check if addr %s is defined") % addr) + + (rc, exists) = semanage_node_exists(self.sh, k) if exists: raise ValueError(_("Addr %s already defined") % addr) @@ -1955,7 +1945,7 @@ class nodeRecords(semanageRecords): semanage_node_key_free(k) semanage_node_free(node) - self.mylog.log_change("resrc=node op=add laddr=%s netmask=%s proto=%s tcontext=%s:%s:%s:%s" % (addr, mask, audit_proto, "system_u", "object_r", ctype, serange)) + self.mylog.log_change("resrc=node op=add laddr=%s netmask=%s proto=%s tcontext=%s:%s:%s:%s" % (addr, mask, socket.getprotobyname(self.protocol[proto]), "system_u", "object_r", ctype, serange)) def add(self, addr, mask, proto, serange, ctype): self.begin() @@ -1963,7 +1953,7 @@ class nodeRecords(semanageRecords): self.commit() def __modify(self, addr, mask, proto, serange, setype): - addr, mask, proto, audit_proto = self.validate(addr, mask, proto) + addr, mask, proto = self.validate(addr, mask, proto) if serange == "" and setype == "": raise ValueError(_("Requires setype or serange")) @@ -2000,7 +1990,7 @@ class nodeRecords(semanageRecords): semanage_node_key_free(k) semanage_node_free(node) - self.mylog.log_change("resrc=node op=modify laddr=%s netmask=%s proto=%s tcontext=%s:%s:%s:%s" % (addr, mask, audit_proto, "system_u", "object_r", setype, serange)) + self.mylog.log_change("resrc=node op=modify laddr=%s netmask=%s proto=%s tcontext=%s:%s:%s:%s" % (addr, mask, socket.getprotobyname(self.protocol[proto]), "system_u", "object_r", setype, serange)) def modify(self, addr, mask, proto, serange, setype): self.begin() @@ -2008,7 +1998,8 @@ class nodeRecords(semanageRecords): self.commit() def __delete(self, addr, mask, proto): - addr, mask, proto, audit_proto = self.validate(addr, mask, proto) + + addr, mask, proto = self.validate(addr, mask, proto) (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto) if rc < 0: @@ -2032,7 +2023,7 @@ class nodeRecords(semanageRecords): semanage_node_key_free(k) - self.mylog.log_change("resrc=node op=delete laddr=%s netmask=%s proto=%s" % (addr, mask, audit_proto)) + self.mylog.log_change("resrc=node op=delete laddr=%s netmask=%s proto=%s" % (addr, mask, socket.getprotobyname(self.protocol[proto]))) def delete(self, addr, mask, proto): self.begin() diff --git a/python/semanage/test-semanage.py b/python/semanage/test-semanage.py index d99e3fda..c8f6ec23 100644 --- a/python/semanage/test-semanage.py +++ b/python/semanage/test-semanage.py @@ -233,7 +233,7 @@ def semanage_custom_suite(test_list): def semanage_run_test(suite): - return unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful() + unittest.TextTestRunner(verbosity=2).run(suite) class CheckTest(argparse.Action): @@ -255,9 +255,9 @@ def semanage_args(args): for i in semanage_test_list: print(i) if args.all: - return semanage_run_test(semanage_suite()) + semanage_run_test(semanage_suite()) if args.test: - return semanage_run_test(semanage_custom_suite(args.test)) + semanage_run_test(semanage_custom_suite(args.test)) def gen_semanage_test_args(parser): @@ -281,10 +281,8 @@ if __name__ == "__main__": gen_semanage_test_args(parser) try: args = parser.parse_args() - if args.func(args): - sys.exit(0) - else: - sys.exit(1) + args.func(args) + sys.exit(0) except ValueError as e: sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e))) sys.exit(1) diff --git a/python/sepolgen/VERSION b/python/sepolgen/VERSION index e6852d8a..9f55b2cc 100644 --- a/python/sepolgen/VERSION +++ b/python/sepolgen/VERSION @@ -1 +1 @@ -3.3-rc1 +3.0 diff --git a/python/sepolgen/src/sepolgen/output.py b/python/sepolgen/src/sepolgen/output.py index aeeaafc8..3a21b64c 100644 --- a/python/sepolgen/src/sepolgen/output.py +++ b/python/sepolgen/src/sepolgen/output.py @@ -84,7 +84,7 @@ def avrule_cmp(a, b): return ret # At this point, who cares - just return something - return 0 + return cmp(len(a.perms), len(b.perms)) # Compare two interface calls def ifcall_cmp(a, b): @@ -100,7 +100,7 @@ def rule_cmp(a, b): else: return id_set_cmp([a.args[0]], b.src_types) else: - if isinstance(b, refpolicy.AVRule) or isinstance(b, refpolicy.AVExtRule): + if isinstance(b, refpolicy.AVRule): return avrule_cmp(a,b) else: return id_set_cmp(a.src_types, [b.args[0]]) @@ -130,7 +130,6 @@ def sort_filter(module): # we assume is the first argument for interfaces). rules = [] rules.extend(node.avrules()) - rules.extend(node.avextrules()) rules.extend(node.interface_calls()) rules.sort(key=util.cmp_to_key(rule_cmp)) diff --git a/python/sepolgen/src/sepolgen/refparser.py b/python/sepolgen/src/sepolgen/refparser.py index e611637f..2e521a0f 100644 --- a/python/sepolgen/src/sepolgen/refparser.py +++ b/python/sepolgen/src/sepolgen/refparser.py @@ -126,7 +126,6 @@ tokens = ( 'GEN_REQ', 'TEMPLATE', 'GEN_CONTEXT', - 'GEN_TUNABLE', # m4 'IFELSE', 'IFDEF', @@ -193,7 +192,6 @@ reserved = { 'gen_require' : 'GEN_REQ', 'template' : 'TEMPLATE', 'gen_context' : 'GEN_CONTEXT', - 'gen_tunable' : 'GEN_TUNABLE', # M4 'ifelse' : 'IFELSE', 'ifndef' : 'IFNDEF', @@ -433,9 +431,9 @@ def p_ifelse(p): def p_ifdef(p): - '''ifdef : IFDEF OPAREN TICK IDENTIFIER SQUOTE COMMA TICK statements SQUOTE CPAREN optional_semi - | IFNDEF OPAREN TICK IDENTIFIER SQUOTE COMMA TICK statements SQUOTE CPAREN optional_semi - | IFDEF OPAREN TICK IDENTIFIER SQUOTE COMMA TICK statements SQUOTE COMMA TICK statements SQUOTE CPAREN optional_semi + '''ifdef : IFDEF OPAREN TICK IDENTIFIER SQUOTE COMMA TICK interface_stmts SQUOTE CPAREN optional_semi + | IFNDEF OPAREN TICK IDENTIFIER SQUOTE COMMA TICK interface_stmts SQUOTE CPAREN optional_semi + | IFDEF OPAREN TICK IDENTIFIER SQUOTE COMMA TICK interface_stmts SQUOTE COMMA TICK interface_stmts SQUOTE CPAREN optional_semi ''' x = refpolicy.IfDef(p[4]) if p[1] == 'ifdef': @@ -520,7 +518,6 @@ def p_policy_stmt(p): | range_transition_def | role_transition_def | bool - | gen_tunable | define | initial_sid | genfscon @@ -847,17 +844,6 @@ def p_bool(p): b.state = False p[0] = b -def p_gen_tunable(p): - '''gen_tunable : GEN_TUNABLE OPAREN TICK IDENTIFIER SQUOTE COMMA TRUE CPAREN - | GEN_TUNABLE OPAREN TICK IDENTIFIER SQUOTE COMMA FALSE CPAREN''' - b = refpolicy.Bool() - b.name = p[4] - if p[7] == "true": - b.state = True - else: - b.state = False - p[0] = b - def p_conditional(p): ''' conditional : IF OPAREN cond_expr CPAREN OBRACE interface_stmts CBRACE | IF OPAREN cond_expr CPAREN OBRACE interface_stmts CBRACE ELSE OBRACE interface_stmts CBRACE @@ -1148,6 +1134,6 @@ def parse_headers(root, output=None, expand=True, debug=False): status.step() if len(failures): - o("failed to parse some headers: %s\n" % ", ".join(failures)) + o("failed to parse some headers: %s" % ", ".join(failures)) return headers diff --git a/python/sepolgen/src/sepolgen/refpolicy.py b/python/sepolgen/src/sepolgen/refpolicy.py index 74763687..43cecfc7 100644 --- a/python/sepolgen/src/sepolgen/refpolicy.py +++ b/python/sepolgen/src/sepolgen/refpolicy.py @@ -407,9 +407,10 @@ class XpermSet(): # print single value without braces if len(self.ranges) == 1 and self.ranges[0][0] == self.ranges[0][1]: - return compl + hex(self.ranges[0][0]) + return compl + str(self.ranges[0][0]) - vals = map(lambda x: hex(x[0]) if x[0] == x[1] else "%s-%s" % (hex(x[0]), hex(x[1]), ), self.ranges) + vals = map(lambda x: str(x[0]) if x[0] == x[1] else "%s-%s" % x, + self.ranges) return "%s{ %s }" % (compl, " ".join(vals)) diff --git a/python/sepolgen/tests/test_access.py b/python/sepolgen/tests/test_access.py index 623588e0..73a5407d 100644 --- a/python/sepolgen/tests/test_access.py +++ b/python/sepolgen/tests/test_access.py @@ -171,7 +171,7 @@ class TestAccessVector(unittest.TestCase): a.merge(b) self.assertEqual(sorted(list(a.perms)), ["append", "read", "write"]) self.assertEqual(list(a.xperms.keys()), ["ioctl"]) - self.assertEqual(a.xperms["ioctl"].to_string(), "{ 0x2a 0x3039 }") + self.assertEqual(a.xperms["ioctl"].to_string(), "{ 42 12345 }") def text_merge_xperm2(self): """Test merging AV that does not contain xperms with AV that does""" @@ -185,7 +185,7 @@ class TestAccessVector(unittest.TestCase): a.merge(b) self.assertEqual(sorted(list(a.perms)), ["append", "read", "write"]) self.assertEqual(list(a.xperms.keys()), ["ioctl"]) - self.assertEqual(a.xperms["ioctl"].to_string(), "{ 0x2a 0x3039 }") + self.assertEqual(a.xperms["ioctl"].to_string(), "{ 42 12345 }") def test_merge_xperm_diff_op(self): """Test merging two AVs that contain xperms with different operation""" @@ -203,8 +203,8 @@ class TestAccessVector(unittest.TestCase): a.merge(b) self.assertEqual(list(a.perms), ["read"]) self.assertEqual(sorted(list(a.xperms.keys())), ["asdf", "ioctl"]) - self.assertEqual(a.xperms["asdf"].to_string(), "0x17") - self.assertEqual(a.xperms["ioctl"].to_string(), "{ 0x2a 0x3039 }") + self.assertEqual(a.xperms["asdf"].to_string(), "23") + self.assertEqual(a.xperms["ioctl"].to_string(), "{ 42 12345 }") def test_merge_xperm_same_op(self): """Test merging two AVs that contain xperms with same operation""" @@ -222,7 +222,7 @@ class TestAccessVector(unittest.TestCase): a.merge(b) self.assertEqual(list(a.perms), ["read"]) self.assertEqual(list(a.xperms.keys()), ["ioctl"]) - self.assertEqual(a.xperms["ioctl"].to_string(), "{ 0x17 0x2a 0x3039 }") + self.assertEqual(a.xperms["ioctl"].to_string(), "{ 23 42 12345 }") class TestUtilFunctions(unittest.TestCase): def test_is_idparam(self): diff --git a/python/sepolgen/tests/test_refpolicy.py b/python/sepolgen/tests/test_refpolicy.py index c7219fd5..4b50c8aa 100644 --- a/python/sepolgen/tests/test_refpolicy.py +++ b/python/sepolgen/tests/test_refpolicy.py @@ -90,17 +90,17 @@ class TestXpermSet(unittest.TestCase): a.complement = True self.assertEqual(a.to_string(), "") a.add(1234) - self.assertEqual(a.to_string(), "~ 0x4d2") + self.assertEqual(a.to_string(), "~ 1234") a.complement = False - self.assertEqual(a.to_string(), "0x4d2") + self.assertEqual(a.to_string(), "1234") a.add(2345) - self.assertEqual(a.to_string(), "{ 0x4d2 0x929 }") + self.assertEqual(a.to_string(), "{ 1234 2345 }") a.complement = True - self.assertEqual(a.to_string(), "~ { 0x4d2 0x929 }") + self.assertEqual(a.to_string(), "~ { 1234 2345 }") a.add(42,64) - self.assertEqual(a.to_string(), "~ { 0x2a-0x40 0x4d2 0x929 }") + self.assertEqual(a.to_string(), "~ { 42-64 1234 2345 }") a.complement = False - self.assertEqual(a.to_string(), "{ 0x2a-0x40 0x4d2 0x929 }") + self.assertEqual(a.to_string(), "{ 42-64 1234 2345 }") class TestSecurityContext(unittest.TestCase): def test_init(self): diff --git a/python/sepolicy/Makefile b/python/sepolicy/Makefile index 3361be4e..69f29fa9 100644 --- a/python/sepolicy/Makefile +++ b/python/sepolicy/Makefile @@ -27,7 +27,7 @@ test: @$(PYTHON) test_sepolicy.py -v install: - $(PYTHON) setup.py install --prefix=$(PREFIX) `test -n "$(DESTDIR)" && echo --root $(DESTDIR)` $(PYTHON_SETUP_ARGS) + $(PYTHON) setup.py install --prefix=$(PREFIX) `test -n "$(DESTDIR)" && echo --root $(DESTDIR)` [ -d $(DESTDIR)$(BINDIR) ] || mkdir -p $(DESTDIR)$(BINDIR) install -m 755 sepolicy.py $(DESTDIR)$(BINDIR)/sepolicy (cd $(DESTDIR)$(BINDIR); ln -sf sepolicy sepolgen) diff --git a/python/sepolicy/sepolicy/__init__.py b/python/sepolicy/sepolicy/__init__.py index e8654abb..e4540977 100644 --- a/python/sepolicy/sepolicy/__init__.py +++ b/python/sepolicy/sepolicy/__init__.py @@ -4,6 +4,7 @@ import errno import selinux +import setools import glob import sepolgen.defaults as defaults import sepolgen.interfaces as interfaces @@ -12,17 +13,6 @@ import os import re import gzip -from setools.boolquery import BoolQuery -from setools.portconquery import PortconQuery -from setools.policyrep import SELinuxPolicy -from setools.objclassquery import ObjClassQuery -from setools.rbacrulequery import RBACRuleQuery -from setools.rolequery import RoleQuery -from setools.terulequery import TERuleQuery -from setools.typeattrquery import TypeAttributeQuery -from setools.typequery import TypeQuery -from setools.userquery import UserQuery - PROGNAME = "policycoreutils" try: import gettext @@ -178,7 +168,7 @@ def policy(policy_file): global _pol try: - _pol = SELinuxPolicy(policy_file) + _pol = setools.SELinuxPolicy(policy_file) except: raise ValueError(_("Failed to read %s policy file") % policy_file) @@ -188,17 +178,17 @@ def load_store_policy(store): return None policy(policy_file) -def init_policy(): +try: policy_file = get_installed_policy() policy(policy_file) +except ValueError as e: + if selinux.is_selinux_enabled() == 1: + raise e + def info(setype, name=None): - global _pol - if not _pol: - init_policy() - if setype == TYPE: - q = TypeQuery(_pol) + q = setools.TypeQuery(_pol) q.name = name results = list(q.results()) @@ -216,7 +206,7 @@ def info(setype, name=None): } for x in results) elif setype == ROLE: - q = RoleQuery(_pol) + q = setools.RoleQuery(_pol) if name: q.name = name @@ -227,7 +217,7 @@ def info(setype, name=None): } for x in q.results()) elif setype == ATTRIBUTE: - q = TypeAttributeQuery(_pol) + q = setools.TypeAttributeQuery(_pol) if name: q.name = name @@ -237,7 +227,7 @@ def info(setype, name=None): } for x in q.results()) elif setype == PORT: - q = PortconQuery(_pol) + q = setools.PortconQuery(_pol) if name: ports = [int(i) for i in name.split("-")] if len(ports) == 2: @@ -261,7 +251,7 @@ def info(setype, name=None): } for x in q.results()) elif setype == USER: - q = UserQuery(_pol) + q = setools.UserQuery(_pol) if name: q.name = name @@ -278,7 +268,7 @@ def info(setype, name=None): } for x in q.results()) elif setype == BOOLEAN: - q = BoolQuery(_pol) + q = setools.BoolQuery(_pol) if name: q.name = name @@ -288,7 +278,7 @@ def info(setype, name=None): } for x in q.results()) elif setype == TCLASS: - q = ObjClassQuery(_pol) + q = setools.ObjClassQuery(_pol) if name: q.name = name @@ -347,9 +337,6 @@ def _setools_rule_to_dict(rule): def search(types, seinfo=None): - global _pol - if not _pol: - init_policy() if not seinfo: seinfo = {} valid_types = set([ALLOW, AUDITALLOW, NEVERALLOW, DONTAUDIT, TRANSITION, ROLE_ALLOW]) @@ -382,11 +369,11 @@ def search(types, seinfo=None): tertypes.append(DONTAUDIT) if len(tertypes) > 0: - q = TERuleQuery(_pol, - ruletype=tertypes, - source=source, - target=target, - tclass=tclass) + q = setools.TERuleQuery(_pol, + ruletype=tertypes, + source=source, + target=target, + tclass=tclass) if PERMS in seinfo: q.perms = seinfo[PERMS] @@ -395,11 +382,11 @@ def search(types, seinfo=None): if TRANSITION in types: rtypes = ['type_transition', 'type_change', 'type_member'] - q = TERuleQuery(_pol, - ruletype=rtypes, - source=source, - target=target, - tclass=tclass) + q = setools.TERuleQuery(_pol, + ruletype=rtypes, + source=source, + target=target, + tclass=tclass) if PERMS in seinfo: q.perms = seinfo[PERMS] @@ -408,11 +395,11 @@ def search(types, seinfo=None): if ROLE_ALLOW in types: ratypes = ['allow'] - q = RBACRuleQuery(_pol, - ruletype=ratypes, - source=source, - target=target, - tclass=tclass) + q = setools.RBACRuleQuery(_pol, + ruletype=ratypes, + source=source, + target=target, + tclass=tclass) for r in q.results(): toret.append({'source': str(r.source), @@ -730,11 +717,11 @@ def get_all_entrypoints(): def get_entrypoint_types(setype): - q = TERuleQuery(_pol, - ruletype=[ALLOW], - source=setype, - tclass=["file"], - perms=["entrypoint"]) + q = setools.TERuleQuery(_pol, + ruletype=[ALLOW], + source=setype, + tclass=["file"], + perms=["entrypoint"]) return [str(x.target) for x in q.results() if x.source == setype] @@ -749,10 +736,10 @@ def get_init_transtype(path): def get_init_entrypoint(transtype): - q = TERuleQuery(_pol, - ruletype=["type_transition"], - source="init_t", - tclass=["process"]) + q = setools.TERuleQuery(_pol, + ruletype=["type_transition"], + source="init_t", + tclass=["process"]) entrypoints = [] for i in q.results(): try: @@ -764,10 +751,10 @@ def get_init_entrypoint(transtype): return entrypoints def get_init_entrypoints_str(): - q = TERuleQuery(_pol, - ruletype=["type_transition"], - source="init_t", - tclass=["process"]) + q = setools.TERuleQuery(_pol, + ruletype=["type_transition"], + source="init_t", + tclass=["process"]) entrypoints = {} for i in q.results(): try: @@ -847,7 +834,7 @@ def get_all_role_allows(): return role_allows role_allows = {} - q = RBACRuleQuery(_pol, ruletype=[ALLOW]) + q = setools.RBACRuleQuery(_pol, ruletype=[ALLOW]) for r in q.results(): src = str(r.source) tgt = str(r.target) @@ -929,11 +916,7 @@ def get_all_roles(): if roles: return roles - global _pol - if not _pol: - init_policy() - - q = RoleQuery(_pol) + q = setools.RoleQuery(_pol) roles = [str(x) for x in q.results() if str(x) != "object_r"] return roles @@ -1049,7 +1032,7 @@ def get_description(f, markup=markup): return txt + "treat the files as %s key data." % prettyprint(f, "_key_t") if f.endswith("_secret_t"): - return txt + "treat the files as %s secret data." % prettyprint(f, "_secret_t") + return txt + "treat the files as %s secret data." % prettyprint(f, "_key_t") if f.endswith("_ra_t"): return txt + "treat the files as %s read/append content." % prettyprint(f, "_ra_t") @@ -1081,7 +1064,7 @@ def get_description(f, markup=markup): if f.endswith("_tmp_t"): return txt + "store %s temporary files in the /tmp directories." % prettyprint(f, "_tmp_t") if f.endswith("_etc_t"): - return txt + "store %s files in the /etc directories." % prettyprint(f, "_etc_t") + return txt + "store %s files in the /etc directories." % prettyprint(f, "_tmp_t") if f.endswith("_home_t"): return txt + "store %s files in the users home directory." % prettyprint(f, "_home_t") if f.endswith("_tmpfs_t"): diff --git a/python/sepolicy/sepolicy/generate.py b/python/sepolicy/sepolicy/generate.py index 4e1ed4e9..e8d07e7d 100644 --- a/python/sepolicy/sepolicy/generate.py +++ b/python/sepolicy/sepolicy/generate.py @@ -340,7 +340,7 @@ class policy: (self.generate_root_user_types, self.generate_root_user_rules), (self.generate_new_types, self.generate_new_rules)) if not re.match(r"^[a-zA-Z0-9-_]+$", name): - raise ValueError(_("Name must be alphanumeric with no spaces. Consider using option \"-n MODULENAME\"")) + raise ValueError(_("Name must be alpha numeric with no spaces. Consider using option \"-n MODULENAME\"")) if type == CGI: self.name = "httpd_%s_script" % name @@ -438,7 +438,7 @@ class policy: def set_init_script(self, initscript): if self.type != DAEMON: - raise ValueError(_("Only Daemon apps can use an init script.")) + raise ValueError(_("Only Daemon apps can use an init script..")) self.initscript = initscript diff --git a/python/sepolicy/sepolicy/interface.py b/python/sepolicy/sepolicy/interface.py index bdffb770..187419fa 100644 --- a/python/sepolicy/sepolicy/interface.py +++ b/python/sepolicy/sepolicy/interface.py @@ -146,12 +146,12 @@ def get_interface_dict(path="/usr/share/selinux/devel/policy.xml"): tree = xml.etree.ElementTree.fromstring(xml_path) for l in tree.findall("layer"): for m in l.findall("module"): - for i in m.iter('interface'): + for i in m.getiterator('interface'): for e in i.findall("param"): param_list.append(e.get('name')) interface_dict[(i.get("name"))] = [param_list, (i.find('summary').text), "interface"] param_list = [] - for i in m.iter('template'): + for i in m.getiterator('template'): for e in i.findall("param"): param_list.append(e.get('name')) interface_dict[(i.get("name"))] = [param_list, (i.find('summary').text), "template"] @@ -198,7 +198,7 @@ def get_xml_file(if_file): filename = os.path.basename(if_file).split(".")[0] rc, output = getstatusoutput("/usr/bin/python3 /usr/share/selinux/devel/include/support/segenxml.py -w -m %s" % (basedir + filename)) if rc != 0: - sys.stderr.write("\n Could not process selected interface file.\n") + sys.stderr.write("\n Could not proceed selected interface file.\n") sys.stderr.write("\n%s" % output) sys.exit(1) else: diff --git a/python/sepolicy/sepolicy/manpage.py b/python/sepolicy/sepolicy/manpage.py index 2f847abb..44260819 100755 --- a/python/sepolicy/sepolicy/manpage.py +++ b/python/sepolicy/sepolicy/manpage.py @@ -39,8 +39,6 @@ typealias_types = { equiv_dict = {"smbd": ["samba"], "httpd": ["apache"], "virtd": ["virt", "libvirt"], "named": ["bind"], "fsdaemon": ["smartmon"], "mdadm": ["raid"]} equiv_dirs = ["/var"] -man_date = time.strftime("%y-%m-%d", time.gmtime( - int(os.environ.get('SOURCE_DATE_EPOCH', time.time())))) modules_dict = None @@ -571,7 +569,7 @@ class ManPage: def _typealias(self,typealias): self.fd.write('.TH "%(typealias)s_selinux" "8" "%(date)s" "%(typealias)s" "SELinux Policy %(typealias)s"' - % {'typealias':typealias, 'date': man_date}) + % {'typealias':typealias, 'date': time.strftime("%y-%m-%d")}) self.fd.write(r""" .SH "NAME" %(typealias)s_selinux \- Security Enhanced Linux Policy for the %(typealias)s processes @@ -590,7 +588,7 @@ man page for more details. def _header(self): self.fd.write('.TH "%(domainname)s_selinux" "8" "%(date)s" "%(domainname)s" "SELinux Policy %(domainname)s"' - % {'domainname': self.domainname, 'date': man_date}) + % {'domainname': self.domainname, 'date': time.strftime("%y-%m-%d")}) self.fd.write(r""" .SH "NAME" %(domainname)s_selinux \- Security Enhanced Linux Policy for the %(domainname)s processes @@ -1076,7 +1074,7 @@ If you wanted to change the default user mapping to use the %(user)s_u user, you .B semanage login -m -s %(user)s_u __default__ -""" % {'desc': self.desc, 'user': self.domainname, 'range': self._get_users_range()}) +""" % {'desc': self.desc, 'type': self.type, 'user': self.domainname, 'range': self._get_users_range()}) if "login_userdomain" in self.attributes and "login_userdomain" in self.all_attributes: self.fd.write(""" @@ -1247,7 +1245,7 @@ Execute the following to see the types that the SELinux user %(type)s can execut .B $ sesearch -A -s %(type)s -c process -p transition -""" % {'type': self.type}) +""" % {'user': self.domainname, 'type': self.type}) def _role_header(self): self.fd.write('.TH "%(user)s_selinux" "8" "%(user)s" "mgrepl@redhat.com" "%(user)s SELinux Policy documentation"' diff --git a/python/sepolicy/sepolicy/network.py b/python/sepolicy/sepolicy/network.py index d26a7ce6..ff308fad 100755 --- a/python/sepolicy/sepolicy/network.py +++ b/python/sepolicy/sepolicy/network.py @@ -49,15 +49,15 @@ def get_network_connect(src, protocol, perm, check_bools=False): if "port_t" in tlist: continue if i == "port_t": - d[(src, protocol, perm)].append((i, ["all ports without defined types"])) + d[(src, protocol, perm)].append((i, ["all ports with out defined types"])) if i == "port_type": d[(src, protocol, perm)].append((i, ["all ports"])) elif i == "unreserved_port_type": - d[(src, protocol, perm)].append((i, ["all ports >= 1024"])) + d[(src, protocol, perm)].append((i, ["all ports > 1024"])) elif i == "reserved_port_type": d[(src, protocol, perm)].append((i, ["all ports < 1024"])) elif i == "rpc_port_type": - d[(src, protocol, perm)].append((i, ["all ports >= 512 and < 1024"])) + d[(src, protocol, perm)].append((i, ["all ports > 500 and < 1024"])) else: try: d[(src, protocol, perm)].append((i, portrecs[(i, protocol)])) diff --git a/python/sepolicy/sepolicy/sedbus.py b/python/sepolicy/sepolicy/sedbus.py index 39b53d47..76b259ae 100644 --- a/python/sepolicy/sepolicy/sedbus.py +++ b/python/sepolicy/sepolicy/sedbus.py @@ -2,6 +2,7 @@ import sys import dbus import dbus.service import dbus.mainloop.glib +from slip.dbus import polkit class SELinuxDBus (object): @@ -10,34 +11,42 @@ class SELinuxDBus (object): self.bus = dbus.SystemBus() self.dbus_object = self.bus.get_object("org.selinux", "/org/selinux/object") + @polkit.enable_proxy def semanage(self, buf): ret = self.dbus_object.semanage(buf, dbus_interface="org.selinux") return ret + @polkit.enable_proxy def restorecon(self, path): ret = self.dbus_object.restorecon(path, dbus_interface="org.selinux") return ret + @polkit.enable_proxy def setenforce(self, value): ret = self.dbus_object.setenforce(value, dbus_interface="org.selinux") return ret + @polkit.enable_proxy def customized(self): ret = self.dbus_object.customized(dbus_interface="org.selinux") return ret + @polkit.enable_proxy def semodule_list(self): ret = self.dbus_object.semodule_list(dbus_interface="org.selinux") return ret + @polkit.enable_proxy def relabel_on_boot(self, value): ret = self.dbus_object.relabel_on_boot(value, dbus_interface="org.selinux") return ret + @polkit.enable_proxy def change_default_mode(self, value): ret = self.dbus_object.change_default_mode(value, dbus_interface="org.selinux") return ret + @polkit.enable_proxy def change_default_policy(self, value): ret = self.dbus_object.change_default_policy(value, dbus_interface="org.selinux") return ret diff --git a/python/sepolicy/sepolicy/sepolicy.glade b/python/sepolicy/sepolicy/sepolicy.glade index 52407887..8f6ad650 100644 --- a/python/sepolicy/sepolicy/sepolicy.glade +++ b/python/sepolicy/sepolicy/sepolicy.glade @@ -2876,10 +2876,20 @@ Enabled + + + + + + 1 + + + + True - Executable File + Boolean name True True True diff --git a/python/sepolicy/setup.py b/python/sepolicy/setup.py index 2b1e4b50..fa60ef6c 100644 --- a/python/sepolicy/setup.py +++ b/python/sepolicy/setup.py @@ -6,7 +6,7 @@ from distutils.core import setup setup( name="sepolicy", - version="3.3-rc1", + version="3.0", description="Python SELinux Policy Analyses bindings", author="Daniel Walsh", author_email="dwalsh@redhat.com", diff --git a/restorecond/Makefile b/restorecond/Makefile index 8e9a5ef1..12452cd2 100644 --- a/restorecond/Makefile +++ b/restorecond/Makefile @@ -7,20 +7,19 @@ SBINDIR ?= $(PREFIX)/sbin MANDIR = $(PREFIX)/share/man AUTOSTARTDIR = /etc/xdg/autostart DBUSSERVICEDIR = $(PREFIX)/share/dbus-1/services -SYSTEMDSYSTEMUNITDIR ?= $(shell $(PKG_CONFIG) --variable=systemdsystemunitdir systemd) -SYSTEMDUSERUNITDIR ?= $(shell $(PKG_CONFIG) --variable=systemduserunitdir systemd) +SYSTEMDDIR ?= $(PREFIX)/lib/systemd autostart_DATA = sealertauto.desktop INITDIR ?= /etc/rc.d/init.d SELINUXDIR = /etc/selinux -GIO_CFLAGS = -DHAVE_DBUS $(shell $(PKG_CONFIG) --cflags gio-2.0) -GIO_LIBS = $(shell $(PKG_CONFIG) --libs gio-2.0) +DBUSFLAGS = -DHAVE_DBUS $(shell $(PKG_CONFIG) --cflags dbus-glib-1) +DBUSLIB = $(shell $(PKG_CONFIG) --libs dbus-glib-1) CFLAGS ?= -g -Werror -Wall -W -override CFLAGS += $(GIO_CFLAGS) +override CFLAGS += $(DBUSFLAGS) -override LDLIBS += -lselinux $(GIO_LIBS) +override LDLIBS += -lselinux $(DBUSLIB) all: restorecond @@ -49,10 +48,8 @@ install: all install -m 644 restorecond.desktop $(DESTDIR)$(AUTOSTARTDIR)/restorecond.desktop -mkdir -p $(DESTDIR)$(DBUSSERVICEDIR) install -m 644 org.selinux.Restorecond.service $(DESTDIR)$(DBUSSERVICEDIR)/org.selinux.Restorecond.service - -mkdir -p $(DESTDIR)$(SYSTEMDSYSTEMUNITDIR) - install -m 644 restorecond.service $(DESTDIR)$(SYSTEMDSYSTEMUNITDIR) - -mkdir -p $(DESTDIR)$(SYSTEMDUSERUNITDIR) - install -m 644 restorecond_user.service $(DESTDIR)$(SYSTEMDUSERUNITDIR) + -mkdir -p $(DESTDIR)$(SYSTEMDDIR)/system + install -m 644 restorecond.service $(DESTDIR)$(SYSTEMDDIR)/system/ relabel: install /sbin/restorecon $(DESTDIR)$(SBINDIR)/restorecond diff --git a/restorecond/VERSION b/restorecond/VERSION index e6852d8a..9f55b2cc 100644 --- a/restorecond/VERSION +++ b/restorecond/VERSION @@ -1 +1 @@ -3.3-rc1 +3.0 diff --git a/restorecond/org.selinux.Restorecond.service b/restorecond/org.selinux.Restorecond.service index 45aeb7aa..0ef5f0b5 100644 --- a/restorecond/org.selinux.Restorecond.service +++ b/restorecond/org.selinux.Restorecond.service @@ -1,4 +1,3 @@ [D-BUS Service] Name=org.selinux.Restorecond Exec=/usr/sbin/restorecond -u -SystemdService=restorecond_user.service diff --git a/restorecond/restorecond.desktop b/restorecond/restorecond.desktop index 7df85472..af728680 100644 --- a/restorecond/restorecond.desktop +++ b/restorecond/restorecond.desktop @@ -5,4 +5,3 @@ Comment=Fix file context in owned by the user Type=Application StartupNotify=false X-GNOME-Autostart-enabled=false -X-GNOME-HiddenUnderSystemd=true diff --git a/restorecond/restorecond_user.service b/restorecond/restorecond_user.service deleted file mode 100644 index 28ca770f..00000000 --- a/restorecond/restorecond_user.service +++ /dev/null @@ -1,10 +0,0 @@ -[Unit] -Description=Restorecon maintaining path file context (user service) -Documentation=man:restorecond(8) -ConditionPathExists=/etc/selinux/restorecond_user.conf -ConditionSecurity=selinux - -[Service] -Type=dbus -BusName=org.selinux.Restorecond -ExecStart=/usr/sbin/restorecond -u diff --git a/restorecond/user.c b/restorecond/user.c index 47b86823..8f932307 100644 --- a/restorecond/user.c +++ b/restorecond/user.c @@ -2,7 +2,6 @@ * restorecond * * Copyright (C) 2006-2009 Red Hat - * Copyright (C) 2020 Nicolas Iooss * see file 'COPYING' for use and warranty information * * This program is free software; you can redistribute it and/or @@ -22,7 +21,7 @@ * * Authors: * Dan Walsh - * Nicolas Iooss + * */ #define _GNU_SOURCE @@ -34,76 +33,73 @@ #include #include #include -#include #include #include #include #include #include -#include - #include "restorecond.h" #include "stringslist.h" #include -#include +#ifdef HAVE_DBUS +#include +#include +#include + +static DBusHandlerResult signal_filter (DBusConnection *connection, DBusMessage *message, void *user_data); + +static const char *PATH="/org/selinux/Restorecond"; +//static const char *BUSNAME="org.selinux.Restorecond"; +static const char *INTERFACE="org.selinux.RestorecondIface"; +static const char *RULE="type='signal',interface='org.selinux.RestorecondIface'"; static int local_lock_fd = -1; -#ifdef HAVE_DBUS -#include - -static const char *DBUS_NAME = "org.selinux.Restorecond"; - -static void on_name_acquired(GDBusConnection *connection G_GNUC_UNUSED, - const gchar *name, - gpointer user_data G_GNUC_UNUSED) +static DBusHandlerResult +signal_filter (DBusConnection *connection __attribute__ ((__unused__)), DBusMessage *message, void *user_data) { - if (debug_mode) - g_print("D-Bus name acquired: %s\n", name); + /* User data is the event loop we are running in */ + GMainLoop *loop = user_data; + + /* A signal from the bus saying we are about to be disconnected */ + if (dbus_message_is_signal + (message, INTERFACE, "Stop")) { + + /* Tell the main loop to quit */ + g_main_loop_quit (loop); + /* We have handled this message, don't pass it on */ + return DBUS_HANDLER_RESULT_HANDLED; + } + /* A Ping signal on the com.burtonini.dbus.Signal interface */ + else if (dbus_message_is_signal (message, INTERFACE, "Start")) { + DBusError error; + dbus_error_init (&error); + g_print("Start received\n"); + return DBUS_HANDLER_RESULT_HANDLED; + } + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -static void on_name_lost(GDBusConnection *connection G_GNUC_UNUSED, - const gchar *name, - gpointer user_data) -{ - /* Exit when the D-Bus connection closes */ - GMainLoop *loop = user_data; - - if (debug_mode) - g_print("D-Bus name lost (%s), exiting\n", name); - g_main_loop_quit(loop); -} - -/** - * Try starting a D-Bus server on the session bus. - * Returns -1 if the connection failed, so that a local server can be launched - */ -static int dbus_server(GMainLoop *loop) -{ - GDBusConnection *bus; - guint client_id; - - bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL); - if (!bus) - return -1; - - client_id = g_bus_own_name_on_connection( - bus, - DBUS_NAME, - G_BUS_NAME_OWNER_FLAGS_NONE, - on_name_acquired, - on_name_lost, - loop, - NULL); - g_object_unref(bus); - if (client_id == 0) - return -1; +static int dbus_server(GMainLoop *loop) { + DBusConnection *bus; + DBusError error; + dbus_error_init (&error); + bus = dbus_bus_get (DBUS_BUS_SESSION, &error); + if (bus) { + dbus_connection_setup_with_g_main (bus, NULL); + /* listening to messages from all objects as no path is specified */ + dbus_bus_add_match (bus, RULE, &error); // see signals from the given interfacey + dbus_connection_add_filter (bus, signal_filter, loop, NULL); return 0; + } + return -1; } #endif +#include +#include /* size of the event structure, not counting name */ #define EVENT_SIZE (sizeof (struct inotify_event)) @@ -171,42 +167,29 @@ io_channel_callback int start() { #ifdef HAVE_DBUS - GDBusConnection *bus; - GError *err = NULL; - GVariant *result; + DBusConnection *bus; + DBusError error; + DBusMessage *message; /* Get a connection to the session bus */ - bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &err); + dbus_error_init (&error); + bus = dbus_bus_get (DBUS_BUS_SESSION, &error); if (!bus) { if (debug_mode) - g_warning("Failed to connect to the D-BUS daemon: %s", err->message); - g_error_free(err); + g_warning ("Failed to connect to the D-BUS daemon: %s", error.message); + dbus_error_free (&error); return 1; } - /* Start restorecond D-Bus service by pinging its bus name - * - * https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-peer - */ - result = g_dbus_connection_call_sync(bus, - DBUS_NAME, /* bus name */ - "/", /* object path */ - "org.freedesktop.DBus.Peer", /* interface */ - "Ping", /* method */ - NULL, /* parameters */ - NULL, /* reply_type */ - G_DBUS_CALL_FLAGS_NONE, - -1, /* timeout_msec */ - NULL, - &err); - if (!result) { - g_object_unref(bus); - if (debug_mode) - g_warning("Failed to start %s: %s", DBUS_NAME, err->message); - g_error_free(err); - return 1; - } - g_object_unref(bus); + + /* Create a new signal "Start" on the interface, + * from the object */ + message = dbus_message_new_signal (PATH, + INTERFACE, "Start"); + /* Send the signal */ + dbus_connection_send (bus, message, NULL); + /* Free the signal now we have finished with it */ + dbus_message_unref (message); #endif /* HAVE_DBUS */ return 0; } @@ -230,10 +213,9 @@ static int local_server(void) { return -1; } if (flock(local_lock_fd, LOCK_EX | LOCK_NB) < 0) { + close(local_lock_fd); if (debug_mode) perror("flock"); - close(local_lock_fd); - local_lock_fd = -1; return -1; } /* watch for stdin/terminal going away */ @@ -252,54 +234,35 @@ static void end_local_server(void) { local_lock_fd = -1; } -static int sigterm_handler(gpointer user_data) -{ - GMainLoop *loop = user_data; - - if (debug_mode) - g_print("Received SIGTERM, exiting\n"); - g_main_loop_quit(loop); - return FALSE; -} - - int server(int master_fd, const char *watch_file) { - GMainLoop *loop; + GMainLoop *loop; - loop = g_main_loop_new (NULL, FALSE); + loop = g_main_loop_new (NULL, FALSE); #ifdef HAVE_DBUS - if (dbus_server(loop) != 0) + if (dbus_server(loop) != 0) #endif /* HAVE_DBUS */ - if (local_server()) - goto end; + if (local_server()) + goto end; - read_config(master_fd, watch_file); + read_config(master_fd, watch_file); - if (watch_list_isempty()) - goto end; + if (watch_list_isempty()) goto end; - set_matchpathcon_flags(MATCHPATHCON_NOTRANS); + set_matchpathcon_flags(MATCHPATHCON_NOTRANS); - GIOChannel *c = g_io_channel_unix_new(master_fd); + GIOChannel *c = g_io_channel_unix_new(master_fd); - g_io_add_watch_full(c, - G_PRIORITY_HIGH, - G_IO_IN|G_IO_ERR|G_IO_HUP, - io_channel_callback, NULL, NULL); + g_io_add_watch_full( c, + G_PRIORITY_HIGH, + G_IO_IN|G_IO_ERR|G_IO_HUP, + io_channel_callback, NULL, NULL); - /* Handle SIGTERM */ - g_unix_signal_add_full(G_PRIORITY_DEFAULT, - SIGTERM, - sigterm_handler, - loop, - NULL); - - g_main_loop_run (loop); + g_main_loop_run (loop); end: - end_local_server(); - g_main_loop_unref (loop); - return 0; + end_local_server(); + g_main_loop_unref (loop); + return 0; } diff --git a/sandbox/VERSION b/sandbox/VERSION index e6852d8a..9f55b2cc 100644 --- a/sandbox/VERSION +++ b/sandbox/VERSION @@ -1 +1 @@ -3.3-rc1 +3.0 diff --git a/sandbox/seunshare.c b/sandbox/seunshare.c index d626e98d..9707a456 100644 --- a/sandbox/seunshare.c +++ b/sandbox/seunshare.c @@ -431,13 +431,13 @@ static int cleanup_tmpdir(const char *tmpdir, const char *src, * to clean it up. */ static char *create_tmpdir(const char *src, struct stat *src_st, - struct stat *out_st, struct passwd *pwd, const char *execcon) + struct stat *out_st, struct passwd *pwd, security_context_t execcon) { char *tmpdir = NULL; char *cmdbuf = NULL; int fd_t = -1, fd_s = -1; struct stat tmp_st; - char *con = NULL; + security_context_t con = NULL; /* get selinux context */ if (execcon) { @@ -549,10 +549,10 @@ good: #define PROC_BASE "/proc" static int -killall (const char *execcon) +killall (security_context_t execcon) { DIR *dir; - char *scon; + security_context_t scon; struct dirent *de; pid_t *pid_table, pid, self; int i; @@ -615,7 +615,7 @@ killall (const char *execcon) int main(int argc, char **argv) { int status = -1; - const char *execcon = NULL; + security_context_t execcon = NULL; int clflag; /* holds codes for command line flags */ int kill_all = 0; diff --git a/scripts/ci/.gitignore b/scripts/ci/.gitignore deleted file mode 100644 index a977916f..00000000 --- a/scripts/ci/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.vagrant/ diff --git a/scripts/ci/LICENSE b/scripts/ci/LICENSE deleted file mode 100644 index 1f95d26c..00000000 --- a/scripts/ci/LICENSE +++ /dev/null @@ -1,5 +0,0 @@ -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/scripts/ci/README.md b/scripts/ci/README.md deleted file mode 100644 index 04a134a4..00000000 --- a/scripts/ci/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Continuous Integration Scripts - -The scripts under `scripts/ci` are designed specifically -for the Travis CI system. While nothing prevents you -from mimicking that environment and using them locally, -they are not applicable for general consumption. Any -thing in this directory should never be considered as -a stable API. diff --git a/scripts/ci/Vagrantfile b/scripts/ci/Vagrantfile deleted file mode 100644 index 20c523a0..00000000 --- a/scripts/ci/Vagrantfile +++ /dev/null @@ -1,48 +0,0 @@ -# -*- mode: ruby -*- -# vi: set ft=ruby : -# Vagrant configuration file which creates a virtual machine that can run the -# test suite using fedora-test-runner.sh, in an environment similar to the one -# used for automated continuous integration tests (Travis-CI) -# -# To create a new virtual machine: -# -# vagrant up --provision -# -# To launch tests (for example after modifications to libsepol, libselinux... are made): -# -# vagrant rsync && echo ./run-selinux-test.sh | vagrant ssh -# -# To destroy the virtual machine (for example to start again from a clean environment): -# -# vagrant destroy - -# Create a helper script in the VM to run the testsuite as root from a clean environment -$script = <