mirror of
https://github.com/topjohnwu/selinux.git
synced 2024-11-23 03:29:58 +00:00
Revert "Revert "Merge remote-tracking branch 'aosp/upstream-mast..."
Revert^2 "Use cil_write_build_ast" bde09de39feec91cf8220f0f798a6e52154d69e9 Change-Id: I3ab19bda9c1968409ad5a4f4d0866649036c683c
This commit is contained in:
parent
c65aca49bb
commit
454466e2e4
39
.github/workflows/cifuzz.yml
vendored
Normal file
39
.github/workflows/cifuzz.yml
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
---
|
||||
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
|
189
.github/workflows/run_tests.yml
vendored
Normal file
189
.github/workflows/run_tests.yml
vendored
Normal file
@ -0,0 +1,189 @@
|
||||
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::"
|
22
.github/workflows/vm_testsuite.yml
vendored
Normal file
22
.github/workflows/vm_testsuite.yml
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
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
|
158
.travis.yml
158
.travis.yml
@ -1,164 +1,12 @@
|
||||
# Define the building environment
|
||||
language: c
|
||||
|
||||
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
|
||||
# Use Travis-CI Ubuntu 18.04 Bionic Beaver, "full image" variant
|
||||
sudo: required
|
||||
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
|
||||
dist: bionic
|
||||
|
||||
script:
|
||||
# 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 '^')
|
||||
- FEDORA_MAJOR=33 FEDORA_MINOR=1.2 scripts/ci/travis-kvm-setup.sh
|
||||
|
||||
# Do not spam by email so long as the build succeeds
|
||||
notifications:
|
||||
|
25
README
25
README
@ -1,25 +0,0 @@
|
||||
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).
|
145
README.md
Normal file
145
README.md
Normal file
@ -0,0 +1,145 @@
|
||||
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 <selinux@vger.kernel.org>.
|
||||
|
||||
Subscribe by sending "subscribe selinux" in the body of an email
|
||||
to <majordomo@vger.kernel.org>.
|
||||
|
||||
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
|
@ -10,7 +10,7 @@ TARGETS = checkpolicy checkmodule
|
||||
LEX = flex
|
||||
YACC = bison -y
|
||||
|
||||
CFLAGS ?= -g -Wall -Werror -Wshadow -O2 -pipe -fno-strict-aliasing
|
||||
CFLAGS ?= -g -Wall -Werror -Wshadow -O2 -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) -o $@ $^ $(LDFLAGS) $(LDLIBS_LIBSEPOLA)
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LDLIBS_LIBSEPOLA)
|
||||
|
||||
checkmodule: $(CHECKMODOBJS) $(LIBSEPOLA)
|
||||
$(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS_LIBSEPOLA)
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LDLIBS_LIBSEPOLA)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
@ -1 +1 @@
|
||||
3.0
|
||||
3.3-rc1
|
||||
|
@ -28,6 +28,9 @@ 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
|
||||
@ -64,6 +67,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 Arpad Magosanyi <mag@bunuel.tii.matav.hu>,
|
||||
written by Árpád Magosányi <mag@bunuel.tii.matav.hu>,
|
||||
and edited by Dan Walsh <dwalsh@redhat.com>.
|
||||
The program was written by Stephen Smalley <sds@tycho.nsa.gov>.
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include <sepol/policydb/policydb.h>
|
||||
#include <sepol/policydb/services.h>
|
||||
#include <sepol/policydb/conditional.h>
|
||||
#include <sepol/policydb/flask.h>
|
||||
#include <sepol/policydb/hierarchy.h>
|
||||
#include <sepol/policydb/expand.h>
|
||||
#include <sepol/policydb/link.h>
|
||||
@ -41,6 +40,7 @@ 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] [-U handle_unknown] [-m] [-M] [-o FILE] [INPUT]\n", progname);
|
||||
printf("usage: %s [-h] [-V] [-b] [-C] [-E] [-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,6 +134,7 @@ 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");
|
||||
@ -162,10 +163,11 @@ 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:bVU:mMCc:", long_options, NULL)) != -1) {
|
||||
while ((ch = getopt_long(argc, argv, "ho:bVEU:mMCc:", long_options, NULL)) != -1) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
@ -180,6 +182,9 @@ 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;
|
||||
@ -283,14 +288,16 @@ 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);
|
||||
}
|
||||
char *out_name = basename(out_path);
|
||||
char *separator = strrchr(out_name, '.');
|
||||
out_name = basename(out_path);
|
||||
separator = strrchr(out_name, '.');
|
||||
if (separator) {
|
||||
*separator = '\0';
|
||||
}
|
||||
|
@ -53,6 +53,9 @@ 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
|
||||
@ -64,6 +67,6 @@ SELinux Reference Policy documentation at https://github.com/SELinuxProject/refp
|
||||
|
||||
|
||||
.SH AUTHOR
|
||||
This manual page was written by Arpad Magosanyi <mag@bunuel.tii.matav.hu>,
|
||||
This manual page was written by Árpád Magosányi <mag@bunuel.tii.matav.hu>,
|
||||
and edited by Stephen Smalley <sds@tycho.nsa.gov>.
|
||||
The program was written by Stephen Smalley <sds@tycho.nsa.gov>.
|
||||
|
@ -85,7 +85,6 @@
|
||||
#include <sepol/policydb/services.h>
|
||||
#include <sepol/policydb/conditional.h>
|
||||
#include <sepol/policydb/hierarchy.h>
|
||||
#include <sepol/policydb/flask.h>
|
||||
#include <sepol/policydb/expand.h>
|
||||
#include <sepol/policydb/link.h>
|
||||
|
||||
@ -101,29 +100,33 @@ 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 = POLICYDB_VERSION_MAX;
|
||||
unsigned int policyvers = 0;
|
||||
|
||||
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)] [-V] [input_file]\n",
|
||||
"[-t target_platform (selinux,xen)] [-E] [-V] [input_file]\n",
|
||||
progname, POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#define FGETS(out, size, in) \
|
||||
if (fgets(out,size,in)==NULL) { \
|
||||
fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__,\
|
||||
strerror(errno)); \
|
||||
exit(1);\
|
||||
}
|
||||
do { \
|
||||
if (fgets(out,size,in)==NULL) { \
|
||||
fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__, \
|
||||
strerror(errno)); \
|
||||
exit(1);\
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static int print_sid(sepol_security_id_t sid,
|
||||
context_struct_t * context
|
||||
__attribute__ ((unused)), void *data
|
||||
@ -421,11 +424,12 @@ 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:Oh", long_options, NULL)) != -1) {
|
||||
while ((ch = getopt_long(argc, argv, "o:t:dbU:MCFSVc:OEh", long_options, NULL)) != -1) {
|
||||
switch (ch) {
|
||||
case 'o':
|
||||
outfile = optarg;
|
||||
@ -500,10 +504,12 @@ int main(int argc, char **argv)
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
if (policyvers != n)
|
||||
policyvers = n;
|
||||
policyvers = n;
|
||||
break;
|
||||
}
|
||||
case 'E':
|
||||
werror = 1;
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
usage(argv[0]);
|
||||
@ -511,7 +517,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
if (show_version) {
|
||||
printf("%d (compatibility range %d-%d)\n", policyvers,
|
||||
printf("%d (compatibility range %d-%d)\n",
|
||||
policyvers ? policyvers : POLICYDB_VERSION_MAX ,
|
||||
POLICYDB_VERSION_MAX, POLICYDB_VERSION_MIN);
|
||||
exit(0);
|
||||
}
|
||||
@ -584,6 +591,16 @@ 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");
|
||||
@ -625,6 +642,8 @@ int main(int argc, char **argv)
|
||||
policydb_destroy(policydbp);
|
||||
policydbp = &policydb;
|
||||
}
|
||||
|
||||
policydbp->policyvers = policyvers ? policyvers : POLICYDB_VERSION_MAX;
|
||||
}
|
||||
|
||||
if (policydb_load_isids(&policydb, &sidtab))
|
||||
@ -650,8 +669,6 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
policydb.policyvers = policyvers;
|
||||
|
||||
if (!cil) {
|
||||
if (!conf) {
|
||||
policydb.policy_type = POLICY_KERN;
|
||||
@ -953,8 +970,12 @@ int main(int argc, char **argv)
|
||||
printf("fs kdevname? ");
|
||||
FGETS(ans, sizeof(ans), stdin);
|
||||
ans[strlen(ans) - 1] = 0;
|
||||
sepol_fs_sid(ans, &ssid, &tsid);
|
||||
printf("fs_sid %d default_file_sid %d\n", ssid, tsid);
|
||||
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);
|
||||
}
|
||||
break;
|
||||
case '9':
|
||||
printf("protocol? ");
|
||||
@ -982,8 +1003,12 @@ int main(int argc, char **argv)
|
||||
printf("netif name? ");
|
||||
FGETS(ans, sizeof(ans), stdin);
|
||||
ans[strlen(ans) - 1] = 0;
|
||||
sepol_netif_sid(ans, &ssid, &tsid);
|
||||
printf("if_sid %d default_msg_sid %d\n", ssid, tsid);
|
||||
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);
|
||||
}
|
||||
break;
|
||||
case 'b':{
|
||||
char *p;
|
||||
@ -1162,8 +1187,6 @@ 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 =
|
||||
@ -1215,8 +1238,6 @@ 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 =
|
||||
|
@ -28,7 +28,6 @@ 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);
|
||||
|
@ -53,7 +53,6 @@
|
||||
#include <sepol/policydb/policydb.h>
|
||||
#include <sepol/policydb/services.h>
|
||||
#include <sepol/policydb/conditional.h>
|
||||
#include <sepol/policydb/flask.h>
|
||||
#include <sepol/policydb/hierarchy.h>
|
||||
#include <sepol/policydb/polcaps.h>
|
||||
#include "queue.h"
|
||||
@ -78,7 +77,7 @@ extern int yyerror(const char *msg);
|
||||
#define ERRORMSG_LEN 255
|
||||
static char errormsg[ERRORMSG_LEN + 1] = {0};
|
||||
|
||||
static int id_has_dot(char *id);
|
||||
static int id_has_dot(const char *id);
|
||||
static int parse_security_context(context_struct_t *c);
|
||||
|
||||
/* initialize all of the state variables for the scanner/parser */
|
||||
@ -142,7 +141,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(char *id)
|
||||
static int id_has_dot(const char *id)
|
||||
{
|
||||
if (strchr(id, '.') >= id + 1) {
|
||||
return 1;
|
||||
@ -1169,11 +1168,6 @@ 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;
|
||||
@ -1802,7 +1796,7 @@ int define_bool_tunable(int is_tunable)
|
||||
return -1;
|
||||
}
|
||||
|
||||
datum->state = (int)(bool_value[0] == 'T') ? 1 : 0;
|
||||
datum->state = (bool_value[0] == 'T') ? 1 : 0;
|
||||
free(bool_value);
|
||||
return 0;
|
||||
cleanup:
|
||||
@ -1910,9 +1904,10 @@ int avrule_read_ioctls(struct av_ioctl_range_list **rangehead)
|
||||
{
|
||||
char *id;
|
||||
struct av_ioctl_range_list *rnew, *r = NULL;
|
||||
*rangehead = NULL;
|
||||
uint8_t omit = 0;
|
||||
|
||||
*rangehead = NULL;
|
||||
|
||||
/* read in all the ioctl commands */
|
||||
while ((id = queue_remove(id_queue))) {
|
||||
if (strcmp(id,"~") == 0) {
|
||||
@ -1948,7 +1943,9 @@ int avrule_read_ioctls(struct av_ioctl_range_list **rangehead)
|
||||
}
|
||||
}
|
||||
r = *rangehead;
|
||||
r->omit = omit;
|
||||
if (r) {
|
||||
r->omit = omit;
|
||||
}
|
||||
return 0;
|
||||
error:
|
||||
yyerror("out of memory");
|
||||
@ -2148,7 +2145,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) ((1 << (x & 0x1f)) - 1)
|
||||
#define XPERM_SETBITS(x) ((1U << (x & 0x1f)) - 1)
|
||||
/* low value for this u32 */
|
||||
#define XPERM_LOW(x) (x << 5)
|
||||
/* high value for this u32 */
|
||||
@ -2175,7 +2172,7 @@ void avrule_xperm_setrangebits(uint16_t low, uint16_t high,
|
||||
}
|
||||
}
|
||||
|
||||
int avrule_xperms_used(av_extended_perms_t *xperms)
|
||||
int avrule_xperms_used(const av_extended_perms_t *xperms)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
@ -2350,7 +2347,7 @@ unsigned int xperms_for_each_bit(unsigned int *bit, av_extended_perms_t *xperms)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int avrule_cpy(avrule_t *dest, avrule_t *src)
|
||||
int avrule_cpy(avrule_t *dest, const avrule_t *src)
|
||||
{
|
||||
class_perm_node_t *src_perms;
|
||||
class_perm_node_t *dest_perms, *dest_tail;
|
||||
@ -2398,7 +2395,7 @@ int avrule_cpy(avrule_t *dest, avrule_t *src)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int define_te_avtab_ioctl(avrule_t *avrule_template)
|
||||
int define_te_avtab_ioctl(const avrule_t *avrule_template)
|
||||
{
|
||||
avrule_t *avrule;
|
||||
struct av_ioctl_range_list *rangelist;
|
||||
@ -3304,8 +3301,6 @@ 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;
|
||||
@ -3389,40 +3384,19 @@ 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) {
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
yyerror("out of memory");
|
||||
goto bad;
|
||||
}
|
||||
@ -3470,9 +3444,10 @@ bad:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static constraint_expr_t *constraint_expr_clone(constraint_expr_t * expr)
|
||||
static constraint_expr_t *constraint_expr_clone(const constraint_expr_t * expr)
|
||||
{
|
||||
constraint_expr_t *h = NULL, *l = NULL, *e, *newe;
|
||||
constraint_expr_t *h = NULL, *l = NULL, *newe;
|
||||
const constraint_expr_t *e;
|
||||
for (e = expr; e; e = e->next) {
|
||||
newe = malloc(sizeof(*newe));
|
||||
if (!newe)
|
||||
@ -3503,12 +3478,7 @@ static constraint_expr_t *constraint_expr_clone(constraint_expr_t * expr)
|
||||
|
||||
return h;
|
||||
oom:
|
||||
e = h;
|
||||
while (e) {
|
||||
l = e;
|
||||
e = e->next;
|
||||
constraint_expr_destroy(l);
|
||||
}
|
||||
constraint_expr_destroy(h);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -4117,8 +4087,6 @@ 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);
|
||||
@ -4144,12 +4112,9 @@ 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");
|
||||
@ -5509,7 +5474,9 @@ 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) {
|
||||
@ -5571,30 +5538,39 @@ int define_genfs_context_helper(char *fstype, int has_type)
|
||||
}
|
||||
switch (type[0]) {
|
||||
case 'b':
|
||||
newc->v.sclass = SECCLASS_BLK_FILE;
|
||||
sclass = "blk_file";
|
||||
break;
|
||||
case 'c':
|
||||
newc->v.sclass = SECCLASS_CHR_FILE;
|
||||
sclass = "chr_file";
|
||||
break;
|
||||
case 'd':
|
||||
newc->v.sclass = SECCLASS_DIR;
|
||||
sclass = "dir";
|
||||
break;
|
||||
case 'p':
|
||||
newc->v.sclass = SECCLASS_FIFO_FILE;
|
||||
sclass = "fifo_file";
|
||||
break;
|
||||
case 'l':
|
||||
newc->v.sclass = SECCLASS_LNK_FILE;
|
||||
sclass = "lnk_file";
|
||||
break;
|
||||
case 's':
|
||||
newc->v.sclass = SECCLASS_SOCK_FILE;
|
||||
sclass = "sock_file";
|
||||
break;
|
||||
case '-':
|
||||
newc->v.sclass = SECCLASS_FILE;
|
||||
sclass = "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;
|
||||
|
@ -46,7 +46,6 @@
|
||||
#include <sepol/policydb/policydb.h>
|
||||
#include <sepol/policydb/services.h>
|
||||
#include <sepol/policydb/conditional.h>
|
||||
#include <sepol/policydb/flask.h>
|
||||
#include <sepol/policydb/hierarchy.h>
|
||||
#include <sepol/policydb/polcaps.h>
|
||||
#include "queue.h"
|
||||
|
@ -36,6 +36,8 @@ 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);
|
||||
@ -290,7 +292,7 @@ GLBLUB { return(GLBLUB); }
|
||||
"]" |
|
||||
"~" |
|
||||
"*" { return(yytext[0]); }
|
||||
. { yywarn("unrecognized character");}
|
||||
. { yyerror("unrecognized character");}
|
||||
%%
|
||||
int yyerror(const char *msg)
|
||||
{
|
||||
@ -310,6 +312,9 @@ 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);
|
||||
|
@ -50,7 +50,7 @@ $ checkmodule \-M \-m httpd.te \-o httpd.mod
|
||||
|
||||
|
||||
.SH АВТОРЫ
|
||||
Эта страница руководства была скопирована со страницы руководства checkpolicy, написанной Arpad Magosanyi <mag@bunuel.tii.matav.hu>,
|
||||
Эта страница руководства была скопирована со страницы руководства checkpolicy, написанной Árpád Magosányi <mag@bunuel.tii.matav.hu>,
|
||||
и отредактирована Dan Walsh <dwalsh@redhat.com>.
|
||||
Программа была написана Stephen Smalley <sds@tycho.nsa.gov>.
|
||||
Перевод на русский язык выполнила Герасименко Олеся <gammaray@basealt.ru>.
|
||||
Перевод на русский язык выполнила Олеся Герасименко <gammaray@basealt.ru>.
|
||||
|
@ -54,7 +54,7 @@ checkpolicy \- компилятор политики SELinux
|
||||
Документация SELinux Reference Policy по адресу https://github.com/SELinuxProject/refpolicy/wiki
|
||||
|
||||
.SH АВТОРЫ
|
||||
Эта страница руководства была написана Arpad Magosanyi <mag@bunuel.tii.matav.hu>,
|
||||
Эта страница руководства была написана Árpád Magosányi <mag@bunuel.tii.matav.hu>,
|
||||
и отредактирована Stephen Smalley <sds@tycho.nsa.gov>.
|
||||
Программа была написана Stephen Smalley <sds@tycho.nsa.gov>.
|
||||
Перевод на русский язык выполнила Герасименко Олеся <gammaray@basealt.ru>.
|
||||
Перевод на русский язык выполнила Олеся Герасименко <gammaray@basealt.ru>.
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Makefile for building the dispol program
|
||||
#
|
||||
CFLAGS ?= -g -Wall -W -Werror -O2 -pipe
|
||||
CFLAGS ?= -g -Wall -W -Werror -O2
|
||||
|
||||
# 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) $(LDFLAGS) -o $@ $^ $(LDLIBS_LIBSEPOLA)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS_LIBSEPOLA)
|
||||
|
||||
dismod: dismod.o $(LIBSEPOLA)
|
||||
$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS_LIBSEPOLA)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS_LIBSEPOLA)
|
||||
|
||||
clean:
|
||||
-rm -f dispol dismod *.o
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include <sepol/policydb/policydb.h>
|
||||
#include <sepol/policydb/services.h>
|
||||
#include <sepol/policydb/conditional.h>
|
||||
#include <sepol/policydb/flask.h>
|
||||
#include <sepol/policydb/link.h>
|
||||
#include <sepol/policydb/module.h>
|
||||
#include <sepol/policydb/util.h>
|
||||
@ -112,7 +111,7 @@ static void display_id(policydb_t * p, FILE * fp, uint32_t symbol_type,
|
||||
}
|
||||
}
|
||||
|
||||
int display_type_set(type_set_t * set, uint32_t flags, policydb_t * policy,
|
||||
static int display_type_set(type_set_t * set, uint32_t flags, policydb_t * policy,
|
||||
FILE * fp)
|
||||
{
|
||||
unsigned int i, num_types;
|
||||
@ -176,7 +175,7 @@ int display_type_set(type_set_t * set, uint32_t flags, policydb_t * policy,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int display_mod_role_set(role_set_t * roles, policydb_t * p, FILE * fp)
|
||||
static int display_mod_role_set(role_set_t * roles, policydb_t * p, FILE * fp)
|
||||
{
|
||||
unsigned int i, num = 0;
|
||||
|
||||
@ -211,7 +210,7 @@ int display_mod_role_set(role_set_t * roles, policydb_t * p, FILE * fp)
|
||||
|
||||
}
|
||||
|
||||
int display_avrule(avrule_t * avrule, policydb_t * policy,
|
||||
static int display_avrule(avrule_t * avrule, policydb_t * policy,
|
||||
FILE * fp)
|
||||
{
|
||||
class_perm_node_t *cur;
|
||||
@ -314,7 +313,7 @@ int display_avrule(avrule_t * avrule, policydb_t * policy,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int display_type_callback(hashtab_key_t key, hashtab_datum_t datum, void *data)
|
||||
static int display_type_callback(hashtab_key_t key, hashtab_datum_t datum, void *data)
|
||||
{
|
||||
type_datum_t *type;
|
||||
FILE *fp;
|
||||
@ -356,14 +355,14 @@ int display_type_callback(hashtab_key_t key, hashtab_datum_t datum, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int display_types(policydb_t * p, FILE * fp)
|
||||
static int display_types(policydb_t * p, FILE * fp)
|
||||
{
|
||||
if (hashtab_map(p->p_types.table, display_type_callback, fp))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int display_users(policydb_t * p, FILE * fp)
|
||||
static int display_users(policydb_t * p, FILE * fp)
|
||||
{
|
||||
unsigned int i, j;
|
||||
ebitmap_t *bitmap;
|
||||
@ -382,7 +381,7 @@ int display_users(policydb_t * p, FILE * fp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int display_bools(policydb_t * p, FILE * fp)
|
||||
static int display_bools(policydb_t * p, FILE * fp)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
@ -393,7 +392,7 @@ int display_bools(policydb_t * p, FILE * fp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void display_expr(policydb_t * p, cond_expr_t * exp, FILE * fp)
|
||||
static void display_expr(policydb_t * p, cond_expr_t * exp, FILE * fp)
|
||||
{
|
||||
|
||||
cond_expr_t *cur;
|
||||
@ -428,14 +427,14 @@ void display_expr(policydb_t * p, cond_expr_t * exp, FILE * fp)
|
||||
}
|
||||
}
|
||||
|
||||
void display_policycon(FILE * fp)
|
||||
static 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");
|
||||
}
|
||||
|
||||
void display_initial_sids(policydb_t * p, FILE * fp)
|
||||
static void display_initial_sids(policydb_t * p, FILE * fp)
|
||||
{
|
||||
ocontext_t *cur;
|
||||
char *user, *role, *type;
|
||||
@ -460,7 +459,7 @@ void display_initial_sids(policydb_t * p, FILE * fp)
|
||||
#endif
|
||||
}
|
||||
|
||||
void display_class_set(ebitmap_t *classes, policydb_t *p, FILE *fp)
|
||||
static void display_class_set(ebitmap_t *classes, policydb_t *p, FILE *fp)
|
||||
{
|
||||
unsigned int i, num = 0;
|
||||
|
||||
@ -483,7 +482,7 @@ void display_class_set(ebitmap_t *classes, policydb_t *p, FILE *fp)
|
||||
fprintf(fp, " }");
|
||||
}
|
||||
|
||||
void display_role_trans(role_trans_rule_t * tr, policydb_t * p, FILE * fp)
|
||||
static void display_role_trans(role_trans_rule_t * tr, policydb_t * p, FILE * fp)
|
||||
{
|
||||
for (; tr; tr = tr->next) {
|
||||
fprintf(fp, "role transition ");
|
||||
@ -496,7 +495,7 @@ void display_role_trans(role_trans_rule_t * tr, policydb_t * p, FILE * fp)
|
||||
}
|
||||
}
|
||||
|
||||
void display_role_allow(role_allow_rule_t * ra, policydb_t * p, FILE * fp)
|
||||
static void display_role_allow(role_allow_rule_t * ra, policydb_t * p, FILE * fp)
|
||||
{
|
||||
for (; ra; ra = ra->next) {
|
||||
fprintf(fp, "role allow ");
|
||||
@ -518,7 +517,7 @@ static void display_filename_trans(filename_trans_rule_t * tr, policydb_t * p, F
|
||||
}
|
||||
}
|
||||
|
||||
int role_display_callback(hashtab_key_t key __attribute__((unused)),
|
||||
static int role_display_callback(hashtab_key_t key __attribute__((unused)),
|
||||
hashtab_datum_t datum, void *data)
|
||||
{
|
||||
role_datum_t *role;
|
||||
@ -612,7 +611,7 @@ int change_bool(char *name, int state, policydb_t * p, FILE * fp)
|
||||
}
|
||||
#endif
|
||||
|
||||
int display_avdecl(avrule_decl_t * decl, int field,
|
||||
static 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,
|
||||
@ -693,13 +692,13 @@ int display_avdecl(avrule_decl_t * decl, int field,
|
||||
return 0; /* should never get here */
|
||||
}
|
||||
|
||||
int display_avblock(int field, policydb_t * policy,
|
||||
static int display_avblock(int field, policydb_t * policy,
|
||||
FILE * out_fp)
|
||||
{
|
||||
avrule_block_t *block = policydb.global;
|
||||
while (block != NULL) {
|
||||
fprintf(out_fp, "--- begin avrule block ---\n");
|
||||
avrule_decl_t *decl = block->branch_list;
|
||||
fprintf(out_fp, "--- begin avrule block ---\n");
|
||||
while (decl != NULL) {
|
||||
if (display_avdecl(decl, field, policy, out_fp)) {
|
||||
return -1;
|
||||
@ -711,7 +710,7 @@ int display_avblock(int field, policydb_t * policy,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int display_handle_unknown(policydb_t * p, FILE * out_fp)
|
||||
static 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");
|
||||
@ -828,14 +827,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 (%d)", i);
|
||||
snprintf(buf, sizeof(buf), "unknown (%u)", i);
|
||||
capname = buf;
|
||||
}
|
||||
fprintf(fp, "\t%s\n", capname);
|
||||
}
|
||||
}
|
||||
|
||||
int menu(void)
|
||||
static int menu(void)
|
||||
{
|
||||
printf("\nSelect a command:\n");
|
||||
printf("1) display unconditional AVTAB\n");
|
||||
|
@ -42,7 +42,7 @@ static __attribute__((__noreturn__)) void usage(const char *progname)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int render_access_mask(uint32_t mask, avtab_key_t * key, policydb_t * p,
|
||||
static int render_access_mask(uint32_t mask, avtab_key_t * key, policydb_t * p,
|
||||
FILE * fp)
|
||||
{
|
||||
char *perm;
|
||||
@ -54,13 +54,13 @@ int render_access_mask(uint32_t mask, avtab_key_t * key, policydb_t * p,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int render_type(uint32_t type, policydb_t * p, FILE * fp)
|
||||
static int render_type(uint32_t type, policydb_t * p, FILE * fp)
|
||||
{
|
||||
fprintf(fp, "%s", p->p_type_val_to_name[type - 1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int render_key(avtab_key_t * key, policydb_t * p, FILE * fp)
|
||||
static 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 @@ int render_key(avtab_key_t * key, policydb_t * p, FILE * fp)
|
||||
#define RENDER_DISABLED 0x0004
|
||||
#define RENDER_CONDITIONAL (RENDER_ENABLED|RENDER_DISABLED)
|
||||
|
||||
int render_av_rule(avtab_key_t * key, avtab_datum_t * datum, uint32_t what,
|
||||
static 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 @@ int render_av_rule(avtab_key_t * key, avtab_datum_t * datum, uint32_t what,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int display_avtab(avtab_t * a, uint32_t what, policydb_t * p, FILE * fp)
|
||||
static 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 @@ int display_avtab(avtab_t * a, uint32_t what, policydb_t * p, FILE * fp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int display_bools(policydb_t * p, FILE * fp)
|
||||
static int display_bools(policydb_t * p, FILE * fp)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
@ -189,7 +189,7 @@ int display_bools(policydb_t * p, FILE * fp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void display_expr(policydb_t * p, cond_expr_t * exp, FILE * fp)
|
||||
static void display_expr(policydb_t * p, cond_expr_t * exp, FILE * fp)
|
||||
{
|
||||
|
||||
cond_expr_t *cur;
|
||||
@ -224,7 +224,7 @@ void display_expr(policydb_t * p, cond_expr_t * exp, FILE * fp)
|
||||
}
|
||||
}
|
||||
|
||||
int display_cond_expressions(policydb_t * p, FILE * fp)
|
||||
static int display_cond_expressions(policydb_t * p, FILE * fp)
|
||||
{
|
||||
cond_node_t *cur;
|
||||
cond_av_list_t *av_cur;
|
||||
@ -249,7 +249,7 @@ int display_cond_expressions(policydb_t * p, FILE * fp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int display_handle_unknown(policydb_t * p, FILE * out_fp)
|
||||
static 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 @@ int display_handle_unknown(policydb_t * p, FILE * out_fp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int change_bool(char *name, int state, policydb_t * p, FILE * fp)
|
||||
static 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 (%d)", i);
|
||||
snprintf(buf, sizeof(buf), "unknown (%u)", i);
|
||||
capname = buf;
|
||||
}
|
||||
fprintf(fp, "\t%s\n", capname);
|
||||
@ -335,17 +335,25 @@ static int filenametr_display(hashtab_key_t key,
|
||||
hashtab_datum_t datum,
|
||||
void *ptr)
|
||||
{
|
||||
struct filename_trans *ft = (struct filename_trans *)key;
|
||||
struct filename_trans_key *ft = (struct filename_trans_key *)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;
|
||||
}
|
||||
|
||||
@ -360,7 +368,7 @@ static void display_filename_trans(policydb_t *p, FILE *fp)
|
||||
hashtab_map(p->filename_trans, filenametr_display, &args);
|
||||
}
|
||||
|
||||
int menu(void)
|
||||
static int menu(void)
|
||||
{
|
||||
printf("\nSelect a command:\n");
|
||||
printf("1) display unconditional AVTAB\n");
|
||||
|
@ -1 +1 @@
|
||||
3.0
|
||||
3.3-rc1
|
||||
|
@ -2,28 +2,36 @@
|
||||
|
||||
import dbus
|
||||
import dbus.service
|
||||
import dbus.mainloop.glib
|
||||
from dbus.mainloop.glib import DBusGMainLoop
|
||||
from gi.repository import GObject
|
||||
import slip.dbus.service
|
||||
from slip.dbus import polkit
|
||||
from gi.repository import GLib
|
||||
import os
|
||||
import selinux
|
||||
from subprocess import Popen, PIPE, STDOUT
|
||||
|
||||
|
||||
class selinux_server(slip.dbus.service.Object):
|
||||
class selinux_server(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
|
||||
#
|
||||
@slip.dbus.polkit.require_auth("org.selinux.semanage")
|
||||
@dbus.service.method("org.selinux", in_signature='s')
|
||||
def semanage(self, buf):
|
||||
@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")
|
||||
p = Popen(["/usr/sbin/semanage", "import"], stdout=PIPE, stderr=PIPE, stdin=PIPE, universal_newlines=True)
|
||||
p.stdin.write(buf)
|
||||
output = p.communicate()
|
||||
@ -35,9 +43,10 @@ class selinux_server(slip.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.
|
||||
#
|
||||
@slip.dbus.polkit.require_auth("org.selinux.customized")
|
||||
@dbus.service.method("org.selinux", in_signature='', out_signature='s')
|
||||
def customized(self):
|
||||
@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")
|
||||
p = Popen(["/usr/sbin/semanage", "export"], stdout=PIPE, stderr=PIPE, universal_newlines=True)
|
||||
buf = p.stdout.read()
|
||||
output = p.communicate()
|
||||
@ -49,9 +58,10 @@ class selinux_server(slip.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
|
||||
#
|
||||
@slip.dbus.polkit.require_auth("org.selinux.semodule_list")
|
||||
@dbus.service.method("org.selinux", in_signature='', out_signature='s')
|
||||
def semodule_list(self):
|
||||
@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")
|
||||
p = Popen(["/usr/sbin/semodule", "--list=full"], stdout=PIPE, stderr=PIPE, universal_newlines=True)
|
||||
buf = p.stdout.read()
|
||||
output = p.communicate()
|
||||
@ -62,25 +72,28 @@ class selinux_server(slip.dbus.service.Object):
|
||||
#
|
||||
# The restorecon method modifies any file path to the default system label
|
||||
#
|
||||
@slip.dbus.polkit.require_auth("org.selinux.restorecon")
|
||||
@dbus.service.method("org.selinux", in_signature='s')
|
||||
def restorecon(self, path):
|
||||
@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")
|
||||
selinux.restorecon(str(path), recursive=1)
|
||||
|
||||
#
|
||||
# The setenforce method turns off the current enforcement of SELinux
|
||||
#
|
||||
@slip.dbus.polkit.require_auth("org.selinux.setenforce")
|
||||
@dbus.service.method("org.selinux", in_signature='i')
|
||||
def setenforce(self, value):
|
||||
@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")
|
||||
selinux.security_setenforce(value)
|
||||
|
||||
#
|
||||
# The setenforce method turns off the current enforcement of SELinux
|
||||
#
|
||||
@slip.dbus.polkit.require_auth("org.selinux.relabel_on_boot")
|
||||
@dbus.service.method("org.selinux", in_signature='i')
|
||||
def relabel_on_boot(self, value):
|
||||
@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")
|
||||
if value == 1:
|
||||
fd = open("/.autorelabel", "w")
|
||||
fd.close()
|
||||
@ -111,9 +124,10 @@ class selinux_server(slip.dbus.service.Object):
|
||||
#
|
||||
# The change_default_enforcement modifies the current enforcement mode
|
||||
#
|
||||
@slip.dbus.polkit.require_auth("org.selinux.change_default_mode")
|
||||
@dbus.service.method("org.selinux", in_signature='s')
|
||||
def change_default_mode(self, value):
|
||||
@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")
|
||||
values = ["enforcing", "permissive", "disabled"]
|
||||
if value not in values:
|
||||
raise ValueError("Enforcement mode must be %s" % ", ".join(values))
|
||||
@ -122,19 +136,20 @@ class selinux_server(slip.dbus.service.Object):
|
||||
#
|
||||
# The change_default_policy method modifies the policy type
|
||||
#
|
||||
@slip.dbus.polkit.require_auth("org.selinux.change_default_policy")
|
||||
@dbus.service.method("org.selinux", in_signature='s')
|
||||
def change_default_policy(self, value):
|
||||
@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")
|
||||
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__":
|
||||
mainloop = GObject.MainLoop()
|
||||
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
|
||||
DBusGMainLoop(set_as_default=True)
|
||||
mainloop = GLib.MainLoop()
|
||||
|
||||
system_bus = dbus.SystemBus()
|
||||
name = dbus.service.BusName("org.selinux", system_bus)
|
||||
object = selinux_server(system_bus, "/org/selinux/object")
|
||||
slip.dbus.service.set_mainloop(mainloop)
|
||||
server = selinux_server(system_bus, "/org/selinux/object")
|
||||
mainloop.run()
|
||||
|
@ -1 +1 @@
|
||||
3.0
|
||||
3.3-rc1
|
||||
|
@ -102,6 +102,13 @@ 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")
|
||||
|
||||
|
@ -401,32 +401,6 @@ Level</property>
|
||||
<!-- column-name gchararray -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
<data>
|
||||
<row>
|
||||
<col id="0" translatable="yes">all files</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">regular file</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">directory</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">character device</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">block device</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">socket file</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">symbolic link</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">named pipe</col>
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkDialog" id="fcontextDialog">
|
||||
<property name="can_focus">False</property>
|
||||
|
@ -1,9 +1,10 @@
|
||||
SUBDIRS = src include utils man
|
||||
SUBDIRS = include src 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
|
||||
@ -17,7 +18,10 @@ endif
|
||||
ifeq ($(DISABLE_BOOL),y)
|
||||
DISABLE_FLAGS+= -DDISABLE_BOOL
|
||||
endif
|
||||
export DISABLE_SETRANS DISABLE_RPM DISABLE_FLAGS ANDROID_HOST
|
||||
ifeq ($(DISABLE_X11),y)
|
||||
DISABLE_FLAGS+= -DNO_X_BACKEND
|
||||
endif
|
||||
export DISABLE_SETRANS DISABLE_RPM DISABLE_FLAGS ANDROID_HOST DISABLE_X11 LABEL_BACKEND_ANDROID
|
||||
|
||||
USE_PCRE2 ?= n
|
||||
ifeq ($(USE_PCRE2),y)
|
||||
@ -46,24 +50,24 @@ all install relabel clean distclean indent:
|
||||
done
|
||||
|
||||
swigify: all
|
||||
$(MAKE) -C src swigify $@
|
||||
$(MAKE) -C src $@
|
||||
|
||||
pywrap:
|
||||
$(MAKE) -C src pywrap $@
|
||||
$(MAKE) -C src $@
|
||||
|
||||
rubywrap:
|
||||
$(MAKE) -C src rubywrap $@
|
||||
$(MAKE) -C src $@
|
||||
|
||||
install-pywrap:
|
||||
$(MAKE) -C src install-pywrap $@
|
||||
$(MAKE) -C src $@
|
||||
|
||||
install-rubywrap:
|
||||
$(MAKE) -C src install-rubywrap $@
|
||||
$(MAKE) -C src $@
|
||||
|
||||
clean-pywrap:
|
||||
$(MAKE) -C src clean-pywrap $@
|
||||
$(MAKE) -C src $@
|
||||
|
||||
clean-rubywrap:
|
||||
$(MAKE) -C src clean-rubywrap $@
|
||||
$(MAKE) -C src $@
|
||||
|
||||
test:
|
||||
|
@ -1 +1 @@
|
||||
3.0
|
||||
3.3-rc1
|
||||
|
@ -64,7 +64,11 @@ 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);
|
||||
extern int sidget(security_id_t sid)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((deprecated))
|
||||
#endif
|
||||
;
|
||||
|
||||
/**
|
||||
* sidput - decrement SID reference counter.
|
||||
@ -76,7 +80,11 @@ extern int sidget(security_id_t sid);
|
||||
* 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);
|
||||
extern int sidput(security_id_t sid)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((deprecated))
|
||||
#endif
|
||||
;
|
||||
|
||||
/**
|
||||
* avc_get_initial_sid - get SID for an initial kernel security identifier
|
||||
@ -192,7 +200,11 @@ 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);
|
||||
const struct avc_lock_callback *lock_callbacks)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((deprecated("Use avc_open and selinux_set_callback")))
|
||||
#endif
|
||||
;
|
||||
|
||||
/**
|
||||
* avc_open - Initialize the AVC.
|
||||
|
@ -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,
|
||||
char * fromcon,
|
||||
const 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,
|
||||
char * fromcon,
|
||||
const 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,
|
||||
char * fromcon,
|
||||
const 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,
|
||||
char * fromcon,
|
||||
const 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,
|
||||
char * fromcon,
|
||||
const 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,
|
||||
char * fromcon,
|
||||
const char *fromcon,
|
||||
char ** newcon);
|
||||
|
||||
/* Given a list of authorized security contexts for the user,
|
||||
|
@ -30,77 +30,82 @@ 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 0x0001
|
||||
#define SELINUX_RESTORECON_IGNORE_DIGEST 0x00001
|
||||
/*
|
||||
* Do not change file labels.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_NOCHANGE 0x0002
|
||||
#define SELINUX_RESTORECON_NOCHANGE 0x00002
|
||||
/*
|
||||
* 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 0x0004
|
||||
#define SELINUX_RESTORECON_SET_SPECFILE_CTX 0x00004
|
||||
/*
|
||||
* Recursively descend directories.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_RECURSE 0x0008
|
||||
#define SELINUX_RESTORECON_RECURSE 0x00008
|
||||
/*
|
||||
* Log changes to selinux log. Note that if VERBOSE and
|
||||
* PROGRESS are set, then PROGRESS will take precedence.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_VERBOSE 0x0010
|
||||
#define SELINUX_RESTORECON_VERBOSE 0x00010
|
||||
/*
|
||||
* 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 0x0020
|
||||
#define SELINUX_RESTORECON_PROGRESS 0x00020
|
||||
/*
|
||||
* Convert passed-in pathname to canonical pathname.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_REALPATH 0x0040
|
||||
#define SELINUX_RESTORECON_REALPATH 0x00040
|
||||
/*
|
||||
* Prevent descending into directories that have a different
|
||||
* device number than the pathname from which the descent began.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_XDEV 0x0080
|
||||
#define SELINUX_RESTORECON_XDEV 0x00080
|
||||
/*
|
||||
* 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 0x0100
|
||||
#define SELINUX_RESTORECON_ADD_ASSOC 0x00100
|
||||
/*
|
||||
* Abort on errors during the file tree walk.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_ABORT_ON_ERROR 0x0200
|
||||
#define SELINUX_RESTORECON_ABORT_ON_ERROR 0x00200
|
||||
/*
|
||||
* Log any label changes to syslog.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_SYSLOG_CHANGES 0x0400
|
||||
#define SELINUX_RESTORECON_SYSLOG_CHANGES 0x00400
|
||||
/*
|
||||
* Log what spec matched each file.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_LOG_MATCHES 0x0800
|
||||
#define SELINUX_RESTORECON_LOG_MATCHES 0x00800
|
||||
/*
|
||||
* Ignore files that do not exist.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_IGNORE_NOENTRY 0x1000
|
||||
#define SELINUX_RESTORECON_IGNORE_NOENTRY 0x01000
|
||||
/*
|
||||
* Do not read /proc/mounts to obtain a list of non-seclabel
|
||||
* mounts to be excluded from relabeling checks.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_IGNORE_MOUNTS 0x2000
|
||||
#define SELINUX_RESTORECON_IGNORE_MOUNTS 0x02000
|
||||
/*
|
||||
* Set if there is a mass relabel required.
|
||||
* See SELINUX_RESTORECON_PROGRESS flag for details.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_MASS_RELABEL 0x4000
|
||||
#define SELINUX_RESTORECON_MASS_RELABEL 0x04000
|
||||
/*
|
||||
* 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 0x8000
|
||||
#define SELINUX_RESTORECON_SKIP_DIGEST 0x08000
|
||||
|
||||
/*
|
||||
* Set to treat conflicting specifications as errors.
|
||||
*/
|
||||
#define SELINUX_RESTORECON_CONFLICT_ERROR 0x10000
|
||||
|
||||
/**
|
||||
* selinux_restorecon_set_sehandle - Set the global fc handle.
|
||||
|
@ -8,13 +8,17 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Return 1 if we are running on a SELinux kernel, or 0 if not or -1 if we get an error. */
|
||||
/* Return 1 if we are running on a SELinux kernel, or 0 otherwise. */
|
||||
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;
|
||||
typedef char *security_context_t
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((deprecated))
|
||||
#endif
|
||||
;
|
||||
|
||||
/* Free the memory allocated for a context by any of the below get* calls. */
|
||||
extern void freecon(char * con);
|
||||
@ -178,6 +182,8 @@ 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. */
|
||||
@ -246,8 +252,12 @@ 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. */
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
extern int security_compute_user(const char * scon,
|
||||
const char *username,
|
||||
char *** con);
|
||||
@ -319,9 +329,13 @@ 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 0.
|
||||
* longer supported. Will always return -1.
|
||||
*/
|
||||
extern int security_load_booleans(char *path);
|
||||
extern int security_load_booleans(char *path)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((deprecated))
|
||||
#endif
|
||||
;
|
||||
|
||||
/* Check the validity of a security context. */
|
||||
extern int security_check_context(const char * con);
|
||||
@ -457,14 +471,22 @@ 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);
|
||||
extern int matchpathcon_init(const char *path)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((deprecated("Use selabel_open with backend SELABEL_CTX_FILE")))
|
||||
#endif
|
||||
;
|
||||
|
||||
/* 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);
|
||||
extern void matchpathcon_fini(void)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((deprecated("Use selabel_close")))
|
||||
#endif
|
||||
;
|
||||
|
||||
/* 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
|
||||
@ -478,7 +500,11 @@ 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);
|
||||
mode_t mode, char ** con)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((deprecated("Use selabel_lookup instead")))
|
||||
#endif
|
||||
;
|
||||
|
||||
/* Same as above, but return a specification index for
|
||||
later use in a matchpathcon_filespec_add() call - see below. */
|
||||
@ -571,10 +597,18 @@ 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);
|
||||
extern const char *selinux_booleans_path(void)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((deprecated))
|
||||
#endif
|
||||
;
|
||||
extern const char *selinux_customizable_types_path(void);
|
||||
/* Deprecated as policy ./users no longer supported. */
|
||||
extern const char *selinux_users_path(void);
|
||||
extern const char *selinux_users_path(void)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((deprecated))
|
||||
#endif
|
||||
;
|
||||
extern const char *selinux_usersconf_path(void);
|
||||
extern const char *selinux_translations_path(void);
|
||||
extern const char *selinux_colors_path(void);
|
||||
@ -602,8 +636,17 @@ 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);
|
||||
extern int checkPasswdAccess(access_vector_t requested);
|
||||
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
|
||||
;
|
||||
|
||||
/* Check if the tty_context is defined as a securetty
|
||||
Return 0 if secure, < 0 otherwise. */
|
||||
@ -629,7 +672,11 @@ 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[]);
|
||||
char *const argv[], char *const envp[])
|
||||
#ifdef __GNUC__
|
||||
__attribute__((deprecated("Use setexecfilecon and execve")))
|
||||
#endif
|
||||
;
|
||||
#endif
|
||||
|
||||
/* Returns whether a file context is customizable, and should not
|
||||
|
@ -117,6 +117,8 @@ 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.
|
||||
|
||||
@ -153,14 +155,49 @@ 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 "NETLINK NOTIFICATION"
|
||||
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 "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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
.
|
||||
.SH "RETURN VALUE"
|
||||
Functions with a return value return zero on success. On error, \-1 is returned and
|
||||
@ -192,5 +229,7 @@ Eamon Walsh <ewalsh@tycho.nsa.gov>
|
||||
.
|
||||
.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)
|
||||
|
@ -54,6 +54,11 @@ 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
|
||||
@ -78,6 +83,9 @@ 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 <mike.palmiotto@crunchydata.com>
|
||||
.
|
||||
.SH "SEE ALSO"
|
||||
.BR avc_open (3),
|
||||
.BR selinux_set_callback (3),
|
||||
|
@ -26,6 +26,9 @@ 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
|
||||
@ -46,10 +49,37 @@ 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 "NETLINK NOTIFICATION"
|
||||
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
|
||||
.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)
|
||||
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.
|
||||
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.
|
||||
.
|
||||
.SH "RETURN VALUE"
|
||||
Functions with a return value return zero on success. On error, \-1 is returned and
|
||||
@ -61,9 +91,12 @@ Eamon Walsh <ewalsh@tycho.nsa.gov>
|
||||
.
|
||||
.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)
|
||||
|
@ -7,17 +7,17 @@ get_ordered_context_list, get_ordered_context_list_with_level, get_default_conte
|
||||
.br
|
||||
.B #include <selinux/get_context_list.h>
|
||||
.sp
|
||||
.BI "int get_ordered_context_list(const char *" user ", char *" fromcon ", char ***" list );
|
||||
.BI "int get_ordered_context_list(const char *" user ", const char *" fromcon ", char ***" list );
|
||||
.sp
|
||||
.BI "int get_ordered_context_list_with_level(const char *" user ", const char *" level ", char *" fromcon ", char ***" list );
|
||||
.BI "int get_ordered_context_list_with_level(const char *" user ", const char *" level ", const char *" fromcon ", char ***" list );
|
||||
.sp
|
||||
.BI "int get_default_context(const char *" user ", char *" fromcon ", char **" newcon );
|
||||
.BI "int get_default_context(const char *" user ", const char *" fromcon ", char **" newcon );
|
||||
.sp
|
||||
.BI "int get_default_context_with_level(const char *" user ", const char *" level ", char *" fromcon ", char **" newcon );
|
||||
.BI "int get_default_context_with_level(const char *" user ", const char *" level ", const char *" fromcon ", char **" newcon );
|
||||
.sp
|
||||
.BI "int get_default_context_with_role(const char *" user ", const char *" role ", char *" fromcon ", char **" newcon ");
|
||||
.BI "int get_default_context_with_role(const char *" user ", const char *" role ", const char *" fromcon ", char **" newcon ");
|
||||
.sp
|
||||
.BI "int get_default_context_with_rolelevel(const char *" user ", const char *" role ", const char *" level ", char *" fromcon ", char **" newcon ");
|
||||
.BI "int get_default_context_with_rolelevel(const char *" user ", const char *" role ", const char *" level ", const char *" fromcon ", char **" newcon ");
|
||||
.sp
|
||||
.BI "int query_user_context(char **" list ", char **" newcon );
|
||||
.sp
|
||||
@ -26,14 +26,28 @@ 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 ()
|
||||
invokes the
|
||||
.BR security_compute_user (3)
|
||||
function to obtain the list of contexts for the specified
|
||||
obtains the list of contexts for the specified
|
||||
SELinux
|
||||
.I user
|
||||
that are reachable from the specified
|
||||
identity that are reachable from the specified
|
||||
.I fromcon
|
||||
context. The function then orders the resulting list based on the global
|
||||
context based on the global
|
||||
.I \%/etc/selinux/{SELINUXTYPE}/contexts/default_contexts
|
||||
file and the per-user
|
||||
.I \%/etc/selinux/{SELINUXTYPE}/contexts/users/<username>
|
||||
|
@ -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 <selinux/selinux.h>
|
||||
.sp
|
||||
@ -31,30 +31,39 @@ setcon \- set current security context of a process
|
||||
.sp
|
||||
.BI "void freeconary(char **" con );
|
||||
.sp
|
||||
.BI "int setcon(char *" context );
|
||||
.BI "int setcon(const char *" context );
|
||||
.sp
|
||||
.BI "int setcon_raw(char *" context );
|
||||
.
|
||||
.BI "int setcon_raw(const char *" context );
|
||||
|
||||
.SH "DESCRIPTION"
|
||||
.TP
|
||||
.BR getcon ()
|
||||
retrieves the context of the current process, which must be free'd with
|
||||
freecon.
|
||||
.BR 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.
|
||||
|
||||
.BR getpeercon ()
|
||||
retrieves context of peer socket, and set
|
||||
.BI * context
|
||||
to refer to it, which must be free'd with
|
||||
returns the process context for the specified PID, which must be free'd with
|
||||
.BR freecon ().
|
||||
|
||||
.TP
|
||||
.BR getpeercon ()
|
||||
retrieves the context of the peer socket, 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.
|
||||
|
||||
@ -62,6 +71,7 @@ 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
|
||||
@ -110,6 +120,8 @@ 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 (),
|
||||
@ -118,9 +130,14 @@ 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. On success 0 is returned.
|
||||
.
|
||||
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.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR selinux "(8), " setexeccon "(3)"
|
||||
|
@ -15,7 +15,6 @@ 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
|
||||
|
@ -5,9 +5,9 @@ security_check_context \- check the validity of a SELinux context
|
||||
.SH "SYNOPSIS"
|
||||
.B #include <selinux/selinux.h>
|
||||
.sp
|
||||
.BI "int security_check_context(char *" con );
|
||||
.BI "int security_check_context(const char *" con );
|
||||
.sp
|
||||
.BI "int security_check_context_raw(char *" con );
|
||||
.BI "int security_check_context_raw(const char *" con );
|
||||
.
|
||||
.SH "DESCRIPTION"
|
||||
.BR security_check_context ()
|
||||
|
@ -134,8 +134,9 @@ instance.
|
||||
|
||||
.BR security_compute_user ()
|
||||
is used to determine the set of user contexts that can be reached from a
|
||||
source context. It is mainly used by
|
||||
.BR get_ordered_context_list (3).
|
||||
source context. This function is deprecated; use
|
||||
.BR get_ordered_context_list (3)
|
||||
instead.
|
||||
|
||||
.BR security_validatetrans ()
|
||||
is used to determine if a transition from scon to newcon using tcon as the object
|
||||
|
@ -152,6 +152,10 @@ 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
|
||||
|
@ -46,6 +46,20 @@ 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
|
||||
|
@ -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,9 +57,14 @@ unmap the kernel status page and close its file descriptor, or close the
|
||||
netlink socket if fallbacked.
|
||||
.sp
|
||||
.BR selinux_status_updated ()
|
||||
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.
|
||||
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.
|
||||
.sp
|
||||
.BR selinux_status_getenforce ()
|
||||
returns 0 if SELinux is running in permissive mode, 1 if enforcing mode,
|
||||
|
@ -125,7 +125,14 @@ Where:
|
||||
.RS
|
||||
.I pathname
|
||||
.RS
|
||||
An entry that defines the pathname that may be in the form of a regular expression.
|
||||
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.
|
||||
.RE
|
||||
.I file_type
|
||||
.RS
|
||||
|
@ -19,18 +19,36 @@ 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 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.
|
||||
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.
|
||||
|
||||
The
|
||||
.I /etc/selinux/config
|
||||
@ -76,6 +94,13 @@ 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 <dwalsh@redhat.com>.
|
||||
|
@ -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
|
||||
|
@ -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 imp;print([s for s,m,t in imp.get_suffixes() if t == imp.C_EXTENSION][0])')
|
||||
PYCEXT ?= $(shell $(PYTHON) -c 'import importlib.machinery;print(importlib.machinery.EXTENSION_SUFFIXES[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
|
||||
-Wstrict-overflow=5 -fno-semantic-interposition
|
||||
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),-z,defs,-z,relro
|
||||
LD_SONAME_FLAGS=-soname,$(LIBSO),--version-script=libselinux.map,-z,defs,-z,relro
|
||||
|
||||
ifeq ($(OS), Darwin)
|
||||
override CFLAGS += -I/opt/local/include
|
||||
@ -105,7 +105,8 @@ 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-shadow -Wno-uninitialized -Wno-missing-prototypes -Wno-missing-declarations \
|
||||
-Wno-deprecated-declarations
|
||||
|
||||
RANLIB ?= ranlib
|
||||
|
||||
@ -121,8 +122,16 @@ 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
|
||||
DISABLE_FLAGS+= -DNO_ANDROID_BACKEND
|
||||
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))
|
||||
endif
|
||||
|
||||
SWIGRUBY = swig -Wall -ruby -o $(SWIGRUBYCOUT) -outdir ./ $(DISABLE_FLAGS)
|
||||
@ -173,7 +182,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.py install --prefix=$(PREFIX) `test -n "$(DESTDIR)" && echo --root $(DESTDIR)` $(PYTHON_SETUP_ARGS)
|
||||
install -m 644 $(SWIGPYOUT) $(DESTDIR)$(PYTHONLIBDIR)/selinux/__init__.py
|
||||
ln -sf --relative $(DESTDIR)$(PYTHONLIBDIR)/selinux/_selinux$(PYCEXT) $(DESTDIR)$(PYTHONLIBDIR)/_selinux$(PYCEXT)
|
||||
|
||||
|
@ -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: %s\n",
|
||||
path, strerror(errno));
|
||||
"unable to open %s: %m\n",
|
||||
path);
|
||||
PyErr_SetString( PyExc_ValueError, errormsg);
|
||||
return 1;
|
||||
}
|
||||
@ -221,9 +221,8 @@ static int __policy_init(const char *init_path)
|
||||
fp = fopen(curpolicy, "re");
|
||||
if (!fp) {
|
||||
snprintf(errormsg, sizeof(errormsg),
|
||||
"unable to open %s: %s\n",
|
||||
curpolicy,
|
||||
strerror(errno));
|
||||
"unable to open %s: %m\n",
|
||||
curpolicy);
|
||||
PyErr_SetString( PyExc_ValueError, errormsg);
|
||||
return 1;
|
||||
}
|
||||
@ -242,7 +241,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: %s\n", strerror(errno));
|
||||
"policydb_init failed: %m\n");
|
||||
PyErr_SetString( PyExc_RuntimeError, errormsg);
|
||||
fclose(fp);
|
||||
return 1;
|
||||
@ -275,7 +274,7 @@ static int __policy_init(const char *init_path)
|
||||
}
|
||||
|
||||
sepol_bool_iterate(avc->handle, avc->policydb,
|
||||
load_booleans, (void *)NULL);
|
||||
load_booleans, NULL);
|
||||
|
||||
/* Initialize the sidtab for subsequent use by sepol_context_to_sid
|
||||
and sepol_compute_av_reason. */
|
||||
|
@ -50,7 +50,6 @@ 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;
|
||||
@ -145,22 +144,7 @@ int avc_get_initial_sid(const char * name, security_id_t * sid)
|
||||
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("avc", NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
int avc_init(const char *prefix,
|
||||
static int avc_init_internal(const char *prefix,
|
||||
const struct avc_memory_callback *mem_cb,
|
||||
const struct avc_log_callback *log_cb,
|
||||
const struct avc_thread_callback *thread_cb,
|
||||
@ -222,30 +206,49 @@ int avc_init(const char *prefix,
|
||||
rc = security_getenforce();
|
||||
if (rc < 0) {
|
||||
avc_log(SELINUX_ERROR,
|
||||
"%s: could not determine enforcing mode: %s\n",
|
||||
avc_prefix,
|
||||
strerror(errno));
|
||||
"%s: could not determine enforcing mode: %m\n",
|
||||
avc_prefix);
|
||||
goto out;
|
||||
}
|
||||
avc_enforcing = rc;
|
||||
}
|
||||
|
||||
rc = avc_netlink_open(0);
|
||||
rc = selinux_status_open(0);
|
||||
if (rc < 0) {
|
||||
avc_log(SELINUX_ERROR,
|
||||
"%s: can't open netlink socket: %d (%s)\n",
|
||||
avc_prefix, errno, strerror(errno));
|
||||
"%s: could not open selinux status page: %d (%m)\n",
|
||||
avc_prefix, 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));
|
||||
@ -294,7 +297,6 @@ 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)
|
||||
{
|
||||
@ -494,7 +496,6 @@ void avc_cleanup(void)
|
||||
{
|
||||
}
|
||||
|
||||
hidden_def(avc_cleanup)
|
||||
|
||||
int avc_reset(void)
|
||||
{
|
||||
@ -539,7 +540,6 @@ int avc_reset(void)
|
||||
return rc;
|
||||
}
|
||||
|
||||
hidden_def(avc_reset)
|
||||
|
||||
void avc_destroy(void)
|
||||
{
|
||||
@ -551,9 +551,7 @@ void avc_destroy(void)
|
||||
|
||||
avc_get_lock(avc_lock);
|
||||
|
||||
if (avc_using_threads)
|
||||
avc_stop_thread(avc_netlink_thread);
|
||||
avc_netlink_close();
|
||||
selinux_status_close();
|
||||
|
||||
for (i = 0; i < AVC_CACHE_SLOTS; i++) {
|
||||
node = avc_cache.slots[i];
|
||||
@ -733,7 +731,6 @@ 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)
|
||||
@ -761,7 +758,7 @@ int avc_has_perm_noaudit(security_id_t ssid,
|
||||
avd_init(avd);
|
||||
|
||||
if (!avc_using_threads && !avc_app_main_loop) {
|
||||
(void)avc_netlink_check_nb();
|
||||
(void) selinux_status_updated();
|
||||
}
|
||||
|
||||
if (!aeref) {
|
||||
@ -825,7 +822,6 @@ 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,
|
||||
|
@ -53,6 +53,49 @@ 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;
|
||||
|
||||
@ -177,20 +220,7 @@ static int avc_netlink_process(void *buf)
|
||||
|
||||
case SELNL_MSG_SETENFORCE:{
|
||||
struct selnl_msg_setenforce *msg = NLMSG_DATA(nlh);
|
||||
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);
|
||||
rc = avc_process_setenforce(!!msg->val);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
break;
|
||||
@ -198,18 +228,7 @@ static int avc_netlink_process(void *buf)
|
||||
|
||||
case SELNL_MSG_POLICYLOAD:{
|
||||
struct selnl_msg_policyload *msg = NLMSG_DATA(nlh);
|
||||
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);
|
||||
rc = avc_process_policyload(msg->seqno);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
break;
|
||||
@ -284,6 +303,17 @@ 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;
|
||||
|
@ -14,24 +14,27 @@
|
||||
#include <string.h>
|
||||
#include <selinux/avc.h>
|
||||
#include "callbacks.h"
|
||||
#include "dso.h"
|
||||
|
||||
/* callback pointers */
|
||||
extern void *(*avc_func_malloc) (size_t) hidden;
|
||||
extern void (*avc_func_free) (void *)hidden;
|
||||
extern void *(*avc_func_malloc) (size_t) ;
|
||||
extern void (*avc_func_free) (void *);
|
||||
|
||||
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 void (*avc_func_log) (const char *, ...) __attribute__((__format__(printf,1,2))) ;
|
||||
extern void (*avc_func_audit) (void *, security_class_t, char *, size_t);
|
||||
|
||||
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 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 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;
|
||||
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);
|
||||
|
||||
static inline void set_callbacks(const struct avc_memory_callback *mem_cb,
|
||||
const struct avc_log_callback *log_cb,
|
||||
@ -61,10 +64,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] hidden;
|
||||
extern int avc_running hidden;
|
||||
extern int avc_enforcing hidden;
|
||||
extern int avc_setenforce hidden;
|
||||
extern char avc_prefix[AVC_PREFIX_SIZE] ;
|
||||
extern int avc_running ;
|
||||
extern int avc_enforcing ;
|
||||
extern int avc_setenforce ;
|
||||
|
||||
/* user-supplied callback interface for avc */
|
||||
static inline void *avc_malloc(size_t size)
|
||||
@ -82,10 +85,12 @@ static inline void avc_free(void *ptr)
|
||||
|
||||
/* this is a macro in order to use the variadic capability. */
|
||||
#define avc_log(type, format...) \
|
||||
if (avc_func_log) \
|
||||
avc_func_log(format); \
|
||||
else \
|
||||
selinux_log(type, format);
|
||||
do { \
|
||||
if (avc_func_log) \
|
||||
avc_func_log(format); \
|
||||
else \
|
||||
selinux_log(type, format); \
|
||||
} while (0)
|
||||
|
||||
static inline void avc_suppl_audit(void *ptr, security_class_t class,
|
||||
char *buf, size_t len)
|
||||
@ -134,14 +139,18 @@ static inline void avc_free_lock(void *lock)
|
||||
#ifdef AVC_CACHE_STATS
|
||||
|
||||
#define avc_cache_stats_incr(field) \
|
||||
cache_stats.field ++;
|
||||
do { \
|
||||
cache_stats.field ++; \
|
||||
} while (0)
|
||||
#define avc_cache_stats_add(field, num) \
|
||||
cache_stats.field += num;
|
||||
do { \
|
||||
cache_stats.field += num; \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define avc_cache_stats_incr(field)
|
||||
#define avc_cache_stats_add(field, num)
|
||||
#define avc_cache_stats_incr(field) do {} while (0)
|
||||
#define avc_cache_stats_add(field, num) do {} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
@ -155,28 +164,23 @@ 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) hidden;
|
||||
uint32_t seqno) ;
|
||||
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) hidden;
|
||||
access_vector_t * out_retained) ;
|
||||
int avc_ss_revoke(security_id_t ssid, security_id_t tsid,
|
||||
security_class_t tclass, access_vector_t perms,
|
||||
uint32_t seqno) hidden;
|
||||
int avc_ss_reset(uint32_t seqno) hidden;
|
||||
uint32_t seqno) ;
|
||||
int avc_ss_reset(uint32_t seqno) ;
|
||||
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) hidden;
|
||||
uint32_t seqno, uint32_t enable) ;
|
||||
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) hidden;
|
||||
uint32_t seqno, uint32_t enable) ;
|
||||
|
||||
/* netlink kernel message code */
|
||||
extern int avc_netlink_trouble hidden;
|
||||
extern int avc_netlink_trouble ;
|
||||
|
||||
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_ */
|
||||
|
@ -15,14 +15,13 @@
|
||||
|
||||
static inline unsigned sidtab_hash(const char * key)
|
||||
{
|
||||
char *p, *keyp;
|
||||
const char *p;
|
||||
unsigned int size;
|
||||
unsigned int val;
|
||||
|
||||
val = 0;
|
||||
keyp = (char *)key;
|
||||
size = strlen(keyp);
|
||||
for (p = keyp; (unsigned int)(p - keyp) < size; p++)
|
||||
size = strlen(key);
|
||||
for (p = key; (unsigned int)(p - key) < size; p++)
|
||||
val =
|
||||
(val << 4 | (val >> (8 * sizeof(unsigned int) - 4))) ^ (*p);
|
||||
return val & (SIDTAB_SIZE - 1);
|
||||
@ -57,7 +56,7 @@ int sidtab_insert(struct sidtab *s, const char * ctx)
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
newctx = (char *) strdup(ctx);
|
||||
newctx = strdup(ctx);
|
||||
if (!newctx) {
|
||||
rc = -1;
|
||||
avc_free(newnode);
|
||||
@ -101,7 +100,7 @@ sidtab_context_to_sid(struct sidtab *s,
|
||||
return rc;
|
||||
}
|
||||
|
||||
void sidtab_sid_stats(struct sidtab *h, char *buf, int buflen)
|
||||
void sidtab_sid_stats(struct sidtab *s, char *buf, int buflen)
|
||||
{
|
||||
int i, chain_len, slots_used, max_chain_len;
|
||||
struct sidtab_node *cur;
|
||||
@ -109,7 +108,7 @@ void sidtab_sid_stats(struct sidtab *h, char *buf, int buflen)
|
||||
slots_used = 0;
|
||||
max_chain_len = 0;
|
||||
for (i = 0; i < SIDTAB_SIZE; i++) {
|
||||
cur = h->htable[i];
|
||||
cur = s->htable[i];
|
||||
if (cur) {
|
||||
slots_used++;
|
||||
chain_len = 0;
|
||||
@ -125,7 +124,7 @@ void sidtab_sid_stats(struct sidtab *h, char *buf, int buflen)
|
||||
|
||||
snprintf(buf, buflen,
|
||||
"%s: %u SID entries and %d/%d buckets used, longest "
|
||||
"chain length %d\n", avc_prefix, h->nel, slots_used,
|
||||
"chain length %d\n", avc_prefix, s->nel, slots_used,
|
||||
SIDTAB_SIZE, max_chain_len);
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
#include <selinux/selinux.h>
|
||||
#include <selinux/avc.h>
|
||||
#include "dso.h"
|
||||
|
||||
struct sidtab_node {
|
||||
struct security_id sid_s;
|
||||
@ -24,13 +23,13 @@ struct sidtab {
|
||||
unsigned nel;
|
||||
};
|
||||
|
||||
int sidtab_init(struct sidtab *s) hidden;
|
||||
int sidtab_insert(struct sidtab *s, const char * ctx) hidden;
|
||||
int sidtab_init(struct sidtab *s) ;
|
||||
int sidtab_insert(struct sidtab *s, const char * ctx) ;
|
||||
|
||||
int sidtab_context_to_sid(struct sidtab *s,
|
||||
const char * ctx, security_id_t * sid) hidden;
|
||||
const char * ctx, security_id_t * sid) ;
|
||||
|
||||
void sidtab_sid_stats(struct sidtab *s, char *buf, int buflen) hidden;
|
||||
void sidtab_destroy(struct sidtab *s) hidden;
|
||||
void sidtab_sid_stats(struct sidtab *s, char *buf, int buflen) ;
|
||||
void sidtab_destroy(struct sidtab *s) ;
|
||||
|
||||
#endif /* _SELINUX_AVC_SIDTAB_H_ */
|
||||
|
@ -414,8 +414,3 @@ 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)
|
||||
|
@ -9,22 +9,21 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <selinux/selinux.h>
|
||||
#include "dso.h"
|
||||
|
||||
/* callback pointers */
|
||||
extern int __attribute__ ((format(printf, 2, 3)))
|
||||
(*selinux_log) (int type, const char *, ...) hidden;
|
||||
(*selinux_log) (int type, const char *, ...) ;
|
||||
|
||||
extern int
|
||||
(*selinux_audit) (void *, security_class_t, char *, size_t) hidden;
|
||||
(*selinux_audit) (void *, security_class_t, char *, size_t) ;
|
||||
|
||||
extern int
|
||||
(*selinux_validate)(char **ctx) hidden;
|
||||
(*selinux_validate)(char **ctx) ;
|
||||
|
||||
extern int
|
||||
(*selinux_netlink_setenforce) (int enforcing) hidden;
|
||||
(*selinux_netlink_setenforce) (int enforcing) ;
|
||||
|
||||
extern int
|
||||
(*selinux_netlink_policyload) (int seqno) hidden;
|
||||
(*selinux_netlink_policyload) (int seqno) ;
|
||||
|
||||
#endif /* _SELINUX_CALLBACKS_H_ */
|
||||
|
@ -60,7 +60,6 @@ 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)
|
||||
@ -83,4 +82,3 @@ int security_canonicalize_context(const char * con,
|
||||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(security_canonicalize_context)
|
||||
|
@ -39,7 +39,7 @@ int selinux_check_access(const char *scon, const char *tcon, const char *class,
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
(void) avc_netlink_check_nb();
|
||||
(void) selinux_status_updated();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
int selinux_check_passwd_access(access_vector_t requested)
|
||||
static int selinux_check_passwd_access_internal(access_vector_t requested)
|
||||
{
|
||||
int status = -1;
|
||||
char *user_context;
|
||||
@ -78,7 +78,9 @@ int selinux_check_passwd_access(access_vector_t requested)
|
||||
passwd_class = string_to_security_class("passwd");
|
||||
if (passwd_class == 0) {
|
||||
freecon(user_context);
|
||||
return 0;
|
||||
if (security_deny_unknown() == 0)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = security_compute_av_raw(user_context,
|
||||
@ -99,9 +101,11 @@ int selinux_check_passwd_access(access_vector_t requested)
|
||||
return status;
|
||||
}
|
||||
|
||||
hidden_def(selinux_check_passwd_access)
|
||||
int selinux_check_passwd_access(access_vector_t requested) {
|
||||
return selinux_check_passwd_access_internal(requested);
|
||||
}
|
||||
|
||||
int checkPasswdAccess(access_vector_t requested)
|
||||
{
|
||||
return selinux_check_passwd_access(requested);
|
||||
return selinux_check_passwd_access_internal(requested);
|
||||
}
|
||||
|
@ -31,7 +31,6 @@ int security_check_context_raw(const char * con)
|
||||
return 0;
|
||||
}
|
||||
|
||||
hidden_def(security_check_context_raw)
|
||||
|
||||
int security_check_context(const char * con)
|
||||
{
|
||||
@ -48,4 +47,3 @@ int security_check_context(const char * con)
|
||||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(security_check_context)
|
||||
|
@ -37,4 +37,3 @@ int security_get_checkreqprot(void)
|
||||
return checkreqprot;
|
||||
}
|
||||
|
||||
hidden_def(security_get_checkreqprot);
|
||||
|
@ -80,7 +80,6 @@ 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,
|
||||
@ -107,7 +106,6 @@ 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,
|
||||
@ -134,7 +132,6 @@ 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,
|
||||
@ -162,4 +159,3 @@ int security_compute_av(const char * scon,
|
||||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(security_compute_av)
|
||||
|
@ -105,7 +105,6 @@ 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,
|
||||
@ -115,7 +114,6 @@ 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,
|
||||
@ -146,7 +144,6 @@ 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,
|
||||
@ -155,4 +152,3 @@ int security_compute_create(const char * scon,
|
||||
{
|
||||
return security_compute_create_name(scon, tcon, tclass, NULL, newcon);
|
||||
}
|
||||
hidden_def(security_compute_create)
|
||||
|
@ -60,7 +60,6 @@ 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,
|
||||
|
@ -60,7 +60,6 @@ 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,
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "selinux_internal.h"
|
||||
#include "policy.h"
|
||||
#include <limits.h>
|
||||
#include "callbacks.h"
|
||||
|
||||
int security_compute_user_raw(const char * scon,
|
||||
const char *user, char *** con)
|
||||
@ -24,6 +25,8 @@ 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)
|
||||
@ -77,7 +80,6 @@ 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)
|
||||
@ -107,4 +109,3 @@ int security_compute_user(const char * scon,
|
||||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(security_compute_user)
|
||||
|
@ -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 (i = count = 0, p = str; *p; p++) {
|
||||
for (count = 0, p = str; *p; p++) {
|
||||
switch (*p) {
|
||||
case ':':
|
||||
count++;
|
||||
@ -82,7 +82,6 @@ context_t context_new(const char *str)
|
||||
return 0;
|
||||
}
|
||||
|
||||
hidden_def(context_new)
|
||||
|
||||
static void conditional_free(char **v)
|
||||
{
|
||||
@ -113,7 +112,6 @@ void context_free(context_t context)
|
||||
}
|
||||
}
|
||||
|
||||
hidden_def(context_free)
|
||||
|
||||
/*
|
||||
* Return a pointer to the string value of the context.
|
||||
@ -144,7 +142,6 @@ 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)
|
||||
@ -154,14 +151,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);
|
||||
@ -176,8 +173,7 @@ 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)
|
||||
@ -187,8 +183,7 @@ 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)
|
||||
|
@ -1,14 +1,2 @@
|
||||
#include <selinux/context.h>
|
||||
#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)
|
||||
|
@ -37,4 +37,3 @@ int security_deny_unknown(void)
|
||||
return deny_unknown;
|
||||
}
|
||||
|
||||
hidden_def(security_deny_unknown);
|
||||
|
@ -35,4 +35,3 @@ int security_disable(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
hidden_def(security_disable)
|
||||
|
@ -1,23 +0,0 @@
|
||||
#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
|
@ -20,7 +20,6 @@ int is_selinux_enabled(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
hidden_def(is_selinux_enabled)
|
||||
|
||||
/*
|
||||
* Function: is_selinux_mls_enabled()
|
||||
@ -55,4 +54,3 @@ int is_selinux_mls_enabled(void)
|
||||
return enabled;
|
||||
}
|
||||
|
||||
hidden_def(is_selinux_mls_enabled)
|
||||
|
@ -1,3 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
function except() {
|
||||
case $1 in
|
||||
selinux_file_context_cmp) # ignore
|
||||
@ -10,15 +12,26 @@ echo "
|
||||
PyErr_SetFromErrno(PyExc_OSError);
|
||||
SWIG_fail;
|
||||
}
|
||||
}
|
||||
"
|
||||
}"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
if ! ${CC:-gcc} -x c -c -I../include -o temp.o - -aux-info temp.aux < ../include/selinux/selinux.h
|
||||
|
||||
# Make sure that selinux.h is included first in order not to depend on the order
|
||||
# in which "#include <selinux/selinux.h>" 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
|
||||
then
|
||||
# clang does not support -aux-info so fall back to gcc
|
||||
gcc -x c -c -I../include -o temp.o - -aux-info temp.aux < ../include/selinux/selinux.h
|
||||
cat "${FILE_LIST[@]}" | gcc -x c -c -I../include -o temp.o - -aux-info temp.aux
|
||||
fi
|
||||
for i in `awk '/<stdin>.*extern int/ { print $6 }' temp.aux`; do except $i ; done
|
||||
rm -f -- temp.aux temp.o
|
||||
|
@ -49,7 +49,6 @@ int fgetfilecon_raw(int fd, char ** context)
|
||||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(fgetfilecon_raw)
|
||||
|
||||
int fgetfilecon(int fd, char ** context)
|
||||
{
|
||||
|
@ -8,4 +8,3 @@ void freecon(char * con)
|
||||
free(con);
|
||||
}
|
||||
|
||||
hidden_def(freecon)
|
||||
|
@ -16,4 +16,3 @@ void freeconary(char ** con)
|
||||
free(con);
|
||||
}
|
||||
|
||||
hidden_def(freeconary)
|
||||
|
@ -25,7 +25,6 @@ int fsetfilecon_raw(int fd, const char * context)
|
||||
return rc;
|
||||
}
|
||||
|
||||
hidden_def(fsetfilecon_raw)
|
||||
|
||||
int fsetfilecon(int fd, const char *context)
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdio_ext.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
@ -12,7 +13,7 @@
|
||||
|
||||
int get_default_context_with_role(const char *user,
|
||||
const char *role,
|
||||
char * fromcon,
|
||||
const char *fromcon,
|
||||
char ** newcon)
|
||||
{
|
||||
char **conary;
|
||||
@ -51,28 +52,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,
|
||||
char * fromcon,
|
||||
const char *fromcon,
|
||||
char ** newcon)
|
||||
{
|
||||
|
||||
int rc = 0;
|
||||
int freefrom = 0;
|
||||
int rc;
|
||||
char *backup_fromcon = NULL;
|
||||
context_t con;
|
||||
char *newfromcon;
|
||||
const char *newfromcon;
|
||||
|
||||
if (!level)
|
||||
return get_default_context_with_role(user, role, fromcon,
|
||||
newcon);
|
||||
|
||||
if (!fromcon) {
|
||||
rc = getcon(&fromcon);
|
||||
rc = getcon(&backup_fromcon);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
freefrom = 1;
|
||||
fromcon = backup_fromcon;
|
||||
}
|
||||
|
||||
rc = -1;
|
||||
@ -91,14 +92,13 @@ int get_default_context_with_rolelevel(const char *user,
|
||||
|
||||
out:
|
||||
context_free(con);
|
||||
if (freefrom)
|
||||
freecon(fromcon);
|
||||
freecon(backup_fromcon);
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
||||
int get_default_context(const char *user,
|
||||
char * fromcon, char ** newcon)
|
||||
const char *fromcon, char ** newcon)
|
||||
{
|
||||
char **conary;
|
||||
int rc;
|
||||
@ -114,64 +114,41 @@ int get_default_context(const char *user,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int find_partialcon(char ** list,
|
||||
unsigned int nreach, char *part)
|
||||
static int is_in_reachable(char **reachable, const char *usercon_str)
|
||||
{
|
||||
const char *conrole, *contype;
|
||||
char *partrole, *parttype, *ptr;
|
||||
context_t con;
|
||||
unsigned int i;
|
||||
if (!reachable)
|
||||
return 0;
|
||||
|
||||
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;
|
||||
for (; *reachable != NULL; reachable++) {
|
||||
if (strcmp(*reachable, usercon_str) == 0) {
|
||||
return 1;
|
||||
}
|
||||
if (!strcmp(conrole, partrole) && !strcmp(contype, parttype)) {
|
||||
context_free(con);
|
||||
return i;
|
||||
}
|
||||
context_free(con);
|
||||
}
|
||||
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_context_order(FILE * fp,
|
||||
char * fromcon,
|
||||
char ** reachable,
|
||||
unsigned int nreach,
|
||||
unsigned int *ordering, unsigned int *nordered)
|
||||
static int get_context_user(FILE * fp,
|
||||
const char * fromcon,
|
||||
const char * user,
|
||||
char ***reachable,
|
||||
unsigned int *nreachable)
|
||||
{
|
||||
char *start, *end = NULL;
|
||||
char *line = NULL;
|
||||
size_t line_len = 0;
|
||||
size_t line_len = 0, usercon_len;
|
||||
size_t user_len = strlen(user);
|
||||
ssize_t len;
|
||||
int found = 0;
|
||||
const char *fromrole, *fromtype;
|
||||
const char *fromrole, *fromtype, *fromlevel;
|
||||
char *linerole, *linetype;
|
||||
unsigned int i;
|
||||
char **new_reachable = NULL;
|
||||
char *usercon_str;
|
||||
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. */
|
||||
@ -180,6 +157,7 @@ static int get_context_order(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;
|
||||
@ -243,23 +221,75 @@ static int get_context_order(FILE * fp,
|
||||
if (*end)
|
||||
*end++ = 0;
|
||||
|
||||
/* Check for a match in the reachable list. */
|
||||
rc = find_partialcon(reachable, nreach, start);
|
||||
if (rc < 0) {
|
||||
/* No match, skip it. */
|
||||
/* 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);
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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)++;
|
||||
/* 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);
|
||||
start = end;
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
||||
out:
|
||||
@ -313,39 +343,24 @@ 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,
|
||||
char * fromcon,
|
||||
const char *fromcon,
|
||||
char *** list)
|
||||
{
|
||||
int rc;
|
||||
int freefrom = 0;
|
||||
char *backup_fromcon = NULL;
|
||||
context_t con;
|
||||
char *newfromcon;
|
||||
const char *newfromcon;
|
||||
|
||||
if (!level)
|
||||
return get_ordered_context_list(user, fromcon, list);
|
||||
|
||||
if (!fromcon) {
|
||||
rc = getcon(&fromcon);
|
||||
rc = getcon(&backup_fromcon);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
freefrom = 1;
|
||||
fromcon = backup_fromcon;
|
||||
}
|
||||
|
||||
rc = -1;
|
||||
@ -364,16 +379,14 @@ int get_ordered_context_list_with_level(const char *user,
|
||||
|
||||
out:
|
||||
context_free(con);
|
||||
if (freefrom)
|
||||
freecon(fromcon);
|
||||
freecon(backup_fromcon);
|
||||
return rc;
|
||||
}
|
||||
|
||||
hidden_def(get_ordered_context_list_with_level)
|
||||
|
||||
int get_default_context_with_level(const char *user,
|
||||
const char *level,
|
||||
char * fromcon,
|
||||
const char *fromcon,
|
||||
char ** newcon)
|
||||
{
|
||||
char **conary;
|
||||
@ -391,15 +404,13 @@ int get_default_context_with_level(const char *user,
|
||||
}
|
||||
|
||||
int get_ordered_context_list(const char *user,
|
||||
char * fromcon,
|
||||
const char *fromcon,
|
||||
char *** list)
|
||||
{
|
||||
char **reachable = NULL;
|
||||
unsigned int *ordering = NULL;
|
||||
struct context_order *co = NULL;
|
||||
char **ptr;
|
||||
int rc = 0;
|
||||
unsigned int nreach = 0, nordered = 0, freefrom = 0, i;
|
||||
unsigned nreachable = 0;
|
||||
char *backup_fromcon = NULL;
|
||||
FILE *fp;
|
||||
char *fname = NULL;
|
||||
size_t fname_len;
|
||||
@ -407,29 +418,12 @@ int get_ordered_context_list(const char *user,
|
||||
|
||||
if (!fromcon) {
|
||||
/* Get the current context and use it for the starting context */
|
||||
rc = getcon(&fromcon);
|
||||
rc = getcon(&backup_fromcon);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
freefrom = 1;
|
||||
fromcon = backup_fromcon;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
@ -440,8 +434,8 @@ int get_ordered_context_list(const char *user,
|
||||
fp = fopen(fname, "re");
|
||||
if (fp) {
|
||||
__fsetlocking(fp, FSETLOCKING_BYCALLER);
|
||||
rc = get_context_order(fp, fromcon, reachable, nreach, ordering,
|
||||
&nordered);
|
||||
rc = get_context_user(fp, fromcon, user, &reachable, &nreachable);
|
||||
|
||||
fclose(fp);
|
||||
if (rc < 0 && errno != ENOENT) {
|
||||
fprintf(stderr,
|
||||
@ -454,8 +448,7 @@ int get_ordered_context_list(const char *user,
|
||||
fp = fopen(selinux_default_context_path(), "re");
|
||||
if (fp) {
|
||||
__fsetlocking(fp, FSETLOCKING_BYCALLER);
|
||||
rc = get_context_order(fp, fromcon, reachable, nreach, ordering,
|
||||
&nordered);
|
||||
rc = get_context_user(fp, fromcon, user, &reachable, &nreachable);
|
||||
fclose(fp);
|
||||
if (rc < 0 && errno != ENOENT) {
|
||||
fprintf(stderr,
|
||||
@ -463,42 +456,20 @@ int get_ordered_context_list(const char *user,
|
||||
__FUNCTION__, selinux_default_context_path());
|
||||
/* Fall through */
|
||||
}
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
if (!nordered)
|
||||
if (!nreachable)
|
||||
goto failsafe;
|
||||
|
||||
/* 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)
|
||||
if (nreachable > 0) {
|
||||
*list = reachable;
|
||||
rc = nreachable;
|
||||
}
|
||||
else
|
||||
freeconary(reachable);
|
||||
|
||||
free(ordering);
|
||||
if (freefrom)
|
||||
freecon(fromcon);
|
||||
freecon(backup_fromcon);
|
||||
|
||||
return rc;
|
||||
|
||||
@ -519,8 +490,7 @@ int get_ordered_context_list(const char *user,
|
||||
reachable = NULL;
|
||||
goto out;
|
||||
}
|
||||
rc = 1; /* one context in the list */
|
||||
nreachable = 1; /* one context in the list */
|
||||
goto out;
|
||||
}
|
||||
|
||||
hidden_def(get_ordered_context_list)
|
||||
|
@ -1,6 +1,2 @@
|
||||
#include <selinux/get_context_list.h>
|
||||
#include "dso.h"
|
||||
|
||||
hidden_proto(get_ordered_context_list)
|
||||
hidden_proto(get_ordered_context_list_with_level)
|
||||
hidden_proto(get_default_context_with_role)
|
||||
|
@ -1,4 +1,2 @@
|
||||
#include <selinux/get_default_type.h>
|
||||
#include "dso.h"
|
||||
|
||||
hidden_proto(selinux_default_type_path)
|
||||
|
@ -53,7 +53,6 @@ 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)
|
||||
{
|
||||
@ -69,4 +68,3 @@ int security_get_initial_context(const char * name, char ** con)
|
||||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(security_get_initial_context)
|
||||
|
@ -37,4 +37,3 @@ int security_getenforce(void)
|
||||
return !!enforce;
|
||||
}
|
||||
|
||||
hidden_def(security_getenforce)
|
||||
|
@ -49,7 +49,6 @@ int getfilecon_raw(const char *path, char ** context)
|
||||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(getfilecon_raw)
|
||||
|
||||
int getfilecon(const char *path, char ** context)
|
||||
{
|
||||
@ -70,4 +69,3 @@ int getfilecon(const char *path, char ** context)
|
||||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(getfilecon)
|
||||
|
@ -43,7 +43,6 @@ int getpeercon_raw(int fd, char ** context)
|
||||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(getpeercon_raw)
|
||||
|
||||
int getpeercon(int fd, char ** context)
|
||||
{
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "dso.h"
|
||||
#include "policy.h"
|
||||
#include "selinux_internal.h"
|
||||
#include "setrans_internal.h"
|
||||
@ -79,7 +78,6 @@ int selinuxfs_exists(void)
|
||||
fclose(fp);
|
||||
return exists;
|
||||
}
|
||||
hidden_def(selinuxfs_exists)
|
||||
|
||||
static void init_selinuxmnt(void)
|
||||
{
|
||||
@ -138,14 +136,12 @@ 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)
|
||||
|
@ -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] = (char *) strdup(buf);
|
||||
list[i] = strdup(buf);
|
||||
if (!list[i]) {
|
||||
unsigned int j;
|
||||
for (j = 0; j < i; j++)
|
||||
|
@ -96,9 +96,15 @@ static int process_line(struct selabel_handle *rec,
|
||||
items = read_spec_entries(line_buf, &errbuf, 2, &prop, &context);
|
||||
if (items < 0) {
|
||||
items = errno;
|
||||
selinux_log(SELINUX_ERROR,
|
||||
"%s: line %u error due to: %s\n", path,
|
||||
lineno, errbuf ?: strerror(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);
|
||||
}
|
||||
errno = items;
|
||||
return -1;
|
||||
}
|
||||
|
@ -277,7 +277,7 @@ db_init(const struct selinux_opt *opts, unsigned nopts,
|
||||
if (!path)
|
||||
path = selinux_sepgsql_context_path();
|
||||
|
||||
if ((filp = fopen(path, "rb")) == NULL) {
|
||||
if ((filp = fopen(path, "re")) == NULL) {
|
||||
free(catalog);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -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 const struct spec **lookup_all(struct selabel_handle *rec,
|
||||
static struct spec **lookup_all(struct selabel_handle *rec,
|
||||
const char *key,
|
||||
int type,
|
||||
bool partial,
|
||||
@ -907,13 +907,14 @@ static const 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;
|
||||
|
||||
const struct spec **result = NULL;
|
||||
struct spec **result = NULL;
|
||||
if (match_count) {
|
||||
*match_count = 0;
|
||||
result = calloc(data->nspec, sizeof(struct spec*));
|
||||
@ -947,6 +948,27 @@ static const 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;
|
||||
@ -1001,6 +1023,8 @@ static const struct spec **lookup_all(struct selabel_handle *rec,
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
if (!result[0])
|
||||
errno = ENOENT;
|
||||
|
||||
finish:
|
||||
free(clean_key);
|
||||
@ -1016,11 +1040,11 @@ static struct spec *lookup_common(struct selabel_handle *rec,
|
||||
const char *key,
|
||||
int type,
|
||||
bool partial) {
|
||||
const struct spec **matches = lookup_all(rec, key, type, partial, NULL);
|
||||
struct spec **matches = lookup_all(rec, key, type, partial, NULL);
|
||||
if (!matches) {
|
||||
return NULL;
|
||||
}
|
||||
struct spec *result = (struct spec*)matches[0];
|
||||
struct spec *result = matches[0];
|
||||
free(matches);
|
||||
return result;
|
||||
}
|
||||
@ -1083,7 +1107,7 @@ static bool hash_all_partial_matches(struct selabel_handle *rec, const char *key
|
||||
assert(digest);
|
||||
|
||||
size_t total_matches;
|
||||
const struct spec **matches = lookup_all(rec, key, 0, true, &total_matches);
|
||||
struct spec **matches = lookup_all(rec, key, 0, true, &total_matches);
|
||||
if (!matches) {
|
||||
return false;
|
||||
}
|
||||
|
@ -286,7 +286,6 @@ 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;
|
||||
@ -308,6 +307,7 @@ 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,7 +321,11 @@ static inline int find_stem_from_spec(struct saved_data *data, const char *buf)
|
||||
if (!stem)
|
||||
return -1;
|
||||
|
||||
return store_stem(data, stem, stem_len);
|
||||
r = store_stem(data, stem, stem_len);
|
||||
if (r < 0)
|
||||
free(stem);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* This will always check for buffer over-runs and either read the next entry
|
||||
@ -441,9 +445,15 @@ 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;
|
||||
selinux_log(SELINUX_ERROR,
|
||||
"%s: line %u error due to: %s\n", path,
|
||||
lineno, errbuf ?: strerror(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);
|
||||
}
|
||||
errno = rc;
|
||||
return -1;
|
||||
}
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include <stdio.h>
|
||||
#include <selinux/selinux.h>
|
||||
#include <selinux/label.h>
|
||||
#include "dso.h"
|
||||
#include "sha1.h"
|
||||
|
||||
#if defined(ANDROID) || defined(__APPLE__)
|
||||
@ -26,22 +25,22 @@
|
||||
*/
|
||||
int selabel_file_init(struct selabel_handle *rec,
|
||||
const struct selinux_opt *opts,
|
||||
unsigned nopts) hidden;
|
||||
unsigned nopts) ;
|
||||
int selabel_media_init(struct selabel_handle *rec,
|
||||
const struct selinux_opt *opts,
|
||||
unsigned nopts) hidden;
|
||||
unsigned nopts) ;
|
||||
int selabel_x_init(struct selabel_handle *rec,
|
||||
const struct selinux_opt *opts,
|
||||
unsigned nopts) hidden;
|
||||
unsigned nopts) ;
|
||||
int selabel_db_init(struct selabel_handle *rec,
|
||||
const struct selinux_opt *opts,
|
||||
unsigned nopts) hidden;
|
||||
unsigned nopts) ;
|
||||
int selabel_property_init(struct selabel_handle *rec,
|
||||
const struct selinux_opt *opts,
|
||||
unsigned nopts) hidden;
|
||||
unsigned nopts) ;
|
||||
int selabel_exact_match_init(struct selabel_handle *rec,
|
||||
const struct selinux_opt *opts,
|
||||
unsigned nopts) hidden;
|
||||
unsigned nopts) ;
|
||||
|
||||
/*
|
||||
* Labeling internal structures
|
||||
@ -122,24 +121,26 @@ struct selabel_handle {
|
||||
*/
|
||||
extern int
|
||||
selabel_validate(struct selabel_handle *rec,
|
||||
struct selabel_lookup_rec *contexts) hidden;
|
||||
struct selabel_lookup_rec *contexts) ;
|
||||
|
||||
/*
|
||||
* Compatibility support
|
||||
*/
|
||||
extern int myprintf_compat;
|
||||
extern void __attribute__ ((format(printf, 1, 2)))
|
||||
(*myprintf) (const char *fmt, ...) hidden;
|
||||
(*myprintf) (const char *fmt, ...) ;
|
||||
|
||||
#define COMPAT_LOG(type, fmt...) if (myprintf_compat) \
|
||||
myprintf(fmt); \
|
||||
else \
|
||||
selinux_log(type, fmt);
|
||||
#define COMPAT_LOG(type, fmt...) do { \
|
||||
if (myprintf_compat) \
|
||||
myprintf(fmt); \
|
||||
else \
|
||||
selinux_log(type, fmt); \
|
||||
} while (0)
|
||||
|
||||
extern int
|
||||
compat_validate(struct selabel_handle *rec,
|
||||
struct selabel_lookup_rec *contexts,
|
||||
const char *path, unsigned lineno) hidden;
|
||||
const char *path, unsigned lineno) ;
|
||||
|
||||
/*
|
||||
* The read_spec_entries function may be used to
|
||||
|
@ -119,7 +119,6 @@ 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) {
|
||||
|
@ -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 hidden read_spec_entries(char *line_buf, const char **errbuf, int num_args, ...)
|
||||
int 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 hidden 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 hidden digest_gen_hash(struct selabel_digest *digest)
|
||||
void digest_gen_hash(struct selabel_digest *digest)
|
||||
{
|
||||
Sha1Context context;
|
||||
|
||||
@ -141,7 +141,7 @@ void hidden digest_gen_hash(struct selabel_digest *digest)
|
||||
*
|
||||
* Return %0 on success, -%1 with @errno set on failure.
|
||||
*/
|
||||
int hidden digest_add_specfile(struct selabel_digest *digest, FILE *fp,
|
||||
int digest_add_specfile(struct selabel_digest *digest, FILE *fp,
|
||||
char *from_addr, size_t buf_len,
|
||||
const char *path)
|
||||
{
|
||||
|
@ -146,7 +146,6 @@ 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) {
|
||||
|
@ -49,7 +49,6 @@ int lgetfilecon_raw(const char *path, char ** context)
|
||||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(lgetfilecon_raw)
|
||||
|
||||
int lgetfilecon(const char *path, char ** context)
|
||||
{
|
||||
|
242
libselinux/src/libselinux.map
Normal file
242
libselinux/src/libselinux.map
Normal file
@ -0,0 +1,242 @@
|
||||
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:
|
||||
*;
|
||||
};
|
@ -45,7 +45,6 @@ int security_load_policy(void *data, size_t len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
hidden_def(security_load_policy)
|
||||
|
||||
#ifndef ANDROID
|
||||
#undef max
|
||||
@ -77,11 +76,11 @@ int selinux_mkload_policy(int preservebools __attribute__((unused)))
|
||||
#ifdef SHARED
|
||||
char *errormsg = NULL;
|
||||
void *libsepolh = NULL;
|
||||
libsepolh = dlopen("libsepol.so.1", RTLD_NOW);
|
||||
libsepolh = dlopen("libsepol.so.2", RTLD_NOW);
|
||||
if (libsepolh) {
|
||||
usesepol = 1;
|
||||
dlerror();
|
||||
#define DLERR() if ((errormsg = dlerror())) goto dlclose;
|
||||
#define DLERR() do { if ((errormsg = dlerror())) goto dlclose; } while (0)
|
||||
vers_max = dlsym(libsepolh, "sepol_policy_kern_vers_max");
|
||||
DLERR();
|
||||
vers_min = dlsym(libsepolh, "sepol_policy_kern_vers_min");
|
||||
@ -138,15 +137,15 @@ int selinux_mkload_policy(int preservebools __attribute__((unused)))
|
||||
}
|
||||
if (fd < 0) {
|
||||
fprintf(stderr,
|
||||
"SELinux: Could not open policy file <= %s.%d: %s\n",
|
||||
selinux_binary_policy_path(), maxvers, strerror(errno));
|
||||
"SELinux: Could not open policy file <= %s.%d: %m\n",
|
||||
selinux_binary_policy_path(), maxvers);
|
||||
goto dlclose;
|
||||
}
|
||||
|
||||
if (fstat(fd, &sb) < 0) {
|
||||
fprintf(stderr,
|
||||
"SELinux: Could not stat policy file %s: %s\n",
|
||||
path, strerror(errno));
|
||||
"SELinux: Could not stat policy file %s: %m\n",
|
||||
path);
|
||||
goto close;
|
||||
}
|
||||
|
||||
@ -154,8 +153,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: %s\n",
|
||||
path, strerror(errno));
|
||||
"SELinux: Could not map policy file %s: %m\n",
|
||||
path);
|
||||
goto close;
|
||||
}
|
||||
|
||||
@ -194,8 +193,8 @@ int selinux_mkload_policy(int preservebools __attribute__((unused)))
|
||||
|
||||
if (rc)
|
||||
fprintf(stderr,
|
||||
"SELinux: Could not load policy file %s: %s\n",
|
||||
path, strerror(errno));
|
||||
"SELinux: Could not load policy file %s: %m\n",
|
||||
path);
|
||||
|
||||
unmap:
|
||||
if (data != map)
|
||||
@ -213,7 +212,6 @@ int selinux_mkload_policy(int preservebools __attribute__((unused)))
|
||||
return rc;
|
||||
}
|
||||
|
||||
hidden_def(selinux_mkload_policy)
|
||||
|
||||
/*
|
||||
* Mount point for selinuxfs.
|
||||
@ -281,7 +279,8 @@ 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) {
|
||||
if (mount(SELINUXFS, SELINUXMNT, SELINUXFS, 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) {
|
||||
mntpoint = SELINUXMNT;
|
||||
} else {
|
||||
/* check old mountpoint */
|
||||
@ -307,7 +306,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: %s\n", SELINUXMNT, strerror(errno));
|
||||
fprintf(stderr, "Mount failed for selinuxfs on %s: %m\n", SELINUXMNT);
|
||||
}
|
||||
|
||||
if (rc == 0)
|
||||
@ -353,7 +352,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: %s\n", (*enforce ? "enforcing" : "permissive"), strerror(errno));
|
||||
fprintf(stderr, "SELinux: Unable to switch to %s mode: %m\n", (*enforce ? "enforcing" : "permissive"));
|
||||
if (*enforce)
|
||||
goto noload;
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ int lsetfilecon_raw(const char *path, const char * context)
|
||||
return rc;
|
||||
}
|
||||
|
||||
hidden_def(lsetfilecon_raw)
|
||||
|
||||
int lsetfilecon(const char *path, const char *context)
|
||||
{
|
||||
|
@ -22,6 +22,7 @@ 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])
|
||||
|
@ -78,17 +78,30 @@ 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;
|
||||
con_array = (char **)realloc(con_array, sizeof(char*) *
|
||||
tmp = (char **)realloc(con_array, sizeof(char*) *
|
||||
con_array_size);
|
||||
if (!con_array) {
|
||||
con_array_size = con_array_used = 0;
|
||||
if (!tmp) {
|
||||
free_array_elts();
|
||||
return -1;
|
||||
}
|
||||
con_array = tmp;
|
||||
}
|
||||
} else {
|
||||
con_array_size = 1000;
|
||||
@ -105,13 +118,6 @@ 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;
|
||||
@ -315,14 +321,24 @@ 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();
|
||||
matchpathcon_fini_internal();
|
||||
}
|
||||
|
||||
void __attribute__((destructor)) matchpathcon_lib_destructor(void);
|
||||
|
||||
void hidden __attribute__((destructor)) matchpathcon_lib_destructor(void)
|
||||
void __attribute__((destructor)) matchpathcon_lib_destructor(void)
|
||||
{
|
||||
if (destructor_key_initialized)
|
||||
__selinux_key_delete(destructor_key);
|
||||
@ -351,7 +367,6 @@ 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)
|
||||
{
|
||||
@ -360,12 +375,7 @@ int matchpathcon_init(const char *path)
|
||||
|
||||
void matchpathcon_fini(void)
|
||||
{
|
||||
free_array_elts();
|
||||
|
||||
if (hnd) {
|
||||
selabel_close(hnd);
|
||||
hnd = NULL;
|
||||
}
|
||||
matchpathcon_fini_internal();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -383,8 +393,8 @@ int realpath_not_final(const char *name, char *resolved_path)
|
||||
|
||||
tmp_path = strdup(name);
|
||||
if (!tmp_path) {
|
||||
myprintf("symlink_realpath(%s) strdup() failed: %s\n",
|
||||
name, strerror(errno));
|
||||
myprintf("symlink_realpath(%s) strdup() failed: %m\n",
|
||||
name);
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
@ -404,8 +414,8 @@ int realpath_not_final(const char *name, char *resolved_path)
|
||||
}
|
||||
|
||||
if (!p) {
|
||||
myprintf("symlink_realpath(%s) realpath() failed: %s\n",
|
||||
name, strerror(errno));
|
||||
myprintf("symlink_realpath(%s) realpath() failed: %m\n",
|
||||
name);
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
@ -428,7 +438,7 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int matchpathcon(const char *path, mode_t mode, char ** con)
|
||||
static int matchpathcon_internal(const char *path, mode_t mode, char ** con)
|
||||
{
|
||||
char stackpath[PATH_MAX + 1];
|
||||
char *p = NULL;
|
||||
@ -449,9 +459,13 @@ int matchpathcon(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(name, mode, con);
|
||||
int i = matchpathcon_internal(name, mode, con);
|
||||
|
||||
if (i < 0)
|
||||
return -1;
|
||||
@ -469,15 +483,15 @@ void matchpathcon_checkmatches(char *str __attribute__((unused)))
|
||||
int selinux_file_context_cmp(const char * a,
|
||||
const char * b)
|
||||
{
|
||||
char *rest_a, *rest_b; /* Rest of the context after the user */
|
||||
const 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((char *)a, ':');
|
||||
rest_b = strchr((char *)b, ':');
|
||||
rest_a = strchr(a, ':');
|
||||
rest_b = strchr(b, ':');
|
||||
if (!rest_a && !rest_b)
|
||||
return 0;
|
||||
if (!rest_a)
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "selinux_internal.h"
|
||||
#include <stdio.h>
|
||||
#include "policy.h"
|
||||
#include "dso.h"
|
||||
#include <limits.h>
|
||||
|
||||
int security_policyvers(void)
|
||||
@ -42,4 +41,3 @@ int security_policyvers(void)
|
||||
return vers;
|
||||
}
|
||||
|
||||
hidden_def(security_policyvers)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user