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:
Thiébaud Weksteen 2021-10-27 04:50:56 +00:00
parent c65aca49bb
commit 454466e2e4
403 changed files with 11609 additions and 9152 deletions

39
.github/workflows/cifuzz.yml vendored Normal file
View 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
View 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
View 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

View file

@ -1,164 +1,12 @@
# Define the building environment # Define the building environment
language: c language: c
matrix: # Use Travis-CI Ubuntu 18.04 Bionic Beaver, "full image" variant
fast_finish: true
compiler:
- clang
- gcc
env:
matrix:
# Test the last version of Python and Ruby together, with some linkers
- PYVER=python3.7 RUBYLIBVER=2.6
- PYVER=python3.7 RUBYLIBVER=2.6 TEST_FLAGS_OVERRIDE=1
- PYVER=python3.7 RUBYLIBVER=2.6 TEST_DEBUG=1
- PYVER=python3.7 RUBYLIBVER=2.6 LINKER=gold
- PYVER=python3.7 RUBYLIBVER=2.6 LINKER=bfd
# Test several Python versions
- PYVER=python3.5 RUBYLIBVER=2.6
- PYVER=python3.6 RUBYLIBVER=2.6
- PYVER=pypy3.5-6.0 RUBYLIBVER=2.6
# Test several Ruby versions (http://rubies.travis-ci.org/)
- PYVER=python3.7 RUBYLIBVER=2.5.1
- PYVER=python3.7 RUBYLIBVER=2.4
- PYVER=python3.7 RUBYLIBVER=2.3
- PYVER=python3.7 RUBYLIBVER=2.2
matrix:
exclude:
- compiler: clang
env: PYVER=python3.7 RUBYLIBVER=2.6 LINKER=gold
- compiler: clang
env: PYVER=python3.7 RUBYLIBVER=2.6 LINKER=bfd
# Use Travis-CI Ubuntu 16.04 Xenial Xerus infrastructure, "full image" variant
sudo: required sudo: required
dist: xenial dist: bionic
# Install SELinux userspace utilities dependencies
addons:
apt:
packages:
- bison
- flex
- gawk
- gettext
- libaudit-dev
- libbz2-dev
- libcap-dev
- libcap-ng-dev # This package is not whitelisted for the container infrastructure (https://github.com/travis-ci/apt-package-whitelist/issues/1096)
- libcunit1-dev
- libdbus-glib-1-dev
- libncurses5-dev
- libpcre3-dev
- patch
- python3-dev
- python-dev
- swig
- xmlto
install:
# Download and install refpolicy headers for sepolgen tests
- curl --location --retry 10 -o "$TRAVIS_BUILD_DIR/refpolicy.tar.bz2" https://github.com/SELinuxProject/refpolicy/releases/download/RELEASE_2_20180701/refpolicy-2.20180701.tar.bz2
- tar -C "$TRAVIS_BUILD_DIR" -xvjf "$TRAVIS_BUILD_DIR/refpolicy.tar.bz2"
# Make refpolicy Makefile use the new toolchain when building modules
- sed -e "s,^PREFIX :=.*,PREFIX := \$(DESTDIR)/usr," -i "$TRAVIS_BUILD_DIR/refpolicy/support/Makefile.devel"
- sudo make -C "$TRAVIS_BUILD_DIR/refpolicy" install-headers
- sudo rm -rf "$TRAVIS_BUILD_DIR/refpolicy.tar.bz2" "$TRAVIS_BUILD_DIR/refpolicy"
- sudo mkdir -p /etc/selinux
- echo 'SELINUXTYPE=refpolicy' | sudo tee /etc/selinux/config
- echo 'SELINUX_DEVEL_PATH = /usr/share/selinux/refpolicy' | sudo tee /etc/selinux/sepolgen.conf
# Make sepolgen tests work without really installing anything in the real root (doing this would conflict with Ubuntu packages)
- sed -e "s,\"\(/usr/bin/[cs]\),\"$TRAVIS_BUILD_DIR/installdir\1," -i python/sepolgen/src/sepolgen/module.py
# Download the required python version if it is not installed
- VIRTUAL_ENV="$HOME/virtualenv/$PYVER"
- if ! [ -d "$VIRTUAL_ENV" ] ; then
curl --retry 10 -o python.tar.bz2 "https://s3.amazonaws.com/travis-python-archives/binaries/ubuntu/16.04/x86_64/${PYVER/python/python-}.tar.bz2" &&
sudo tar xjf python.tar.bz2 --directory / &&
rm python.tar.bz2 ;
fi
# Install flake8 for the given python version
- $VIRTUAL_ENV/bin/pip install flake8
before_script:
# Build and install in a temporary directory to run tests
- export DESTDIR="$TRAVIS_BUILD_DIR/installdir"
# Configure the variables for Python parts
- export VIRTUAL_ENV="$HOME/virtualenv/$PYVER"
- export PYTHON="$VIRTUAL_ENV/bin/python"
# Use the header files in /opt/python/... for Python because the virtualenvs do not provide Python.h
- export PKG_CONFIG_PATH="/opt/python/$($PYTHON -c 'import sys;print("%d.%d.%d" % sys.version_info[:3])')/lib/pkgconfig"
# PyPy does not provide a config file for pkg-config
# libpypy-c.so is provided in bin/libpypy-c.so for PyPy and bin/libpypy3-c.so for PyPy3
- if echo "$PYVER" | grep -q pypy ; then
export PYINC=-I$($PYTHON -c 'import sys;print(sys.prefix)')/include ;
export PYLIBS="$($PYTHON -c 'import sys;print("-L%s/bin -l%s" % (sys.prefix, "pypy-c" if sys.version_info < (3,) else "pypy3-c"))')" ;
fi
# Find the Ruby executable with version $RUBYLIBVER
- rvm reinstall ruby-$RUBYLIBVER --binary
- export RUBY="$(ls -d -1 "$HOME/.rvm/rubies/ruby-$RUBYLIBVER"*/bin/ruby | head -n 1)"
# Set the linker in $CC so that it gets used everywhere
- if [ -n "$LINKER" ]; then CC="$CC -fuse-ld=$LINKER" ; fi
# Show variables and versions (to help debugging)
- echo "$CC" ; $CC --version
- echo "$PYTHON" ; $PYTHON --version
- echo "$RUBY" ; $RUBY --version
# If TEST_FLAGS_OVERRIDE is defined, test that overriding CFLAGS, LDFLAGS and other variables works fine
- if [ -n "$TEST_FLAGS_OVERRIDE" ]; then EXPLICIT_MAKE_VARS="CFLAGS=-I$DESTDIR/usr/include LDFLAGS=-L$DESTDIR/usr/lib LDLIBS= CPPFLAGS=" ; fi
# If TEST_DEBUG is defined, test that debug build works fine
- if [ -n "$TEST_DEBUG" ]; then EXPLICIT_MAKE_VARS="$EXPLICIT_MAKE_VARS DEBUG=1" ; fi
script: script:
# Start by installing everything into $DESTDIR - FEDORA_MAJOR=33 FEDORA_MINOR=1.2 scripts/ci/travis-kvm-setup.sh
- make install $EXPLICIT_MAKE_VARS -k
- make install-pywrap $EXPLICIT_MAKE_VARS -k
- make install-rubywrap $EXPLICIT_MAKE_VARS -k
# Now that everything is installed, run "make all" to build everything which may have not been built
- make all $EXPLICIT_MAKE_VARS -k
# Set up environment variables for the tests
- . ./scripts/env_use_destdir
# Show variables (to help debugging issues)
- echo "$LD_LIBRARY_PATH"
- echo "$PATH"
- echo "$PYTHONPATH"
- echo "$RUBYLIB"
# Run tests
- make test $EXPLICIT_MAKE_VARS
# Test Python and Ruby wrappers
- $PYTHON -c 'import selinux;import selinux.audit2why;import semanage;print(selinux.is_selinux_enabled())'
- $RUBY -e 'require "selinux";require "semanage";puts Selinux::is_selinux_enabled()'
# Run Python linter
- PATH="$VIRTUAL_ENV/bin:$PATH" ./scripts/run-flake8
# Remove every installed files
- rm -rf "$DESTDIR"
# Test that "git status" looks clean, or print a clear error message
- |-
git status --short | sed -n 's/^??/error: missing .gitignore entry for/p' | (! grep '^')
# Clean up everything and show which file would be added to "make clean"
- make clean distclean $EXPLICIT_MAKE_VARS
- |-
git ls-files --ignored --others --exclude-standard | sed 's/^/error: "make clean distclean" did not remove /' | (! grep '^')
# Do not spam by email so long as the build succeeds # Do not spam by email so long as the build succeeds
notifications: notifications:

25
README
View file

@ -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
View 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

1
VERSION Normal file
View file

@ -0,0 +1 @@
3.3-rc1

View file

@ -10,7 +10,7 @@ TARGETS = checkpolicy checkmodule
LEX = flex LEX = flex
YACC = bison -y 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 # If no specific libsepol.a is specified, fall back on LDFLAGS search path
# Otherwise, as $(LIBSEPOLA) already appears in the dependencies, there # Otherwise, as $(LIBSEPOLA) already appears in the dependencies, there
@ -30,10 +30,10 @@ all: $(TARGETS)
$(MAKE) -C test $(MAKE) -C test
checkpolicy: $(CHECKPOLOBJS) $(LIBSEPOLA) checkpolicy: $(CHECKPOLOBJS) $(LIBSEPOLA)
$(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS_LIBSEPOLA) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LDLIBS_LIBSEPOLA)
checkmodule: $(CHECKMODOBJS) $(LIBSEPOLA) checkmodule: $(CHECKMODOBJS) $(LIBSEPOLA)
$(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS_LIBSEPOLA) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LDLIBS_LIBSEPOLA)
%.o: %.c %.o: %.c
$(CC) $(CFLAGS) -o $@ -c $< $(CC) $(CFLAGS) -o $@ -c $<

View file

@ -1 +1 @@
3.0 3.3-rc1

View file

@ -28,6 +28,9 @@ module file. This option is a development/debugging aid.
.B \-C,\-\-cil .B \-C,\-\-cil
Write CIL policy file rather than binary policy file. Write CIL policy file rather than binary policy file.
.TP .TP
.B \-E,\-\-werror
Treat warnings as errors
.TP
.B \-h,\-\-help .B \-h,\-\-help
Print usage. Print usage.
.TP .TP
@ -64,6 +67,6 @@ SELinux Reference Policy documentation at https://github.com/SELinuxProject/refp
.SH AUTHOR .SH AUTHOR
This manual page was copied from the checkpolicy man page 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>. and edited by Dan Walsh <dwalsh@redhat.com>.
The program was written by Stephen Smalley <sds@tycho.nsa.gov>. The program was written by Stephen Smalley <sds@tycho.nsa.gov>.

View file

@ -25,7 +25,6 @@
#include <sepol/policydb/policydb.h> #include <sepol/policydb/policydb.h>
#include <sepol/policydb/services.h> #include <sepol/policydb/services.h>
#include <sepol/policydb/conditional.h> #include <sepol/policydb/conditional.h>
#include <sepol/policydb/flask.h>
#include <sepol/policydb/hierarchy.h> #include <sepol/policydb/hierarchy.h>
#include <sepol/policydb/expand.h> #include <sepol/policydb/expand.h>
#include <sepol/policydb/link.h> #include <sepol/policydb/link.h>
@ -41,6 +40,7 @@ extern int optind;
static sidtab_t sidtab; static sidtab_t sidtab;
extern int mlspol; extern int mlspol;
extern int werror;
static int handle_unknown = SEPOL_DENY_UNKNOWN; static int handle_unknown = SEPOL_DENY_UNKNOWN;
static const char *txtfile = "policy.conf"; 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) 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("Build base and policy modules.\n");
printf("Options:\n"); printf("Options:\n");
printf(" INPUT build module from INPUT (else read from \"%s\")\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(" -V show policy versions created by this program\n");
printf(" -b treat input as a binary policy file\n"); printf(" -b treat input as a binary policy file\n");
printf(" -C output CIL policy instead of binary policy\n"); printf(" -C output CIL policy instead of binary policy\n");
printf(" -E treat warnings as errors\n");
printf(" -h print usage\n"); printf(" -h print usage\n");
printf(" -U OPTION How to handle unknown classes and permissions\n"); printf(" -U OPTION How to handle unknown classes and permissions\n");
printf(" deny: Deny unknown kernel checks\n"); printf(" deny: Deny unknown kernel checks\n");
@ -162,10 +163,11 @@ int main(int argc, char **argv)
{"handle-unknown", required_argument, NULL, 'U'}, {"handle-unknown", required_argument, NULL, 'U'},
{"mls", no_argument, NULL, 'M'}, {"mls", no_argument, NULL, 'M'},
{"cil", no_argument, NULL, 'C'}, {"cil", no_argument, NULL, 'C'},
{"werror", no_argument, NULL, 'E'},
{NULL, 0, NULL, 0} {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) { switch (ch) {
case 'h': case 'h':
usage(argv[0]); usage(argv[0]);
@ -180,6 +182,9 @@ int main(int argc, char **argv)
case 'V': case 'V':
show_version = 1; show_version = 1;
break; break;
case 'E':
werror = 1;
break;
case 'U': case 'U':
if (!strcasecmp(optarg, "deny")) { if (!strcasecmp(optarg, "deny")) {
handle_unknown = DENY_UNKNOWN; handle_unknown = DENY_UNKNOWN;
@ -283,14 +288,16 @@ int main(int argc, char **argv)
} }
if (policy_type != POLICY_BASE && outfile) { if (policy_type != POLICY_BASE && outfile) {
char *out_name;
char *separator;
char *mod_name = modpolicydb.name; char *mod_name = modpolicydb.name;
char *out_path = strdup(outfile); char *out_path = strdup(outfile);
if (out_path == NULL) { if (out_path == NULL) {
fprintf(stderr, "%s: out of memory\n", argv[0]); fprintf(stderr, "%s: out of memory\n", argv[0]);
exit(1); exit(1);
} }
char *out_name = basename(out_path); out_name = basename(out_path);
char *separator = strrchr(out_name, '.'); separator = strrchr(out_name, '.');
if (separator) { if (separator) {
*separator = '\0'; *separator = '\0';
} }

View file

@ -53,6 +53,9 @@ Specify the target platform (selinux or xen).
.B \-O,\-\-optimize .B \-O,\-\-optimize
Optimize the final kernel policy (remove redundant rules). Optimize the final kernel policy (remove redundant rules).
.TP .TP
.B \-E,\-\-werror
Treat warnings as errors
.TP
.B \-V,\-\-version .B \-V,\-\-version
Show version information. Show version information.
.TP .TP
@ -64,6 +67,6 @@ SELinux Reference Policy documentation at https://github.com/SELinuxProject/refp
.SH AUTHOR .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>. and edited by Stephen Smalley <sds@tycho.nsa.gov>.
The program was written by Stephen Smalley <sds@tycho.nsa.gov>. The program was written by Stephen Smalley <sds@tycho.nsa.gov>.

View file

@ -85,7 +85,6 @@
#include <sepol/policydb/services.h> #include <sepol/policydb/services.h>
#include <sepol/policydb/conditional.h> #include <sepol/policydb/conditional.h>
#include <sepol/policydb/hierarchy.h> #include <sepol/policydb/hierarchy.h>
#include <sepol/policydb/flask.h>
#include <sepol/policydb/expand.h> #include <sepol/policydb/expand.h>
#include <sepol/policydb/link.h> #include <sepol/policydb/link.h>
@ -101,29 +100,33 @@ static sidtab_t sidtab;
extern policydb_t *policydbp; extern policydb_t *policydbp;
extern int mlspol; extern int mlspol;
extern int werror;
static int handle_unknown = SEPOL_DENY_UNKNOWN; static int handle_unknown = SEPOL_DENY_UNKNOWN;
static const char *txtfile = "policy.conf"; static const char *txtfile = "policy.conf";
static const char *binfile = "policy"; static const char *binfile = "policy";
unsigned int policyvers = POLICYDB_VERSION_MAX; unsigned int policyvers = 0;
static __attribute__((__noreturn__)) void usage(const char *progname) static __attribute__((__noreturn__)) void usage(const char *progname)
{ {
printf printf
("usage: %s [-b[F]] [-C] [-d] [-U handle_unknown (allow,deny,reject)] [-M] " ("usage: %s [-b[F]] [-C] [-d] [-U handle_unknown (allow,deny,reject)] [-M] "
"[-c policyvers (%d-%d)] [-o output_file|-] [-S] " "[-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); progname, POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
exit(1); exit(1);
} }
#define FGETS(out, size, in) \ #define FGETS(out, size, in) \
if (fgets(out,size,in)==NULL) { \ do { \
fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__,\ if (fgets(out,size,in)==NULL) { \
fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__, \
strerror(errno)); \ strerror(errno)); \
exit(1);\ exit(1);\
} } \
} while (0)
static int print_sid(sepol_security_id_t sid, static int print_sid(sepol_security_id_t sid,
context_struct_t * context context_struct_t * context
__attribute__ ((unused)), void *data __attribute__ ((unused)), void *data
@ -421,11 +424,12 @@ int main(int argc, char **argv)
{"conf",no_argument, NULL, 'F'}, {"conf",no_argument, NULL, 'F'},
{"sort", no_argument, NULL, 'S'}, {"sort", no_argument, NULL, 'S'},
{"optimize", no_argument, NULL, 'O'}, {"optimize", no_argument, NULL, 'O'},
{"werror", no_argument, NULL, 'E'},
{"help", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0} {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) { switch (ch) {
case 'o': case 'o':
outfile = optarg; outfile = optarg;
@ -500,10 +504,12 @@ int main(int argc, char **argv)
usage(argv[0]); usage(argv[0]);
exit(1); exit(1);
} }
if (policyvers != n)
policyvers = n; policyvers = n;
break; break;
} }
case 'E':
werror = 1;
break;
case 'h': case 'h':
default: default:
usage(argv[0]); usage(argv[0]);
@ -511,7 +517,8 @@ int main(int argc, char **argv)
} }
if (show_version) { 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); POLICYDB_VERSION_MAX, POLICYDB_VERSION_MIN);
exit(0); exit(0);
} }
@ -584,6 +591,16 @@ int main(int argc, char **argv)
exit(1); 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 { } else {
if (conf) { if (conf) {
fprintf(stderr, "Can only generate policy.conf from binary policy\n"); fprintf(stderr, "Can only generate policy.conf from binary policy\n");
@ -625,6 +642,8 @@ int main(int argc, char **argv)
policydb_destroy(policydbp); policydb_destroy(policydbp);
policydbp = &policydb; policydbp = &policydb;
} }
policydbp->policyvers = policyvers ? policyvers : POLICYDB_VERSION_MAX;
} }
if (policydb_load_isids(&policydb, &sidtab)) if (policydb_load_isids(&policydb, &sidtab))
@ -650,8 +669,6 @@ int main(int argc, char **argv)
} }
} }
policydb.policyvers = policyvers;
if (!cil) { if (!cil) {
if (!conf) { if (!conf) {
policydb.policy_type = POLICY_KERN; policydb.policy_type = POLICY_KERN;
@ -953,8 +970,12 @@ int main(int argc, char **argv)
printf("fs kdevname? "); printf("fs kdevname? ");
FGETS(ans, sizeof(ans), stdin); FGETS(ans, sizeof(ans), stdin);
ans[strlen(ans) - 1] = 0; ans[strlen(ans) - 1] = 0;
sepol_fs_sid(ans, &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); printf("fs_sid %d default_file_sid %d\n", ssid, tsid);
}
break; break;
case '9': case '9':
printf("protocol? "); printf("protocol? ");
@ -982,8 +1003,12 @@ int main(int argc, char **argv)
printf("netif name? "); printf("netif name? ");
FGETS(ans, sizeof(ans), stdin); FGETS(ans, sizeof(ans), stdin);
ans[strlen(ans) - 1] = 0; ans[strlen(ans) - 1] = 0;
sepol_netif_sid(ans, &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); printf("if_sid %d default_msg_sid %d\n", ssid, tsid);
}
break; break;
case 'b':{ case 'b':{
char *p; char *p;
@ -1162,8 +1187,6 @@ int main(int argc, char **argv)
printf("\nNo such class.\n"); printf("\nNo such class.\n");
break; break;
} }
cladatum =
policydb.class_val_to_struct[tclass - 1];
} else { } else {
ans[strlen(ans) - 1] = 0; ans[strlen(ans) - 1] = 0;
cladatum = cladatum =
@ -1215,8 +1238,6 @@ int main(int argc, char **argv)
printf("\nNo such class.\n"); printf("\nNo such class.\n");
break; break;
} }
cladatum =
policydb.class_val_to_struct[tclass - 1];
} else { } else {
ans[strlen(ans) - 1] = 0; ans[strlen(ans) - 1] = 0;
cladatum = cladatum =

View file

@ -28,7 +28,6 @@ extern int yyparse(void);
extern void yyrestart(FILE *); extern void yyrestart(FILE *);
extern queue_t id_queue; extern queue_t id_queue;
extern unsigned int policydb_errors; extern unsigned int policydb_errors;
extern unsigned long policydb_lineno;
extern policydb_t *policydbp; extern policydb_t *policydbp;
extern int mlspol; extern int mlspol;
extern void set_source_file(const char *name); extern void set_source_file(const char *name);

View file

@ -53,7 +53,6 @@
#include <sepol/policydb/policydb.h> #include <sepol/policydb/policydb.h>
#include <sepol/policydb/services.h> #include <sepol/policydb/services.h>
#include <sepol/policydb/conditional.h> #include <sepol/policydb/conditional.h>
#include <sepol/policydb/flask.h>
#include <sepol/policydb/hierarchy.h> #include <sepol/policydb/hierarchy.h>
#include <sepol/policydb/polcaps.h> #include <sepol/policydb/polcaps.h>
#include "queue.h" #include "queue.h"
@ -78,7 +77,7 @@ extern int yyerror(const char *msg);
#define ERRORMSG_LEN 255 #define ERRORMSG_LEN 255
static char errormsg[ERRORMSG_LEN + 1] = {0}; 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); static int parse_security_context(context_struct_t *c);
/* initialize all of the state variables for the scanner/parser */ /* 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 /* If the identifier has a dot within it and that its first character
is not a dot then return 1, else return 0. */ 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) { if (strchr(id, '.') >= id + 1) {
return 1; return 1;
@ -1169,11 +1168,6 @@ int expand_attrib(void)
ebitmap_init(&attrs); ebitmap_init(&attrs);
while ((id = queue_remove(id_queue))) { 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)) { if (!is_id_in_scope(SYM_TYPES, id)) {
yyerror2("attribute %s is not within scope", id); yyerror2("attribute %s is not within scope", id);
goto exit; goto exit;
@ -1802,7 +1796,7 @@ int define_bool_tunable(int is_tunable)
return -1; return -1;
} }
datum->state = (int)(bool_value[0] == 'T') ? 1 : 0; datum->state = (bool_value[0] == 'T') ? 1 : 0;
free(bool_value); free(bool_value);
return 0; return 0;
cleanup: cleanup:
@ -1910,9 +1904,10 @@ int avrule_read_ioctls(struct av_ioctl_range_list **rangehead)
{ {
char *id; char *id;
struct av_ioctl_range_list *rnew, *r = NULL; struct av_ioctl_range_list *rnew, *r = NULL;
*rangehead = NULL;
uint8_t omit = 0; uint8_t omit = 0;
*rangehead = NULL;
/* read in all the ioctl commands */ /* read in all the ioctl commands */
while ((id = queue_remove(id_queue))) { while ((id = queue_remove(id_queue))) {
if (strcmp(id,"~") == 0) { if (strcmp(id,"~") == 0) {
@ -1948,7 +1943,9 @@ int avrule_read_ioctls(struct av_ioctl_range_list **rangehead)
} }
} }
r = *rangehead; r = *rangehead;
if (r) {
r->omit = omit; r->omit = omit;
}
return 0; return 0;
error: error:
yyerror("out of memory"); yyerror("out of memory");
@ -2148,7 +2145,7 @@ out:
/* index of the u32 containing the permission */ /* index of the u32 containing the permission */
#define XPERM_IDX(x) (x >> 5) #define XPERM_IDX(x) (x >> 5)
/* set bits 0 through x-1 within the u32 */ /* 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 */ /* low value for this u32 */
#define XPERM_LOW(x) (x << 5) #define XPERM_LOW(x) (x << 5)
/* high value for this u32 */ /* 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; unsigned int i;
@ -2350,7 +2347,7 @@ unsigned int xperms_for_each_bit(unsigned int *bit, av_extended_perms_t *xperms)
return 0; 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 *src_perms;
class_perm_node_t *dest_perms, *dest_tail; class_perm_node_t *dest_perms, *dest_tail;
@ -2398,7 +2395,7 @@ int avrule_cpy(avrule_t *dest, avrule_t *src)
return 0; return 0;
} }
int define_te_avtab_ioctl(avrule_t *avrule_template) int define_te_avtab_ioctl(const avrule_t *avrule_template)
{ {
avrule_t *avrule; avrule_t *avrule;
struct av_ioctl_range_list *rangelist; struct av_ioctl_range_list *rangelist;
@ -3304,8 +3301,6 @@ int define_filename_trans(void)
ebitmap_t e_stypes, e_ttypes; ebitmap_t e_stypes, e_ttypes;
ebitmap_t e_tclasses; ebitmap_t e_tclasses;
ebitmap_node_t *snode, *tnode, *cnode; ebitmap_node_t *snode, *tnode, *cnode;
filename_trans_t *ft;
filename_trans_datum_t *ftdatum;
filename_trans_rule_t *ftr; filename_trans_rule_t *ftr;
type_datum_t *typdatum; type_datum_t *typdatum;
uint32_t otype; uint32_t otype;
@ -3389,23 +3384,12 @@ int define_filename_trans(void)
ebitmap_for_each_positive_bit(&e_tclasses, cnode, c) { ebitmap_for_each_positive_bit(&e_tclasses, cnode, c) {
ebitmap_for_each_positive_bit(&e_stypes, snode, s) { ebitmap_for_each_positive_bit(&e_stypes, snode, s) {
ebitmap_for_each_positive_bit(&e_ttypes, tnode, t) { ebitmap_for_each_positive_bit(&e_ttypes, tnode, t) {
ft = calloc(1, sizeof(*ft)); rc = policydb_filetrans_insert(
if (!ft) { policydbp, s+1, t+1, c+1, name,
yyerror("out of memory"); NULL, otype, NULL
goto bad; );
} if (rc != SEPOL_OK) {
ft->stype = s+1; if (rc == SEPOL_EEXIST) {
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", yyerror2("duplicate filename transition for: filename_trans %s %s %s:%s",
name, name,
policydbp->p_type_val_to_name[s], policydbp->p_type_val_to_name[s],
@ -3413,16 +3397,6 @@ int define_filename_trans(void)
policydbp->p_class_val_to_name[c]); policydbp->p_class_val_to_name[c]);
goto bad; goto bad;
} }
ftdatum = calloc(1, sizeof(*ftdatum));
if (!ftdatum) {
yyerror("out of memory");
goto bad;
}
rc = hashtab_insert(policydbp->filename_trans,
(hashtab_key_t)ft,
ftdatum);
if (rc) {
yyerror("out of memory"); yyerror("out of memory");
goto bad; goto bad;
} }
@ -3470,9 +3444,10 @@ bad:
return -1; 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) { for (e = expr; e; e = e->next) {
newe = malloc(sizeof(*newe)); newe = malloc(sizeof(*newe));
if (!newe) if (!newe)
@ -3503,12 +3478,7 @@ static constraint_expr_t *constraint_expr_clone(constraint_expr_t * expr)
return h; return h;
oom: oom:
e = h; constraint_expr_destroy(h);
while (e) {
l = e;
e = e->next;
constraint_expr_destroy(l);
}
return NULL; 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) static int set_user_roles(role_set_t * set, char *id)
{ {
role_datum_t *r; role_datum_t *r;
unsigned int i;
ebitmap_node_t *node;
if (strcmp(id, "*") == 0) { if (strcmp(id, "*") == 0) {
free(id); free(id);
@ -4144,12 +4112,9 @@ static int set_user_roles(role_set_t * set, char *id)
return -1; 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); free(id);
if (ebitmap_set_bit(&set->roles, r->s.value - 1, TRUE))
goto oom;
return 0; return 0;
oom: oom:
yyerror("out of memory"); yyerror("out of memory");
@ -5509,7 +5474,9 @@ int define_genfs_context_helper(char *fstype, int has_type)
{ {
struct genfs *genfs_p, *genfs, *newgenfs; struct genfs *genfs_p, *genfs, *newgenfs;
ocontext_t *newc, *c, *head, *p; ocontext_t *newc, *c, *head, *p;
class_datum_t *cladatum;
char *type = NULL; char *type = NULL;
const char *sclass;
int len, len2; int len, len2;
if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
@ -5571,30 +5538,39 @@ int define_genfs_context_helper(char *fstype, int has_type)
} }
switch (type[0]) { switch (type[0]) {
case 'b': case 'b':
newc->v.sclass = SECCLASS_BLK_FILE; sclass = "blk_file";
break; break;
case 'c': case 'c':
newc->v.sclass = SECCLASS_CHR_FILE; sclass = "chr_file";
break; break;
case 'd': case 'd':
newc->v.sclass = SECCLASS_DIR; sclass = "dir";
break; break;
case 'p': case 'p':
newc->v.sclass = SECCLASS_FIFO_FILE; sclass = "fifo_file";
break; break;
case 'l': case 'l':
newc->v.sclass = SECCLASS_LNK_FILE; sclass = "lnk_file";
break; break;
case 's': case 's':
newc->v.sclass = SECCLASS_SOCK_FILE; sclass = "sock_file";
break; break;
case '-': case '-':
newc->v.sclass = SECCLASS_FILE; sclass = "file";
break; break;
default: default:
yyerror2("invalid type %s", type); yyerror2("invalid type %s", type);
goto fail; 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])) if (parse_security_context(&newc->context[0]))
goto fail; goto fail;

View file

@ -46,7 +46,6 @@
#include <sepol/policydb/policydb.h> #include <sepol/policydb/policydb.h>
#include <sepol/policydb/services.h> #include <sepol/policydb/services.h>
#include <sepol/policydb/conditional.h> #include <sepol/policydb/conditional.h>
#include <sepol/policydb/flask.h>
#include <sepol/policydb/hierarchy.h> #include <sepol/policydb/hierarchy.h>
#include <sepol/policydb/polcaps.h> #include <sepol/policydb/polcaps.h>
#include "queue.h" #include "queue.h"

View file

@ -36,6 +36,8 @@ typedef int (* require_func_t)(void);
static char linebuf[2][255]; static char linebuf[2][255];
static unsigned int lno = 0; static unsigned int lno = 0;
int werror = 0;
int yyerror(const char *msg);
int yywarn(const char *msg); int yywarn(const char *msg);
void set_source_file(const char *name); void set_source_file(const char *name);
@ -290,7 +292,7 @@ GLBLUB { return(GLBLUB); }
"]" | "]" |
"~" | "~" |
"*" { return(yytext[0]); } "*" { return(yytext[0]); }
. { yywarn("unrecognized character");} . { yyerror("unrecognized character");}
%% %%
int yyerror(const char *msg) int yyerror(const char *msg)
{ {
@ -310,6 +312,9 @@ int yyerror(const char *msg)
int yywarn(const char *msg) int yywarn(const char *msg)
{ {
if (werror)
return yyerror(msg);
if (source_file[0]) if (source_file[0])
fprintf(stderr, "%s:%ld:", fprintf(stderr, "%s:%ld:",
source_file, source_lineno); source_file, source_lineno);

View file

@ -50,7 +50,7 @@ $ checkmodule \-M \-m httpd.te \-o httpd.mod
.SH АВТОРЫ .SH АВТОРЫ
Эта страница руководства была скопирована со страницы руководства checkpolicy, написанной Arpad Magosanyi <mag@bunuel.tii.matav.hu>, Эта страница руководства была скопирована со страницы руководства checkpolicy, написанной Árpád Magosányi <mag@bunuel.tii.matav.hu>,
и отредактирована Dan Walsh <dwalsh@redhat.com>. и отредактирована Dan Walsh <dwalsh@redhat.com>.
Программа была написана Stephen Smalley <sds@tycho.nsa.gov>. Программа была написана Stephen Smalley <sds@tycho.nsa.gov>.
Перевод на русский язык выполнила Герасименко Олеся <gammaray@basealt.ru>. Перевод на русский язык выполнила Олеся Герасименко <gammaray@basealt.ru>.

View file

@ -54,7 +54,7 @@ checkpolicy \- компилятор политики SELinux
Документация SELinux Reference Policy по адресу https://github.com/SELinuxProject/refpolicy/wiki Документация SELinux Reference Policy по адресу https://github.com/SELinuxProject/refpolicy/wiki
.SH АВТОРЫ .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>.
Программа была написана Stephen Smalley <sds@tycho.nsa.gov>. Программа была написана Stephen Smalley <sds@tycho.nsa.gov>.
Перевод на русский язык выполнила Герасименко Олеся <gammaray@basealt.ru>. Перевод на русский язык выполнила Олеся Герасименко <gammaray@basealt.ru>.

View file

@ -1,7 +1,7 @@
# #
# Makefile for building the dispol program # 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 # If no specific libsepol.a is specified, fall back on LDFLAGS search path
# Otherwise, as $(LIBSEPOLA) already appears in the dependencies, there # Otherwise, as $(LIBSEPOLA) already appears in the dependencies, there
@ -13,10 +13,10 @@ endif
all: dispol dismod all: dispol dismod
dispol: dispol.o $(LIBSEPOLA) dispol: dispol.o $(LIBSEPOLA)
$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS_LIBSEPOLA) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS_LIBSEPOLA)
dismod: dismod.o $(LIBSEPOLA) dismod: dismod.o $(LIBSEPOLA)
$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS_LIBSEPOLA) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS_LIBSEPOLA)
clean: clean:
-rm -f dispol dismod *.o -rm -f dispol dismod *.o

View file

@ -30,7 +30,6 @@
#include <sepol/policydb/policydb.h> #include <sepol/policydb/policydb.h>
#include <sepol/policydb/services.h> #include <sepol/policydb/services.h>
#include <sepol/policydb/conditional.h> #include <sepol/policydb/conditional.h>
#include <sepol/policydb/flask.h>
#include <sepol/policydb/link.h> #include <sepol/policydb/link.h>
#include <sepol/policydb/module.h> #include <sepol/policydb/module.h>
#include <sepol/policydb/util.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) FILE * fp)
{ {
unsigned int i, num_types; 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; 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; 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) FILE * fp)
{ {
class_perm_node_t *cur; class_perm_node_t *cur;
@ -314,7 +313,7 @@ int display_avrule(avrule_t * avrule, policydb_t * policy,
return 0; 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; type_datum_t *type;
FILE *fp; FILE *fp;
@ -356,14 +355,14 @@ int display_type_callback(hashtab_key_t key, hashtab_datum_t datum, void *data)
return 0; 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)) if (hashtab_map(p->p_types.table, display_type_callback, fp))
return -1; return -1;
return 0; return 0;
} }
int display_users(policydb_t * p, FILE * fp) static int display_users(policydb_t * p, FILE * fp)
{ {
unsigned int i, j; unsigned int i, j;
ebitmap_t *bitmap; ebitmap_t *bitmap;
@ -382,7 +381,7 @@ int display_users(policydb_t * p, FILE * fp)
return 0; return 0;
} }
int display_bools(policydb_t * p, FILE * fp) static int display_bools(policydb_t * p, FILE * fp)
{ {
unsigned int i; unsigned int i;
@ -393,7 +392,7 @@ int display_bools(policydb_t * p, FILE * fp)
return 0; 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; 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 /* There was an attempt to implement this at one time. Look through
* git history to find it. */ * git history to find it. */
fprintf(fp, "Sorry, not implemented\n"); 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; ocontext_t *cur;
char *user, *role, *type; char *user, *role, *type;
@ -460,7 +459,7 @@ void display_initial_sids(policydb_t * p, FILE * fp)
#endif #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; unsigned int i, num = 0;
@ -483,7 +482,7 @@ void display_class_set(ebitmap_t *classes, policydb_t *p, FILE *fp)
fprintf(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) { for (; tr; tr = tr->next) {
fprintf(fp, "role transition "); 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) { for (; ra; ra = ra->next) {
fprintf(fp, "role allow "); 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) hashtab_datum_t datum, void *data)
{ {
role_datum_t *role; role_datum_t *role;
@ -612,7 +611,7 @@ int change_bool(char *name, int state, policydb_t * p, FILE * fp)
} }
#endif #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) policydb_t * policy, FILE * out_fp)
{ {
fprintf(out_fp, "decl %u:%s\n", decl->decl_id, 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 */ 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) FILE * out_fp)
{ {
avrule_block_t *block = policydb.global; avrule_block_t *block = policydb.global;
while (block != NULL) { while (block != NULL) {
fprintf(out_fp, "--- begin avrule block ---\n");
avrule_decl_t *decl = block->branch_list; avrule_decl_t *decl = block->branch_list;
fprintf(out_fp, "--- begin avrule block ---\n");
while (decl != NULL) { while (decl != NULL) {
if (display_avdecl(decl, field, policy, out_fp)) { if (display_avdecl(decl, field, policy, out_fp)) {
return -1; return -1;
@ -711,7 +710,7 @@ int display_avblock(int field, policydb_t * policy,
return 0; 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) if (p->handle_unknown == ALLOW_UNKNOWN)
fprintf(out_fp, "Allow unknown classes and perms\n"); 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) { ebitmap_for_each_positive_bit(&p->policycaps, node, i) {
capname = sepol_polcap_getname(i); capname = sepol_polcap_getname(i);
if (capname == NULL) { if (capname == NULL) {
snprintf(buf, sizeof(buf), "unknown (%d)", i); snprintf(buf, sizeof(buf), "unknown (%u)", i);
capname = buf; capname = buf;
} }
fprintf(fp, "\t%s\n", capname); fprintf(fp, "\t%s\n", capname);
} }
} }
int menu(void) static int menu(void)
{ {
printf("\nSelect a command:\n"); printf("\nSelect a command:\n");
printf("1) display unconditional AVTAB\n"); printf("1) display unconditional AVTAB\n");

View file

@ -42,7 +42,7 @@ static __attribute__((__noreturn__)) void usage(const char *progname)
exit(1); 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) FILE * fp)
{ {
char *perm; char *perm;
@ -54,13 +54,13 @@ int render_access_mask(uint32_t mask, avtab_key_t * key, policydb_t * p,
return 0; 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]); fprintf(fp, "%s", p->p_type_val_to_name[type - 1]);
return 0; 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; char *stype, *ttype, *tclass;
stype = p->p_type_val_to_name[key->source_type - 1]; 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_DISABLED 0x0004
#define RENDER_CONDITIONAL (RENDER_ENABLED|RENDER_DISABLED) #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) policydb_t * p, FILE * fp)
{ {
if (!(what & RENDER_UNCONDITIONAL)) { 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; 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; unsigned int i;
avtab_ptr_t cur; avtab_ptr_t cur;
@ -178,7 +178,7 @@ int display_avtab(avtab_t * a, uint32_t what, policydb_t * p, FILE * fp)
return 0; return 0;
} }
int display_bools(policydb_t * p, FILE * fp) static int display_bools(policydb_t * p, FILE * fp)
{ {
unsigned int i; unsigned int i;
@ -189,7 +189,7 @@ int display_bools(policydb_t * p, FILE * fp)
return 0; 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; 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_node_t *cur;
cond_av_list_t *av_cur; cond_av_list_t *av_cur;
@ -249,7 +249,7 @@ int display_cond_expressions(policydb_t * p, FILE * fp)
return 0; 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) if (p->handle_unknown == ALLOW_UNKNOWN)
fprintf(out_fp, "Allow unknown classes and permissions\n"); 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; 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; 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) { ebitmap_for_each_positive_bit(&p->policycaps, node, i) {
capname = sepol_polcap_getname(i); capname = sepol_polcap_getname(i);
if (capname == NULL) { if (capname == NULL) {
snprintf(buf, sizeof(buf), "unknown (%d)", i); snprintf(buf, sizeof(buf), "unknown (%u)", i);
capname = buf; capname = buf;
} }
fprintf(fp, "\t%s\n", capname); fprintf(fp, "\t%s\n", capname);
@ -335,17 +335,25 @@ static int filenametr_display(hashtab_key_t key,
hashtab_datum_t datum, hashtab_datum_t datum,
void *ptr) 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 filename_trans_datum *ftdatum = datum;
struct filenametr_display_args *args = ptr; struct filenametr_display_args *args = ptr;
policydb_t *p = args->p; policydb_t *p = args->p;
FILE *fp = args->fp; FILE *fp = args->fp;
ebitmap_node_t *node;
uint32_t bit;
display_id(p, fp, SYM_TYPES, ft->stype - 1, ""); 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_TYPES, ft->ttype - 1, "");
display_id(p, fp, SYM_CLASSES, ft->tclass - 1, ":"); display_id(p, fp, SYM_CLASSES, ft->tclass - 1, ":");
display_id(p, fp, SYM_TYPES, ftdatum->otype - 1, ""); display_id(p, fp, SYM_TYPES, ftdatum->otype - 1, "");
fprintf(fp, " %s\n", ft->name); fprintf(fp, " %s\n", ft->name);
}
ftdatum = ftdatum->next;
} while (ftdatum);
return 0; return 0;
} }
@ -360,7 +368,7 @@ static void display_filename_trans(policydb_t *p, FILE *fp)
hashtab_map(p->filename_trans, filenametr_display, &args); hashtab_map(p->filename_trans, filenametr_display, &args);
} }
int menu(void) static int menu(void)
{ {
printf("\nSelect a command:\n"); printf("\nSelect a command:\n");
printf("1) display unconditional AVTAB\n"); printf("1) display unconditional AVTAB\n");

View file

@ -1 +1 @@
3.0 3.3-rc1

View file

@ -2,28 +2,36 @@
import dbus import dbus
import dbus.service import dbus.service
import dbus.mainloop.glib from dbus.mainloop.glib import DBusGMainLoop
from gi.repository import GObject from gi.repository import GObject
import slip.dbus.service from gi.repository import GLib
from slip.dbus import polkit
import os import os
import selinux import selinux
from subprocess import Popen, PIPE, STDOUT 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" default_polkit_auth_required = "org.selinux.semanage"
def __init__(self, *p, **k): def __init__(self, *p, **k):
super(selinux_server, self).__init__(*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, # The semanage method runs a transaction on a series of semanage commands,
# these commands can take the output of customized # these commands can take the output of customized
# #
@slip.dbus.polkit.require_auth("org.selinux.semanage") @dbus.service.method("org.selinux", in_signature='s', sender_keyword="sender")
@dbus.service.method("org.selinux", in_signature='s') def semanage(self, buf, sender):
def semanage(self, buf): 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 = Popen(["/usr/sbin/semanage", "import"], stdout=PIPE, stderr=PIPE, stdin=PIPE, universal_newlines=True)
p.stdin.write(buf) p.stdin.write(buf)
output = p.communicate() 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 # on the server. This output can be used with the semanage method on
# another server to make the two systems have duplicate policy. # 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', sender_keyword="sender")
@dbus.service.method("org.selinux", in_signature='', out_signature='s') def customized(self, sender):
def customized(self): 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) p = Popen(["/usr/sbin/semanage", "export"], stdout=PIPE, stderr=PIPE, universal_newlines=True)
buf = p.stdout.read() buf = p.stdout.read()
output = p.communicate() 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, # The semodule_list method will return the output of semodule --list=full, using the customized polkit,
# since this is a readonly behaviour # 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', sender_keyword="sender")
@dbus.service.method("org.selinux", in_signature='', out_signature='s') def semodule_list(self, sender):
def semodule_list(self): 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) p = Popen(["/usr/sbin/semodule", "--list=full"], stdout=PIPE, stderr=PIPE, universal_newlines=True)
buf = p.stdout.read() buf = p.stdout.read()
output = p.communicate() 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 # 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', sender_keyword="sender")
@dbus.service.method("org.selinux", in_signature='s') def restorecon(self, path, sender):
def restorecon(self, path): if not self.is_authorized(sender, "org.selinux.restorecon"):
raise dbus.exceptions.DBusException("Not authorized")
selinux.restorecon(str(path), recursive=1) selinux.restorecon(str(path), recursive=1)
# #
# The setenforce method turns off the current enforcement of SELinux # 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', sender_keyword="sender")
@dbus.service.method("org.selinux", in_signature='i') def setenforce(self, value, sender):
def setenforce(self, value): if not self.is_authorized(sender, "org.selinux.setenforce"):
raise dbus.exceptions.DBusException("Not authorized")
selinux.security_setenforce(value) selinux.security_setenforce(value)
# #
# The setenforce method turns off the current enforcement of SELinux # 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', sender_keyword="sender")
@dbus.service.method("org.selinux", in_signature='i') def relabel_on_boot(self, value, sender):
def relabel_on_boot(self, value): if not self.is_authorized(sender, "org.selinux.relabel_on_boot"):
raise dbus.exceptions.DBusException("Not authorized")
if value == 1: if value == 1:
fd = open("/.autorelabel", "w") fd = open("/.autorelabel", "w")
fd.close() fd.close()
@ -111,9 +124,10 @@ class selinux_server(slip.dbus.service.Object):
# #
# The change_default_enforcement modifies the current enforcement mode # 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', sender_keyword="sender")
@dbus.service.method("org.selinux", in_signature='s') def change_default_mode(self, value, sender):
def change_default_mode(self, value): if not self.is_authorized(sender, "org.selinux.change_default_mode"):
raise dbus.exceptions.DBusException("Not authorized")
values = ["enforcing", "permissive", "disabled"] values = ["enforcing", "permissive", "disabled"]
if value not in values: if value not in values:
raise ValueError("Enforcement mode must be %s" % ", ".join(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 # 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', sender_keyword="sender")
@dbus.service.method("org.selinux", in_signature='s') def change_default_policy(self, value, sender):
def change_default_policy(self, value): if not self.is_authorized(sender, "org.selinux.change_default_policy"):
raise dbus.exceptions.DBusException("Not authorized")
path = selinux.selinux_path() + value path = selinux.selinux_path() + value
if os.path.isdir(path): if os.path.isdir(path):
return self.write_selinux_config(policy=value) return self.write_selinux_config(policy=value)
raise ValueError("%s does not exist" % path) raise ValueError("%s does not exist" % path)
if __name__ == "__main__": if __name__ == "__main__":
mainloop = GObject.MainLoop() DBusGMainLoop(set_as_default=True)
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) mainloop = GLib.MainLoop()
system_bus = dbus.SystemBus() system_bus = dbus.SystemBus()
name = dbus.service.BusName("org.selinux", system_bus) name = dbus.service.BusName("org.selinux", system_bus)
object = selinux_server(system_bus, "/org/selinux/object") server = selinux_server(system_bus, "/org/selinux/object")
slip.dbus.service.set_mainloop(mainloop)
mainloop.run() mainloop.run()

View file

@ -1 +1 @@
3.0 3.3-rc1

View file

@ -102,6 +102,13 @@ class fcontextPage(semanagePage):
self.load() self.load()
self.fcontextEntry = xml.get_object("fcontextEntry") self.fcontextEntry = xml.get_object("fcontextEntry")
self.fcontextFileTypeCombo = xml.get_object("fcontextFileTypeCombo") 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.fcontextTypeEntry = xml.get_object("fcontextTypeEntry")
self.fcontextMLSEntry = xml.get_object("fcontextMLSEntry") self.fcontextMLSEntry = xml.get_object("fcontextMLSEntry")

View file

@ -401,32 +401,6 @@ Level</property>
<!-- column-name gchararray --> <!-- column-name gchararray -->
<column type="gchararray"/> <column type="gchararray"/>
</columns> </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>
<object class="GtkDialog" id="fcontextDialog"> <object class="GtkDialog" id="fcontextDialog">
<property name="can_focus">False</property> <property name="can_focus">False</property>

View file

@ -1,9 +1,10 @@
SUBDIRS = src include utils man SUBDIRS = include src utils man
PKG_CONFIG ?= pkg-config PKG_CONFIG ?= pkg-config
DISABLE_SETRANS ?= n DISABLE_SETRANS ?= n
DISABLE_RPM ?= n DISABLE_RPM ?= n
ANDROID_HOST ?= n ANDROID_HOST ?= n
LABEL_BACKEND_ANDROID ?= n
ifeq ($(ANDROID_HOST),y) ifeq ($(ANDROID_HOST),y)
override DISABLE_SETRANS=y override DISABLE_SETRANS=y
override DISABLE_BOOL=y override DISABLE_BOOL=y
@ -17,7 +18,10 @@ endif
ifeq ($(DISABLE_BOOL),y) ifeq ($(DISABLE_BOOL),y)
DISABLE_FLAGS+= -DDISABLE_BOOL DISABLE_FLAGS+= -DDISABLE_BOOL
endif 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 USE_PCRE2 ?= n
ifeq ($(USE_PCRE2),y) ifeq ($(USE_PCRE2),y)
@ -46,24 +50,24 @@ all install relabel clean distclean indent:
done done
swigify: all swigify: all
$(MAKE) -C src swigify $@ $(MAKE) -C src $@
pywrap: pywrap:
$(MAKE) -C src pywrap $@ $(MAKE) -C src $@
rubywrap: rubywrap:
$(MAKE) -C src rubywrap $@ $(MAKE) -C src $@
install-pywrap: install-pywrap:
$(MAKE) -C src install-pywrap $@ $(MAKE) -C src $@
install-rubywrap: install-rubywrap:
$(MAKE) -C src install-rubywrap $@ $(MAKE) -C src $@
clean-pywrap: clean-pywrap:
$(MAKE) -C src clean-pywrap $@ $(MAKE) -C src $@
clean-rubywrap: clean-rubywrap:
$(MAKE) -C src clean-rubywrap $@ $(MAKE) -C src $@
test: test:

View file

@ -1 +1 @@
3.0 3.3-rc1

View file

@ -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 * reference count). Note that avc_context_to_sid() also
* increments reference counts. * 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. * 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 * zero, the SID is invalid, and avc_context_to_sid() must
* be called to obtain a new SID for the security context. * 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 * 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_memory_callback *mem_callbacks,
const struct avc_log_callback *log_callbacks, const struct avc_log_callback *log_callbacks,
const struct avc_thread_callback *thread_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. * avc_open - Initialize the AVC.

View file

@ -17,14 +17,14 @@ extern "C" {
If 'fromcon' is NULL, defaults to current context. If 'fromcon' is NULL, defaults to current context.
Caller must free via freeconary. */ Caller must free via freeconary. */
extern int get_ordered_context_list(const char *user, extern int get_ordered_context_list(const char *user,
char * fromcon, const char *fromcon,
char *** list); char *** list);
/* As above, but use the provided MLS level rather than the /* As above, but use the provided MLS level rather than the
default level for the user. */ default level for the user. */
extern int get_ordered_context_list_with_level(const char *user, extern int get_ordered_context_list_with_level(const char *user,
const char *level, const char *level,
char * fromcon, const char *fromcon,
char *** list); char *** list);
/* Get the default security context for a user session for 'user' /* Get the default security context for a user session for 'user'
@ -35,14 +35,14 @@ extern "C" {
Returns 0 on success or -1 otherwise. Returns 0 on success or -1 otherwise.
Caller must free via freecon. */ Caller must free via freecon. */
extern int get_default_context(const char *user, extern int get_default_context(const char *user,
char * fromcon, const char *fromcon,
char ** newcon); char ** newcon);
/* As above, but use the provided MLS level rather than the /* As above, but use the provided MLS level rather than the
default level for the user. */ default level for the user. */
extern int get_default_context_with_level(const char *user, extern int get_default_context_with_level(const char *user,
const char *level, const char *level,
char * fromcon, const char *fromcon,
char ** newcon); char ** newcon);
/* Same as get_default_context, but only return a context /* 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. */ for the user with that role, then return -1. */
extern int get_default_context_with_role(const char *user, extern int get_default_context_with_role(const char *user,
const char *role, const char *role,
char * fromcon, const char *fromcon,
char ** newcon); char ** newcon);
/* Same as get_default_context, but only return a context /* 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, extern int get_default_context_with_rolelevel(const char *user,
const char *role, const char *role,
const char *level, const char *level,
char * fromcon, const char *fromcon,
char ** newcon); char ** newcon);
/* Given a list of authorized security contexts for the user, /* Given a list of authorized security contexts for the user,

View file

@ -30,77 +30,82 @@ extern int selinux_restorecon(const char *pathname,
* Force the checking of labels even if the stored SHA1 digest * Force the checking of labels even if the stored SHA1 digest
* matches the specfiles SHA1 digest (requires CAP_SYS_ADMIN). * 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. * 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 set, change file label to that in spec file.
* If not, only change type component 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. * Recursively descend directories.
*/ */
#define SELINUX_RESTORECON_RECURSE 0x0008 #define SELINUX_RESTORECON_RECURSE 0x00008
/* /*
* Log changes to selinux log. Note that if VERBOSE and * Log changes to selinux log. Note that if VERBOSE and
* PROGRESS are set, then PROGRESS will take precedence. * 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 * If SELINUX_RESTORECON_PROGRESS is true and
* SELINUX_RESTORECON_MASS_RELABEL is true, then output approx % complete, * SELINUX_RESTORECON_MASS_RELABEL is true, then output approx % complete,
* else output the number of files in 1k blocks processed to stdout. * 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. * 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 * Prevent descending into directories that have a different
* device number than the pathname from which the descent began. * 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. * Attempt to add an association between an inode and a specification.
* If there is already an association for the inode and it conflicts * If there is already an association for the inode and it conflicts
* with the specification, then use the last matching specification. * 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. * 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. * Log any label changes to syslog.
*/ */
#define SELINUX_RESTORECON_SYSLOG_CHANGES 0x0400 #define SELINUX_RESTORECON_SYSLOG_CHANGES 0x00400
/* /*
* Log what spec matched each file. * Log what spec matched each file.
*/ */
#define SELINUX_RESTORECON_LOG_MATCHES 0x0800 #define SELINUX_RESTORECON_LOG_MATCHES 0x00800
/* /*
* Ignore files that do not exist. * 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 * Do not read /proc/mounts to obtain a list of non-seclabel
* mounts to be excluded from relabeling checks. * 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. * Set if there is a mass relabel required.
* See SELINUX_RESTORECON_PROGRESS flag for details. * 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 * Set if no digest is to be read or written (as only processes
* running with CAP_SYS_ADMIN can read/write digests). * 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. * selinux_restorecon_set_sehandle - Set the global fc handle.

View file

@ -8,13 +8,17 @@
extern "C" { extern "C" {
#endif #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); extern int is_selinux_enabled(void);
/* Return 1 if we are running on a SELinux MLS kernel, or 0 otherwise. */ /* Return 1 if we are running on a SELinux MLS kernel, or 0 otherwise. */
extern int is_selinux_mls_enabled(void); extern int is_selinux_mls_enabled(void);
/* No longer used; here for compatibility with legacy callers. */ /* 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. */ /* Free the memory allocated for a context by any of the below get* calls. */
extern void freecon(char * con); 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_WARNING 1
#define SELINUX_INFO 2 #define SELINUX_INFO 2
#define SELINUX_AVC 3 #define SELINUX_AVC 3
#define SELINUX_POLICYLOAD 4
#define SELINUX_SETENFORCE 5
#define SELINUX_TRANS_DIR "/var/run/setrans" #define SELINUX_TRANS_DIR "/var/run/setrans"
/* Compute an access decision. */ /* Compute an access decision. */
@ -246,8 +252,12 @@ extern int security_compute_member_raw(const char * scon,
security_class_t tclass, security_class_t tclass,
char ** newcon); 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, extern int security_compute_user(const char * scon,
const char *username, const char *username,
char *** con); char *** con);
@ -319,9 +329,13 @@ extern int security_set_boolean_list(size_t boolcnt,
SELboolean * boollist, int permanent); SELboolean * boollist, int permanent);
/* Load policy boolean settings. Deprecated as local policy booleans no /* 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. */ /* Check the validity of a security context. */
extern int security_check_context(const char * con); 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 function also checks for a 'path'.homedirs file and
a 'path'.local file and loads additional specifications a 'path'.local file and loads additional specifications
from them if present. */ 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 /* Same as matchpathcon_init, but only load entries with
regexes that have stems that are prefixes of 'prefix'. */ regexes that have stems that are prefixes of 'prefix'. */
extern int matchpathcon_init_prefix(const char *path, const char *prefix); extern int matchpathcon_init_prefix(const char *path, const char *prefix);
/* Free the memory allocated by matchpathcon_init. */ /* 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 /* 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 * 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 If matchpathcon_init has not already been called, then this function
will call it upon its first invocation with a NULL path. */ will call it upon its first invocation with a NULL path. */
extern int matchpathcon(const char *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 /* Same as above, but return a specification index for
later use in a matchpathcon_filespec_add() call - see below. */ 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_securetty_types_path(void);
extern const char *selinux_booleans_subs_path(void); extern const char *selinux_booleans_subs_path(void);
/* Deprecated as local policy booleans no longer supported. */ /* 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); extern const char *selinux_customizable_types_path(void);
/* Deprecated as policy ./users no longer supported. */ /* 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_usersconf_path(void);
extern const char *selinux_translations_path(void); extern const char *selinux_translations_path(void);
extern const char *selinux_colors_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. /* Check a permission in the passwd class.
Return 0 if granted or -1 otherwise. */ Return 0 if granted or -1 otherwise. */
extern int selinux_check_passwd_access(access_vector_t requested); extern int selinux_check_passwd_access(access_vector_t requested)
extern int checkPasswdAccess(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 /* Check if the tty_context is defined as a securetty
Return 0 if secure, < 0 otherwise. */ 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. */ /* Execute a helper for rpm in an appropriate security context. */
extern int rpm_execcon(unsigned int verified, extern int rpm_execcon(unsigned int verified,
const char *filename, 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 #endif
/* Returns whether a file context is customizable, and should not /* Returns whether a file context is customizable, and should not

View file

@ -117,6 +117,8 @@ argument, which does not return under normal conditions. The
callback should cancel the running thread referenced by callback should cancel the running thread referenced by
.IR thread . .IR thread .
By default, threading is not used; see By default, threading is not used; see
.B KERNEL STATUS PAGE
and
.B NETLINK NOTIFICATION .B NETLINK NOTIFICATION
below. below.
@ -153,14 +155,49 @@ callback should destroy
.IR lock , .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. 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" .SH "KERNEL STATUS PAGE"
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 Linux kernel version 2.6.37 supports the SELinux kernel status page, enabling userspace applications to
.BR avc_has_perm (3) .BR mmap (2)
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. 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 () .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" .SH "RETURN VALUE"
Functions with a return value return zero on success. On error, \-1 is returned and 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" .SH "SEE ALSO"
.BR avc_open (3), .BR avc_open (3),
.BR selinux_status_open (3),
.BR selinux_status_updated (3),
.BR selinux_set_callback (3), .BR selinux_set_callback (3),
.BR selinux (8) .BR selinux (8)

View file

@ -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 returns the netlink socket descriptor number and informs the userspace AVC
not to check the socket descriptor automatically on calls to not to check the socket descriptor automatically on calls to
.BR avc_has_perm (3). .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 () .BR avc_netlink_release_fd ()
returns control of the netlink socket to the userspace AVC, re-enabling 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 .I errno
is set appropriately. is set appropriately.
. .
.SH "AUTHOR"
Originally KaiGai Kohei. Updated by Mike Palmiotto <mike.palmiotto@crunchydata.com>
.
.SH "SEE ALSO" .SH "SEE ALSO"
.BR avc_open (3), .BR avc_open (3),
.BR selinux_set_callback (3), .BR selinux_set_callback (3),

View file

@ -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, destroys the userspace AVC, freeing all internal memory structures. After this call has been made,
.BR avc_open () .BR avc_open ()
must be called again before any AVC operations can be performed. 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 () .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 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 .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. 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" .SH "KERNEL STATUS PAGE"
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 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) .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" .SH "RETURN VALUE"
Functions with a return value return zero on success. On error, \-1 is returned and 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" .SH "SEE ALSO"
.BR selinux (8), .BR selinux (8),
.BR selinux_check_access (3),
.BR avc_has_perm (3), .BR avc_has_perm (3),
.BR avc_context_to_sid (3), .BR avc_context_to_sid (3),
.BR avc_cache_stats (3), .BR avc_cache_stats (3),
.BR avc_add_callback (3), .BR avc_add_callback (3),
.BR selinux_status_open (3),
.BR selinux_status_updated (3),
.BR selinux_set_callback (3), .BR selinux_set_callback (3),
.BR security_compute_av (3) .BR security_compute_av (3)

View file

@ -7,17 +7,17 @@ get_ordered_context_list, get_ordered_context_list_with_level, get_default_conte
.br .br
.B #include <selinux/get_context_list.h> .B #include <selinux/get_context_list.h>
.sp .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 .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 .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 .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 .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 .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 .sp
.BI "int query_user_context(char **" list ", char **" newcon ); .BI "int query_user_context(char **" list ", char **" newcon );
.sp .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 ); .BI "int get_default_type(const char *" role ", char **" type );
. .
.SH "DESCRIPTION" .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 () .BR get_ordered_context_list ()
invokes the obtains the list of contexts for the specified
.BR security_compute_user (3) SELinux
function to obtain the list of contexts for the specified
.I user .I user
that are reachable from the specified identity that are reachable from the specified
.I fromcon .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 .I \%/etc/selinux/{SELINUXTYPE}/contexts/default_contexts
file and the per-user file and the per-user
.I \%/etc/selinux/{SELINUXTYPE}/contexts/users/<username> .I \%/etc/selinux/{SELINUXTYPE}/contexts/users/<username>

View file

@ -7,7 +7,7 @@ freecon, freeconary \- free memory associated with SELinux security contexts
getpeercon \- get security context of a peer socket getpeercon \- get security context of a peer socket
setcon \- set current security context of a process setcon \- set current security context of a process
.
.SH "SYNOPSIS" .SH "SYNOPSIS"
.B #include <selinux/selinux.h> .B #include <selinux/selinux.h>
.sp .sp
@ -31,30 +31,39 @@ setcon \- set current security context of a process
.sp .sp
.BI "void freeconary(char **" con ); .BI "void freeconary(char **" con );
.sp .sp
.BI "int setcon(char *" context ); .BI "int setcon(const char *" context );
.sp .sp
.BI "int setcon_raw(char *" context ); .BI "int setcon_raw(const char *" context );
.
.SH "DESCRIPTION" .SH "DESCRIPTION"
.TP
.BR getcon () .BR getcon ()
retrieves the context of the current process, which must be free'd with retrieves the context of the current process, which must be free'd with
freecon. .BR freecon ().
.TP
.BR getprevcon () .BR getprevcon ()
same as getcon but gets the context before the last exec. same as getcon but gets the context before the last exec.
.TP
.BR getpidcon () .BR getpidcon ()
returns the process context for the specified PID. returns the process context for the specified PID, which must be free'd with
.BR getpeercon ()
retrieves context of peer socket, and set
.BI * context
to refer to it, which must be free'd with
.BR freecon (). .BR freecon ().
.TP
.BR getpeercon ()
retrieves the context of the peer socket, which must be free'd with
.BR freecon ().
.TP
.BR freecon () .BR freecon ()
frees the memory allocated for a security context. frees the memory allocated for a security context.
If
.I con
is NULL, no operation is performed.
.TP
.BR freeconary () .BR freeconary ()
frees the memory allocated for a context array. frees the memory allocated for a context array.
@ -62,6 +71,7 @@ If
.I con .I con
is NULL, no operation is performed. is NULL, no operation is performed.
.TP
.BR setcon () .BR setcon ()
sets the current security context of the process to a new value. Note sets the current security context of the process to a new value. Note
that use of this function requires that the entire application be that use of this function requires that the entire application be
@ -110,6 +120,8 @@ context and the
.BR setcon () .BR setcon ()
will fail if it is not allowed by policy. will fail if it is not allowed by policy.
.TP
.BR *_raw()
.BR getcon_raw (), .BR getcon_raw (),
.BR getprevcon_raw (), .BR getprevcon_raw (),
.BR getpidcon_raw (), .BR getpidcon_raw (),
@ -118,9 +130,14 @@ and
.BR setcon_raw () .BR setcon_raw ()
behave identically to their non-raw counterparts but do not perform context behave identically to their non-raw counterparts but do not perform context
translation. translation.
.
.SH "RETURN VALUE" .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" .SH "SEE ALSO"
.BR selinux "(8), " setexeccon "(3)" .BR selinux "(8), " setexeccon "(3)"

View file

@ -15,7 +15,6 @@ is_selinux_mls_enabled \- check whether SELinux is enabled for (Multi Level Secu
.SH "DESCRIPTION" .SH "DESCRIPTION"
.BR is_selinux_enabled () .BR is_selinux_enabled ()
returns 1 if SELinux is running or 0 if it is not. returns 1 if SELinux is running or 0 if it is not.
On error, \-1 is returned.
.BR is_selinux_mls_enabled () .BR is_selinux_mls_enabled ()
returns 1 if SELinux is capable of running in MLS mode or 0 if it is not. To returns 1 if SELinux is capable of running in MLS mode or 0 if it is not. To

View file

@ -5,9 +5,9 @@ security_check_context \- check the validity of a SELinux context
.SH "SYNOPSIS" .SH "SYNOPSIS"
.B #include <selinux/selinux.h> .B #include <selinux/selinux.h>
.sp .sp
.BI "int security_check_context(char *" con ); .BI "int security_check_context(const char *" con );
.sp .sp
.BI "int security_check_context_raw(char *" con ); .BI "int security_check_context_raw(const char *" con );
. .
.SH "DESCRIPTION" .SH "DESCRIPTION"
.BR security_check_context () .BR security_check_context ()

View file

@ -134,8 +134,9 @@ instance.
.BR security_compute_user () .BR security_compute_user ()
is used to determine the set of user contexts that can be reached from a is used to determine the set of user contexts that can be reached from a
source context. It is mainly used by source context. This function is deprecated; use
.BR get_ordered_context_list (3). .BR get_ordered_context_list (3)
instead.
.BR security_validatetrans () .BR security_validatetrans ()
is used to determine if a transition from scon to newcon using tcon as the object is used to determine if a transition from scon to newcon using tcon as the object

View file

@ -152,6 +152,10 @@ Setting
.B SELINUX_RESTORECON_IGNORE_MOUNTS .B SELINUX_RESTORECON_IGNORE_MOUNTS
is useful where there is a non-seclabel fs mounted with a seclabel fs mounted is useful where there is a non-seclabel fs mounted with a seclabel fs mounted
on a directory below this. 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 .RE
.sp .sp
The behavior regarding the checking and updating of the SHA1 digest described The behavior regarding the checking and updating of the SHA1 digest described

View file

@ -46,6 +46,20 @@ argument indicates the type of message and will be set to one of the following:
.B SELINUX_INFO .B SELINUX_INFO
.B SELINUX_AVC .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 .TP
.B SELINUX_CB_AUDIT .B SELINUX_CB_AUDIT

View file

@ -48,7 +48,7 @@ Set 1 on the
argument to handle a case of older kernels without kernel status page support. 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 In this case, this function tries to open a netlink socket using
.BR avc_netlink_open (3) .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, Thus, we need to pay attention to the interaction with these interfaces,
when fallback mode is enabled. when fallback mode is enabled.
.sp .sp
@ -57,9 +57,14 @@ unmap the kernel status page and close its file descriptor, or close the
netlink socket if fallbacked. netlink socket if fallbacked.
.sp .sp
.BR selinux_status_updated () .BR selinux_status_updated ()
informs us whether something has been updated since the last call. processes status update events. There are two kinds of status updates.
It returns 0 if nothing was happened, however, 1 if something has been .B setenforce
updated in this duration, or \-1 on error. 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 .sp
.BR selinux_status_getenforce () .BR selinux_status_getenforce ()
returns 0 if SELinux is running in permissive mode, 1 if enforcing mode, returns 0 if SELinux is running in permissive mode, 1 if enforcing mode,

View file

@ -125,7 +125,14 @@ Where:
.RS .RS
.I pathname .I pathname
.RS .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 .RE
.I file_type .I file_type
.RS .RS

View file

@ -19,18 +19,36 @@ enabled or disabled, and if enabled, whether SELinux operates in
permissive mode or enforcing mode. The permissive mode or enforcing mode. The
.B SELINUX .B SELINUX
variable may be set to variable may be set to
any one of disabled, permissive, or enforcing to select one of these any one of \fIdisabled\fR, \fIpermissive\fR, or \fIenforcing\fR to
options. The disabled option completely disables the SELinux kernel select one of these options. The \fIdisabled\fR disables most of the
and application code, leaving the system running without any SELinux SELinux kernel and application code, leaving the system
protection. The permissive option enables the SELinux code, but running without any SELinux protection. The \fIpermissive\fR option
causes it to operate in a mode where accesses that would be denied by enables the SELinux code, but causes it to operate in a mode where
policy are permitted but audited. The enforcing option enables the accesses that would be denied by policy are permitted but audited. The
SELinux code and causes it to enforce access denials as well as \fIenforcing\fR option enables the SELinux code and causes it to enforce
auditing them. Permissive mode may yield a different set of denials access denials as well as auditing them. \fIpermissive\fR mode may
than enforcing mode, both because enforcing mode will prevent an yield a different set of denials than enforcing mode, both because
operation from proceeding past the first denial and because some enforcing mode will prevent an operation from proceeding past the first
application code will fall back to a less privileged mode of operation denial and because some application code will fall back to a less
if denied access. 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 The
.I /etc/selinux/config .I /etc/selinux/config
@ -76,6 +94,13 @@ and reboot.
also has this capability. The also has this capability. The
.BR restorecon / fixfiles .BR restorecon / fixfiles
commands are also available for relabeling files. 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 .SH AUTHOR
This manual page was written by Dan Walsh <dwalsh@redhat.com>. This manual page was written by Dan Walsh <dwalsh@redhat.com>.

View file

@ -1,6 +1,6 @@
.TH "failsafe_context" "5" "28 ноября 2011" "Security Enhanced Linux" "Конфигурация SELinux" .TH "failsafe_context" "5" "28 ноября 2011" "Security Enhanced Linux" "Конфигурация SELinux"
.SH "ИМЯ" .SH "ИМЯ"
failsafe_context \- файл конфигурации надёжного контекста SELinux failsafe_context \- файл конфигурации резервного контекста SELinux
. .
.SH "ОПИСАНИЕ" .SH "ОПИСАНИЕ"
Файл Файл
@ -10,7 +10,7 @@ failsafe_context \- файл конфигурации надёжного кон
получать известный действительный контекст входа для администратора, если в других расположениях отсутствуют действительные записи по умолчанию. получать известный действительный контекст входа для администратора, если в других расположениях отсутствуют действительные записи по умолчанию.
.sp .sp
.BR selinux_failsafe_context_path "(3) " .BR selinux_failsafe_context_path "(3) "
возвращает путь активной политики к этому файлу. Файл надёжного контекста по умолчанию: возвращает путь активной политики к этому файлу. Файл резервного контекста по умолчанию:
.RS .RS
.I /etc/selinux/{SELINUXTYPE}/contexts/failsafe_context .I /etc/selinux/{SELINUXTYPE}/contexts/failsafe_context
.RE .RE

View file

@ -15,7 +15,7 @@ INCLUDEDIR ?= $(PREFIX)/include
PYINC ?= $(shell $(PKG_CONFIG) --cflags $(PYPREFIX)) PYINC ?= $(shell $(PKG_CONFIG) --cflags $(PYPREFIX))
PYLIBS ?= $(shell $(PKG_CONFIG) --libs $(PYPREFIX)) PYLIBS ?= $(shell $(PKG_CONFIG) --libs $(PYPREFIX))
PYTHONLIBDIR ?= $(shell $(PYTHON) -c "from distutils.sysconfig import *; print(get_python_lib(plat_specific=1, prefix='$(PREFIX)'))") 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"]') 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"]') 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"]') 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 \ -Wcoverage-mismatch -Wcpp -Wformat-contains-nul -Wnormalized=nfc -Wsuggest-attribute=const \
-Wsuggest-attribute=noreturn -Wsuggest-attribute=pure -Wtrampolines -Wjump-misses-init \ -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 \ -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 else
EXTRA_CFLAGS = -Wunused-command-line-argument EXTRA_CFLAGS = -Wunused-command-line-argument
endif endif
@ -90,7 +90,7 @@ CFLAGS ?= -O -Wall -W -Wundef -Wformat-y2k -Wformat-security -Winit-self -Wmissi
-Werror -Wno-aggregate-return -Wno-redundant-decls \ -Werror -Wno-aggregate-return -Wno-redundant-decls \
$(EXTRA_CFLAGS) $(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) ifeq ($(OS), Darwin)
override CFLAGS += -I/opt/local/include override CFLAGS += -I/opt/local/include
@ -105,7 +105,8 @@ FTS_LDLIBS ?=
override CFLAGS += -I../include -D_GNU_SOURCE $(DISABLE_FLAGS) $(PCRE_CFLAGS) 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 \ 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 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 \ label_backends_android.c regex.c label_support.c \
matchpathcon.c setrans_client.c sha1.c booleans.c matchpathcon.c setrans_client.c sha1.c booleans.c
else else
DISABLE_FLAGS+= -DNO_ANDROID_BACKEND LABEL_BACKEND_ANDROID=y
endif
ifneq ($(LABEL_BACKEND_ANDROIDT),y)
SRCS:= $(filter-out label_backends_android.c, $(SRCS)) 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 endif
SWIGRUBY = swig -Wall -ruby -o $(SWIGRUBYCOUT) -outdir ./ $(DISABLE_FLAGS) SWIGRUBY = swig -Wall -ruby -o $(SWIGRUBYCOUT) -outdir ./ $(DISABLE_FLAGS)
@ -173,7 +182,7 @@ install: all
ln -sf --relative $(DESTDIR)$(SHLIBDIR)/$(LIBSO) $(DESTDIR)$(LIBDIR)/$(TARGET) ln -sf --relative $(DESTDIR)$(SHLIBDIR)/$(LIBSO) $(DESTDIR)$(LIBDIR)/$(TARGET)
install-pywrap: pywrap 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 install -m 644 $(SWIGPYOUT) $(DESTDIR)$(PYTHONLIBDIR)/selinux/__init__.py
ln -sf --relative $(DESTDIR)$(PYTHONLIBDIR)/selinux/_selinux$(PYCEXT) $(DESTDIR)$(PYTHONLIBDIR)/_selinux$(PYCEXT) ln -sf --relative $(DESTDIR)$(PYTHONLIBDIR)/selinux/_selinux$(PYCEXT) $(DESTDIR)$(PYTHONLIBDIR)/_selinux$(PYCEXT)

View file

@ -204,8 +204,8 @@ static int __policy_init(const char *init_path)
fp = fopen(path, "re"); fp = fopen(path, "re");
if (!fp) { if (!fp) {
snprintf(errormsg, sizeof(errormsg), snprintf(errormsg, sizeof(errormsg),
"unable to open %s: %s\n", "unable to open %s: %m\n",
path, strerror(errno)); path);
PyErr_SetString( PyExc_ValueError, errormsg); PyErr_SetString( PyExc_ValueError, errormsg);
return 1; return 1;
} }
@ -221,9 +221,8 @@ static int __policy_init(const char *init_path)
fp = fopen(curpolicy, "re"); fp = fopen(curpolicy, "re");
if (!fp) { if (!fp) {
snprintf(errormsg, sizeof(errormsg), snprintf(errormsg, sizeof(errormsg),
"unable to open %s: %s\n", "unable to open %s: %m\n",
curpolicy, curpolicy);
strerror(errno));
PyErr_SetString( PyExc_ValueError, errormsg); PyErr_SetString( PyExc_ValueError, errormsg);
return 1; return 1;
} }
@ -242,7 +241,7 @@ static int __policy_init(const char *init_path)
if (sepol_policy_file_create(&pf) || if (sepol_policy_file_create(&pf) ||
sepol_policydb_create(&avc->policydb)) { sepol_policydb_create(&avc->policydb)) {
snprintf(errormsg, sizeof(errormsg), snprintf(errormsg, sizeof(errormsg),
"policydb_init failed: %s\n", strerror(errno)); "policydb_init failed: %m\n");
PyErr_SetString( PyExc_RuntimeError, errormsg); PyErr_SetString( PyExc_RuntimeError, errormsg);
fclose(fp); fclose(fp);
return 1; return 1;
@ -275,7 +274,7 @@ static int __policy_init(const char *init_path)
} }
sepol_bool_iterate(avc->handle, avc->policydb, 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 /* Initialize the sidtab for subsequent use by sepol_context_to_sid
and sepol_compute_av_reason. */ and sepol_compute_av_reason. */

View file

@ -50,7 +50,6 @@ struct avc_callback_node {
struct avc_callback_node *next; struct avc_callback_node *next;
}; };
static void *avc_netlink_thread = NULL;
static void *avc_lock = NULL; static void *avc_lock = NULL;
static void *avc_log_lock = NULL; static void *avc_log_lock = NULL;
static struct avc_node *avc_node_freelist = 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; return rc;
} }
int avc_open(struct selinux_opt *opts, unsigned nopts) static int avc_init_internal(const char *prefix,
{
avc_setenforce = 0;
while (nopts--)
switch(opts[nopts].type) {
case AVC_OPT_SETENFORCE:
avc_setenforce = 1;
avc_enforcing = !!opts[nopts].value;
break;
}
return avc_init("avc", NULL, NULL, NULL, NULL);
}
int avc_init(const char *prefix,
const struct avc_memory_callback *mem_cb, const struct avc_memory_callback *mem_cb,
const struct avc_log_callback *log_cb, const struct avc_log_callback *log_cb,
const struct avc_thread_callback *thread_cb, const struct avc_thread_callback *thread_cb,
@ -222,30 +206,49 @@ int avc_init(const char *prefix,
rc = security_getenforce(); rc = security_getenforce();
if (rc < 0) { if (rc < 0) {
avc_log(SELINUX_ERROR, avc_log(SELINUX_ERROR,
"%s: could not determine enforcing mode: %s\n", "%s: could not determine enforcing mode: %m\n",
avc_prefix, avc_prefix);
strerror(errno));
goto out; goto out;
} }
avc_enforcing = rc; avc_enforcing = rc;
} }
rc = avc_netlink_open(0); rc = selinux_status_open(0);
if (rc < 0) { if (rc < 0) {
avc_log(SELINUX_ERROR, avc_log(SELINUX_ERROR,
"%s: can't open netlink socket: %d (%s)\n", "%s: could not open selinux status page: %d (%m)\n",
avc_prefix, errno, strerror(errno)); avc_prefix, errno);
goto out; goto out;
} }
if (avc_using_threads) {
avc_netlink_thread = avc_create_thread(&avc_netlink_loop);
avc_netlink_trouble = 0;
}
avc_running = 1; avc_running = 1;
out: out:
return rc; 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) void avc_cache_stats(struct avc_cache_stats *p)
{ {
memcpy(p, &cache_stats, sizeof(cache_stats)); memcpy(p, &cache_stats, sizeof(cache_stats));
@ -294,7 +297,6 @@ void avc_av_stats(void)
slots_used, AVC_CACHE_SLOTS, max_chain_len); slots_used, AVC_CACHE_SLOTS, max_chain_len);
} }
hidden_def(avc_av_stats)
static inline struct avc_node *avc_reclaim_node(void) 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) int avc_reset(void)
{ {
@ -539,7 +540,6 @@ int avc_reset(void)
return rc; return rc;
} }
hidden_def(avc_reset)
void avc_destroy(void) void avc_destroy(void)
{ {
@ -551,9 +551,7 @@ void avc_destroy(void)
avc_get_lock(avc_lock); avc_get_lock(avc_lock);
if (avc_using_threads) selinux_status_close();
avc_stop_thread(avc_netlink_thread);
avc_netlink_close();
for (i = 0; i < AVC_CACHE_SLOTS; i++) { for (i = 0; i < AVC_CACHE_SLOTS; i++) {
node = 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); avc_release_lock(avc_log_lock);
} }
hidden_def(avc_audit)
static void avd_init(struct av_decision *avd) static void avd_init(struct av_decision *avd)
@ -761,7 +758,7 @@ int avc_has_perm_noaudit(security_id_t ssid,
avd_init(avd); avd_init(avd);
if (!avc_using_threads && !avc_app_main_loop) { if (!avc_using_threads && !avc_app_main_loop) {
(void)avc_netlink_check_nb(); (void) selinux_status_updated();
} }
if (!aeref) { if (!aeref) {
@ -825,7 +822,6 @@ int avc_has_perm_noaudit(security_id_t ssid,
return rc; return rc;
} }
hidden_def(avc_has_perm_noaudit)
int avc_has_perm(security_id_t ssid, security_id_t tsid, int avc_has_perm(security_id_t ssid, security_id_t tsid,
security_class_t tclass, access_vector_t requested, security_class_t tclass, access_vector_t requested,

View file

@ -53,6 +53,49 @@ int avc_enforcing = 1;
int avc_setenforce = 0; int avc_setenforce = 0;
int avc_netlink_trouble = 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 */ /* netlink socket code */
static int fd = -1; static int fd = -1;
@ -177,20 +220,7 @@ static int avc_netlink_process(void *buf)
case SELNL_MSG_SETENFORCE:{ case SELNL_MSG_SETENFORCE:{
struct selnl_msg_setenforce *msg = NLMSG_DATA(nlh); struct selnl_msg_setenforce *msg = NLMSG_DATA(nlh);
msg->val = !!msg->val; rc = avc_process_setenforce(!!msg->val);
avc_log(SELINUX_INFO,
"%s: received setenforce notice (enforcing=%d)\n",
avc_prefix, msg->val);
if (avc_setenforce)
break;
avc_enforcing = msg->val;
if (avc_enforcing && (rc = avc_ss_reset(0)) < 0) {
avc_log(SELINUX_ERROR,
"%s: cache reset returned %d (errno %d)\n",
avc_prefix, rc, errno);
return rc;
}
rc = selinux_netlink_setenforce(msg->val);
if (rc < 0) if (rc < 0)
return rc; return rc;
break; break;
@ -198,18 +228,7 @@ static int avc_netlink_process(void *buf)
case SELNL_MSG_POLICYLOAD:{ case SELNL_MSG_POLICYLOAD:{
struct selnl_msg_policyload *msg = NLMSG_DATA(nlh); struct selnl_msg_policyload *msg = NLMSG_DATA(nlh);
avc_log(SELINUX_INFO, rc = avc_process_policyload(msg->seqno);
"%s: received policyload notice (seqno=%u)\n",
avc_prefix, msg->seqno);
rc = avc_ss_reset(msg->seqno);
if (rc < 0) {
avc_log(SELINUX_ERROR,
"%s: cache reset returned %d (errno %d)\n",
avc_prefix, rc, errno);
return rc;
}
selinux_flush_class_cache();
rc = selinux_netlink_policyload(msg->seqno);
if (rc < 0) if (rc < 0)
return rc; return rc;
break; break;
@ -284,6 +303,17 @@ void avc_netlink_loop(void)
int avc_netlink_acquire_fd(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; avc_app_main_loop = 1;
return fd; return fd;

View file

@ -14,24 +14,27 @@
#include <string.h> #include <string.h>
#include <selinux/avc.h> #include <selinux/avc.h>
#include "callbacks.h" #include "callbacks.h"
#include "dso.h"
/* callback pointers */ /* callback pointers */
extern void *(*avc_func_malloc) (size_t) hidden; extern void *(*avc_func_malloc) (size_t) ;
extern void (*avc_func_free) (void *)hidden; extern void (*avc_func_free) (void *);
extern void (*avc_func_log) (const char *, ...) __attribute__((__format__(printf,1,2))) 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)hidden; extern void (*avc_func_audit) (void *, security_class_t, char *, size_t);
extern int avc_using_threads hidden; extern int avc_using_threads ;
extern int avc_app_main_loop hidden; extern int avc_app_main_loop ;
extern void *(*avc_func_create_thread) (void (*)(void))hidden; extern void *(*avc_func_create_thread) (void (*)(void));
extern void (*avc_func_stop_thread) (void *)hidden; extern void (*avc_func_stop_thread) (void *);
extern void *(*avc_func_alloc_lock) (void)hidden; extern void *(*avc_func_alloc_lock) (void);
extern void (*avc_func_get_lock) (void *)hidden; extern void (*avc_func_get_lock) (void *);
extern void (*avc_func_release_lock) (void *)hidden; extern void (*avc_func_release_lock) (void *);
extern void (*avc_func_free_lock) (void *)hidden; 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, static inline void set_callbacks(const struct avc_memory_callback *mem_cb,
const struct avc_log_callback *log_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*/ /* message prefix and enforcing mode*/
#define AVC_PREFIX_SIZE 16 #define AVC_PREFIX_SIZE 16
extern char avc_prefix[AVC_PREFIX_SIZE] hidden; extern char avc_prefix[AVC_PREFIX_SIZE] ;
extern int avc_running hidden; extern int avc_running ;
extern int avc_enforcing hidden; extern int avc_enforcing ;
extern int avc_setenforce hidden; extern int avc_setenforce ;
/* user-supplied callback interface for avc */ /* user-supplied callback interface for avc */
static inline void *avc_malloc(size_t size) 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. */ /* this is a macro in order to use the variadic capability. */
#define avc_log(type, format...) \ #define avc_log(type, format...) \
do { \
if (avc_func_log) \ if (avc_func_log) \
avc_func_log(format); \ avc_func_log(format); \
else \ else \
selinux_log(type, format); selinux_log(type, format); \
} while (0)
static inline void avc_suppl_audit(void *ptr, security_class_t class, static inline void avc_suppl_audit(void *ptr, security_class_t class,
char *buf, size_t len) char *buf, size_t len)
@ -134,14 +139,18 @@ static inline void avc_free_lock(void *lock)
#ifdef AVC_CACHE_STATS #ifdef AVC_CACHE_STATS
#define avc_cache_stats_incr(field) \ #define avc_cache_stats_incr(field) \
cache_stats.field ++; do { \
cache_stats.field ++; \
} while (0)
#define avc_cache_stats_add(field, num) \ #define avc_cache_stats_add(field, num) \
cache_stats.field += num; do { \
cache_stats.field += num; \
} while (0)
#else #else
#define avc_cache_stats_incr(field) #define avc_cache_stats_incr(field) do {} while (0)
#define avc_cache_stats_add(field, num) #define avc_cache_stats_add(field, num) do {} while (0)
#endif #endif
@ -155,28 +164,23 @@ static inline void avc_free_lock(void *lock)
/* internal callbacks */ /* internal callbacks */
int avc_ss_grant(security_id_t ssid, security_id_t tsid, int avc_ss_grant(security_id_t ssid, security_id_t tsid,
security_class_t tclass, access_vector_t perms, 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, int avc_ss_try_revoke(security_id_t ssid, security_id_t tsid,
security_class_t tclass, security_class_t tclass,
access_vector_t perms, uint32_t seqno, 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, int avc_ss_revoke(security_id_t ssid, security_id_t tsid,
security_class_t tclass, access_vector_t perms, security_class_t tclass, access_vector_t perms,
uint32_t seqno) hidden; uint32_t seqno) ;
int avc_ss_reset(uint32_t seqno) hidden; int avc_ss_reset(uint32_t seqno) ;
int avc_ss_set_auditallow(security_id_t ssid, security_id_t tsid, int avc_ss_set_auditallow(security_id_t ssid, security_id_t tsid,
security_class_t tclass, access_vector_t perms, 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, int avc_ss_set_auditdeny(security_id_t ssid, security_id_t tsid,
security_class_t tclass, access_vector_t perms, 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 */ /* 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_ */ #endif /* _SELINUX_AVC_INTERNAL_H_ */

View file

@ -15,14 +15,13 @@
static inline unsigned sidtab_hash(const char * key) static inline unsigned sidtab_hash(const char * key)
{ {
char *p, *keyp; const char *p;
unsigned int size; unsigned int size;
unsigned int val; unsigned int val;
val = 0; val = 0;
keyp = (char *)key; size = strlen(key);
size = strlen(keyp); for (p = key; (unsigned int)(p - key) < size; p++)
for (p = keyp; (unsigned int)(p - keyp) < size; p++)
val = val =
(val << 4 | (val >> (8 * sizeof(unsigned int) - 4))) ^ (*p); (val << 4 | (val >> (8 * sizeof(unsigned int) - 4))) ^ (*p);
return val & (SIDTAB_SIZE - 1); return val & (SIDTAB_SIZE - 1);
@ -57,7 +56,7 @@ int sidtab_insert(struct sidtab *s, const char * ctx)
rc = -1; rc = -1;
goto out; goto out;
} }
newctx = (char *) strdup(ctx); newctx = strdup(ctx);
if (!newctx) { if (!newctx) {
rc = -1; rc = -1;
avc_free(newnode); avc_free(newnode);
@ -101,7 +100,7 @@ sidtab_context_to_sid(struct sidtab *s,
return rc; 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; int i, chain_len, slots_used, max_chain_len;
struct sidtab_node *cur; struct sidtab_node *cur;
@ -109,7 +108,7 @@ void sidtab_sid_stats(struct sidtab *h, char *buf, int buflen)
slots_used = 0; slots_used = 0;
max_chain_len = 0; max_chain_len = 0;
for (i = 0; i < SIDTAB_SIZE; i++) { for (i = 0; i < SIDTAB_SIZE; i++) {
cur = h->htable[i]; cur = s->htable[i];
if (cur) { if (cur) {
slots_used++; slots_used++;
chain_len = 0; chain_len = 0;
@ -125,7 +124,7 @@ void sidtab_sid_stats(struct sidtab *h, char *buf, int buflen)
snprintf(buf, buflen, snprintf(buf, buflen,
"%s: %u SID entries and %d/%d buckets used, longest " "%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); SIDTAB_SIZE, max_chain_len);
} }

View file

@ -7,7 +7,6 @@
#include <selinux/selinux.h> #include <selinux/selinux.h>
#include <selinux/avc.h> #include <selinux/avc.h>
#include "dso.h"
struct sidtab_node { struct sidtab_node {
struct security_id sid_s; struct security_id sid_s;
@ -24,13 +23,13 @@ struct sidtab {
unsigned nel; unsigned nel;
}; };
int sidtab_init(struct sidtab *s) hidden; int sidtab_init(struct sidtab *s) ;
int sidtab_insert(struct sidtab *s, const char * ctx) hidden; int sidtab_insert(struct sidtab *s, const char * ctx) ;
int sidtab_context_to_sid(struct sidtab *s, 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_sid_stats(struct sidtab *s, char *buf, int buflen) ;
void sidtab_destroy(struct sidtab *s) hidden; void sidtab_destroy(struct sidtab *s) ;
#endif /* _SELINUX_AVC_SIDTAB_H_ */ #endif /* _SELINUX_AVC_SIDTAB_H_ */

View file

@ -414,8 +414,3 @@ char *selinux_boolean_sub(const char *name __attribute__((unused)))
} }
#endif #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)

View file

@ -9,22 +9,21 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <selinux/selinux.h> #include <selinux/selinux.h>
#include "dso.h"
/* callback pointers */ /* callback pointers */
extern int __attribute__ ((format(printf, 2, 3))) extern int __attribute__ ((format(printf, 2, 3)))
(*selinux_log) (int type, const char *, ...) hidden; (*selinux_log) (int type, const char *, ...) ;
extern int extern int
(*selinux_audit) (void *, security_class_t, char *, size_t) hidden; (*selinux_audit) (void *, security_class_t, char *, size_t) ;
extern int extern int
(*selinux_validate)(char **ctx) hidden; (*selinux_validate)(char **ctx) ;
extern int extern int
(*selinux_netlink_setenforce) (int enforcing) hidden; (*selinux_netlink_setenforce) (int enforcing) ;
extern int extern int
(*selinux_netlink_policyload) (int seqno) hidden; (*selinux_netlink_policyload) (int seqno) ;
#endif /* _SELINUX_CALLBACKS_H_ */ #endif /* _SELINUX_CALLBACKS_H_ */

View file

@ -60,7 +60,6 @@ int security_canonicalize_context_raw(const char * con,
return ret; return ret;
} }
hidden_def(security_canonicalize_context_raw)
int security_canonicalize_context(const char * con, int security_canonicalize_context(const char * con,
char ** canoncon) char ** canoncon)
@ -83,4 +82,3 @@ int security_canonicalize_context(const char * con,
return ret; return ret;
} }
hidden_def(security_canonicalize_context)

View file

@ -39,7 +39,7 @@ int selinux_check_access(const char *scon, const char *tcon, const char *class,
if (rc < 0) if (rc < 0)
return rc; return rc;
(void) avc_netlink_check_nb(); (void) selinux_status_updated();
sclass = string_to_security_class(class); sclass = string_to_security_class(class);
if (sclass == 0) { 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); 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; int status = -1;
char *user_context; char *user_context;
@ -78,7 +78,9 @@ int selinux_check_passwd_access(access_vector_t requested)
passwd_class = string_to_security_class("passwd"); passwd_class = string_to_security_class("passwd");
if (passwd_class == 0) { if (passwd_class == 0) {
freecon(user_context); freecon(user_context);
if (security_deny_unknown() == 0)
return 0; return 0;
return -1;
} }
retval = security_compute_av_raw(user_context, retval = security_compute_av_raw(user_context,
@ -99,9 +101,11 @@ int selinux_check_passwd_access(access_vector_t requested)
return status; 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) int checkPasswdAccess(access_vector_t requested)
{ {
return selinux_check_passwd_access(requested); return selinux_check_passwd_access_internal(requested);
} }

View file

@ -31,7 +31,6 @@ int security_check_context_raw(const char * con)
return 0; return 0;
} }
hidden_def(security_check_context_raw)
int security_check_context(const char * con) int security_check_context(const char * con)
{ {
@ -48,4 +47,3 @@ int security_check_context(const char * con)
return ret; return ret;
} }
hidden_def(security_check_context)

View file

@ -37,4 +37,3 @@ int security_get_checkreqprot(void)
return checkreqprot; return checkreqprot;
} }
hidden_def(security_get_checkreqprot);

View file

@ -80,7 +80,6 @@ int security_compute_av_flags_raw(const char * scon,
return ret; return ret;
} }
hidden_def(security_compute_av_flags_raw)
int security_compute_av_raw(const char * scon, int security_compute_av_raw(const char * scon,
const char * tcon, const char * tcon,
@ -107,7 +106,6 @@ int security_compute_av_raw(const char * scon,
return ret; return ret;
} }
hidden_def(security_compute_av_raw)
int security_compute_av_flags(const char * scon, int security_compute_av_flags(const char * scon,
const char * tcon, const char * tcon,
@ -134,7 +132,6 @@ int security_compute_av_flags(const char * scon,
return ret; return ret;
} }
hidden_def(security_compute_av_flags)
int security_compute_av(const char * scon, int security_compute_av(const char * scon,
const char * tcon, const char * tcon,
@ -162,4 +159,3 @@ int security_compute_av(const char * scon,
return ret; return ret;
} }
hidden_def(security_compute_av)

View file

@ -105,7 +105,6 @@ int security_compute_create_name_raw(const char * scon,
close(fd); close(fd);
return ret; return ret;
} }
hidden_def(security_compute_create_name_raw)
int security_compute_create_raw(const char * scon, int security_compute_create_raw(const char * scon,
const char * tcon, const char * tcon,
@ -115,7 +114,6 @@ int security_compute_create_raw(const char * scon,
return security_compute_create_name_raw(scon, tcon, tclass, return security_compute_create_name_raw(scon, tcon, tclass,
NULL, newcon); NULL, newcon);
} }
hidden_def(security_compute_create_raw)
int security_compute_create_name(const char * scon, int security_compute_create_name(const char * scon,
const char * tcon, const char * tcon,
@ -146,7 +144,6 @@ int security_compute_create_name(const char * scon,
return ret; return ret;
} }
hidden_def(security_compute_create_name)
int security_compute_create(const char * scon, int security_compute_create(const char * scon,
const char * tcon, const char * tcon,
@ -155,4 +152,3 @@ int security_compute_create(const char * scon,
{ {
return security_compute_create_name(scon, tcon, tclass, NULL, newcon); return security_compute_create_name(scon, tcon, tclass, NULL, newcon);
} }
hidden_def(security_compute_create)

View file

@ -60,7 +60,6 @@ int security_compute_member_raw(const char * scon,
return ret; return ret;
} }
hidden_def(security_compute_member_raw)
int security_compute_member(const char * scon, int security_compute_member(const char * scon,
const char * tcon, const char * tcon,

View file

@ -60,7 +60,6 @@ int security_compute_relabel_raw(const char * scon,
return ret; return ret;
} }
hidden_def(security_compute_relabel_raw)
int security_compute_relabel(const char * scon, int security_compute_relabel(const char * scon,
const char * tcon, const char * tcon,

View file

@ -8,6 +8,7 @@
#include "selinux_internal.h" #include "selinux_internal.h"
#include "policy.h" #include "policy.h"
#include <limits.h> #include <limits.h>
#include "callbacks.h"
int security_compute_user_raw(const char * scon, int security_compute_user_raw(const char * scon,
const char *user, char *** con) const char *user, char *** con)
@ -24,6 +25,8 @@ int security_compute_user_raw(const char * scon,
return -1; 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); snprintf(path, sizeof path, "%s/user", selinux_mnt);
fd = open(path, O_RDWR | O_CLOEXEC); fd = open(path, O_RDWR | O_CLOEXEC);
if (fd < 0) if (fd < 0)
@ -77,7 +80,6 @@ int security_compute_user_raw(const char * scon,
return ret; return ret;
} }
hidden_def(security_compute_user_raw)
int security_compute_user(const char * scon, int security_compute_user(const char * scon,
const char *user, char *** con) const char *user, char *** con)
@ -107,4 +109,3 @@ int security_compute_user(const char * scon,
return ret; return ret;
} }
hidden_def(security_compute_user)

View file

@ -37,7 +37,7 @@ context_t context_new(const char *str)
} }
n->current_str = n->component[0] = n->component[1] = n->component[2] = n->current_str = n->component[0] = n->component[1] = n->component[2] =
n->component[3] = 0; n->component[3] = 0;
for (i = count = 0, p = str; *p; p++) { for (count = 0, p = str; *p; p++) {
switch (*p) { switch (*p) {
case ':': case ':':
count++; count++;
@ -82,7 +82,6 @@ context_t context_new(const char *str)
return 0; return 0;
} }
hidden_def(context_new)
static void conditional_free(char **v) 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. * Return a pointer to the string value of the context.
@ -144,7 +142,6 @@ char *context_str(context_t context)
return n->current_str; return n->current_str;
} }
hidden_def(context_str)
/* Returns nonzero iff failed */ /* Returns nonzero iff failed */
static int set_comp(context_private_t * n, int idx, const char *str) 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) { if (str) {
t = (char *)malloc(strlen(str) + 1); t = (char *)malloc(strlen(str) + 1);
if (!t) { if (!t) {
return 1; return -1;
} }
for (p = str; *p; p++) { for (p = str; *p; p++) {
if (*p == '\t' || *p == '\n' || *p == '\r' || if (*p == '\t' || *p == '\n' || *p == '\r' ||
((*p == ':' || *p == ' ') && idx != COMP_RANGE)) { ((*p == ':' || *p == ' ') && idx != COMP_RANGE)) {
free(t); free(t);
errno = EINVAL; errno = EINVAL;
return 1; return -1;
} }
} }
strcpy(t, str); strcpy(t, str);
@ -176,8 +173,7 @@ const char * context_ ## name ## _get(context_t context) \
{ \ { \
context_private_t *n = context->ptr; \ context_private_t *n = context->ptr; \
return n->component[tag]; \ return n->component[tag]; \
} \ }
hidden_def(context_ ## name ## _get)
def_get(type, COMP_TYPE) def_get(type, COMP_TYPE)
def_get(user, COMP_USER) def_get(user, COMP_USER)
@ -187,8 +183,7 @@ def_get(type, COMP_TYPE)
int context_ ## name ## _set(context_t context, const char* str) \ int context_ ## name ## _set(context_t context, const char* str) \
{ \ { \
return set_comp(context->ptr,tag,str);\ return set_comp(context->ptr,tag,str);\
} \ }
hidden_def(context_ ## name ## _set)
def_set(type, COMP_TYPE) def_set(type, COMP_TYPE)
def_set(role, COMP_ROLE) def_set(role, COMP_ROLE)
def_set(user, COMP_USER) def_set(user, COMP_USER)

View file

@ -1,14 +1,2 @@
#include <selinux/context.h> #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)

View file

@ -37,4 +37,3 @@ int security_deny_unknown(void)
return deny_unknown; return deny_unknown;
} }
hidden_def(security_deny_unknown);

View file

@ -35,4 +35,3 @@ int security_disable(void)
return 0; return 0;
} }
hidden_def(security_disable)

View file

@ -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

View file

@ -20,7 +20,6 @@ int is_selinux_enabled(void)
#endif #endif
} }
hidden_def(is_selinux_enabled)
/* /*
* Function: is_selinux_mls_enabled() * Function: is_selinux_mls_enabled()
@ -55,4 +54,3 @@ int is_selinux_mls_enabled(void)
return enabled; return enabled;
} }
hidden_def(is_selinux_mls_enabled)

View file

@ -1,3 +1,5 @@
#!/bin/bash
function except() { function except() {
case $1 in case $1 in
selinux_file_context_cmp) # ignore selinux_file_context_cmp) # ignore
@ -10,15 +12,26 @@ echo "
PyErr_SetFromErrno(PyExc_OSError); PyErr_SetFromErrno(PyExc_OSError);
SWIG_fail; SWIG_fail;
} }
} }"
"
;; ;;
esac 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 then
# clang does not support -aux-info so fall back to gcc # 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 fi
for i in `awk '/<stdin>.*extern int/ { print $6 }' temp.aux`; do except $i ; done for i in `awk '/<stdin>.*extern int/ { print $6 }' temp.aux`; do except $i ; done
rm -f -- temp.aux temp.o rm -f -- temp.aux temp.o

View file

@ -49,7 +49,6 @@ int fgetfilecon_raw(int fd, char ** context)
return ret; return ret;
} }
hidden_def(fgetfilecon_raw)
int fgetfilecon(int fd, char ** context) int fgetfilecon(int fd, char ** context)
{ {

View file

@ -8,4 +8,3 @@ void freecon(char * con)
free(con); free(con);
} }
hidden_def(freecon)

View file

@ -16,4 +16,3 @@ void freeconary(char ** con)
free(con); free(con);
} }
hidden_def(freeconary)

View file

@ -25,7 +25,6 @@ int fsetfilecon_raw(int fd, const char * context)
return rc; return rc;
} }
hidden_def(fsetfilecon_raw)
int fsetfilecon(int fd, const char *context) int fsetfilecon(int fd, const char *context)
{ {

View file

@ -2,6 +2,7 @@
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdio_ext.h> #include <stdio_ext.h>
#include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
@ -12,7 +13,7 @@
int get_default_context_with_role(const char *user, int get_default_context_with_role(const char *user,
const char *role, const char *role,
char * fromcon, const char *fromcon,
char ** newcon) char ** newcon)
{ {
char **conary; char **conary;
@ -51,28 +52,28 @@ int get_default_context_with_role(const char *user,
return rc; return rc;
} }
hidden_def(get_default_context_with_role)
int get_default_context_with_rolelevel(const char *user, int get_default_context_with_rolelevel(const char *user,
const char *role, const char *role,
const char *level, const char *level,
char * fromcon, const char *fromcon,
char ** newcon) char ** newcon)
{ {
int rc = 0; int rc;
int freefrom = 0; char *backup_fromcon = NULL;
context_t con; context_t con;
char *newfromcon; const char *newfromcon;
if (!level) if (!level)
return get_default_context_with_role(user, role, fromcon, return get_default_context_with_role(user, role, fromcon,
newcon); newcon);
if (!fromcon) { if (!fromcon) {
rc = getcon(&fromcon); rc = getcon(&backup_fromcon);
if (rc < 0) if (rc < 0)
return rc; return rc;
freefrom = 1; fromcon = backup_fromcon;
} }
rc = -1; rc = -1;
@ -91,14 +92,13 @@ int get_default_context_with_rolelevel(const char *user,
out: out:
context_free(con); context_free(con);
if (freefrom) freecon(backup_fromcon);
freecon(fromcon);
return rc; return rc;
} }
int get_default_context(const char *user, int get_default_context(const char *user,
char * fromcon, char ** newcon) const char *fromcon, char ** newcon)
{ {
char **conary; char **conary;
int rc; int rc;
@ -114,64 +114,41 @@ int get_default_context(const char *user,
return 0; return 0;
} }
static int find_partialcon(char ** list, static int is_in_reachable(char **reachable, const char *usercon_str)
unsigned int nreach, char *part)
{ {
const char *conrole, *contype; if (!reachable)
char *partrole, *parttype, *ptr; return 0;
context_t con;
unsigned int i;
partrole = part; for (; *reachable != NULL; reachable++) {
ptr = part; if (strcmp(*reachable, usercon_str) == 0) {
while (*ptr && !isspace(*ptr) && *ptr != ':') return 1;
ptr++;
if (*ptr != ':')
return -1;
*ptr++ = 0;
parttype = ptr;
while (*ptr && !isspace(*ptr) && *ptr != ':')
ptr++;
*ptr = 0;
for (i = 0; i < nreach; i++) {
con = context_new(list[i]);
if (!con)
return -1;
conrole = context_role_get(con);
contype = context_type_get(con);
if (!conrole || !contype) {
context_free(con);
return -1;
} }
if (!strcmp(conrole, partrole) && !strcmp(contype, parttype)) {
context_free(con);
return i;
} }
context_free(con); return 0;
}
return -1;
} }
static int get_context_order(FILE * fp, static int get_context_user(FILE * fp,
char * fromcon, const char * fromcon,
char ** reachable, const char * user,
unsigned int nreach, char ***reachable,
unsigned int *ordering, unsigned int *nordered) unsigned int *nreachable)
{ {
char *start, *end = NULL; char *start, *end = NULL;
char *line = 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; ssize_t len;
int found = 0; int found = 0;
const char *fromrole, *fromtype; const char *fromrole, *fromtype, *fromlevel;
char *linerole, *linetype; char *linerole, *linetype;
unsigned int i; char **new_reachable = NULL;
char *usercon_str;
context_t con; context_t con;
context_t usercon;
int rc; int rc;
errno = -EINVAL; errno = EINVAL;
/* Extract the role and type of the fromcon for matching. /* Extract the role and type of the fromcon for matching.
User identity and MLS range can be variable. */ User identity and MLS range can be variable. */
@ -180,6 +157,7 @@ static int get_context_order(FILE * fp,
return -1; return -1;
fromrole = context_role_get(con); fromrole = context_role_get(con);
fromtype = context_type_get(con); fromtype = context_type_get(con);
fromlevel = context_range_get(con);
if (!fromrole || !fromtype) { if (!fromrole || !fromtype) {
context_free(con); context_free(con);
return -1; return -1;
@ -243,23 +221,75 @@ static int get_context_order(FILE * fp,
if (*end) if (*end)
*end++ = 0; *end++ = 0;
/* Check for a match in the reachable list. */ /* Check whether a new context is valid */
rc = find_partialcon(reachable, nreach, start); if (SIZE_MAX - user_len < strlen(start) + 2) {
if (rc < 0) { fprintf(stderr, "%s: one of partial contexts is too big\n", __FUNCTION__);
/* No match, skip it. */ 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; start = end;
continue; continue;
} }
free(usercon_str);
/* If a match is found and the entry is not already ordered if (context_range_set(usercon, fromlevel) != 0) {
(e.g. due to prior match in prior config file), then set context_free(usercon);
the ordering for it. */ rc = -1;
i = rc; goto out;
if (ordering[i] == nreach) }
ordering[i] = (*nordered)++; usercon_str = context_str(usercon);
start = end; if (!usercon_str) {
context_free(usercon);
rc = -1;
goto out;
} }
/* check whether usercon is already in reachable */
if (is_in_reachable(*reachable, usercon_str)) {
context_free(usercon);
start = end;
continue;
}
if (security_check_context(usercon_str) == 0) {
new_reachable = realloc(*reachable, (*nreachable + 2) * sizeof(char *));
if (!new_reachable) {
context_free(usercon);
rc = -1;
goto out;
}
*reachable = new_reachable;
new_reachable[*nreachable] = strdup(usercon_str);
if (new_reachable[*nreachable] == NULL) {
context_free(usercon);
rc = -1;
goto out;
}
new_reachable[*nreachable + 1] = 0;
*nreachable += 1;
}
context_free(usercon);
start = end;
}
rc = 0; rc = 0;
out: out:
@ -313,39 +343,24 @@ static int get_failsafe_context(const char *user, char ** newcon)
return 0; 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, int get_ordered_context_list_with_level(const char *user,
const char *level, const char *level,
char * fromcon, const char *fromcon,
char *** list) char *** list)
{ {
int rc; int rc;
int freefrom = 0; char *backup_fromcon = NULL;
context_t con; context_t con;
char *newfromcon; const char *newfromcon;
if (!level) if (!level)
return get_ordered_context_list(user, fromcon, list); return get_ordered_context_list(user, fromcon, list);
if (!fromcon) { if (!fromcon) {
rc = getcon(&fromcon); rc = getcon(&backup_fromcon);
if (rc < 0) if (rc < 0)
return rc; return rc;
freefrom = 1; fromcon = backup_fromcon;
} }
rc = -1; rc = -1;
@ -364,16 +379,14 @@ int get_ordered_context_list_with_level(const char *user,
out: out:
context_free(con); context_free(con);
if (freefrom) freecon(backup_fromcon);
freecon(fromcon);
return rc; return rc;
} }
hidden_def(get_ordered_context_list_with_level)
int get_default_context_with_level(const char *user, int get_default_context_with_level(const char *user,
const char *level, const char *level,
char * fromcon, const char *fromcon,
char ** newcon) char ** newcon)
{ {
char **conary; char **conary;
@ -391,15 +404,13 @@ int get_default_context_with_level(const char *user,
} }
int get_ordered_context_list(const char *user, int get_ordered_context_list(const char *user,
char * fromcon, const char *fromcon,
char *** list) char *** list)
{ {
char **reachable = NULL; char **reachable = NULL;
unsigned int *ordering = NULL;
struct context_order *co = NULL;
char **ptr;
int rc = 0; int rc = 0;
unsigned int nreach = 0, nordered = 0, freefrom = 0, i; unsigned nreachable = 0;
char *backup_fromcon = NULL;
FILE *fp; FILE *fp;
char *fname = NULL; char *fname = NULL;
size_t fname_len; size_t fname_len;
@ -407,29 +418,12 @@ int get_ordered_context_list(const char *user,
if (!fromcon) { if (!fromcon) {
/* Get the current context and use it for the starting context */ /* Get the current context and use it for the starting context */
rc = getcon(&fromcon); rc = getcon(&backup_fromcon);
if (rc < 0) if (rc < 0)
return rc; 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 /* Determine the ordering to apply from the optional per-user config
and from the global config. */ and from the global config. */
fname_len = strlen(user_contexts_path) + strlen(user) + 2; 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"); fp = fopen(fname, "re");
if (fp) { if (fp) {
__fsetlocking(fp, FSETLOCKING_BYCALLER); __fsetlocking(fp, FSETLOCKING_BYCALLER);
rc = get_context_order(fp, fromcon, reachable, nreach, ordering, rc = get_context_user(fp, fromcon, user, &reachable, &nreachable);
&nordered);
fclose(fp); fclose(fp);
if (rc < 0 && errno != ENOENT) { if (rc < 0 && errno != ENOENT) {
fprintf(stderr, fprintf(stderr,
@ -454,8 +448,7 @@ int get_ordered_context_list(const char *user,
fp = fopen(selinux_default_context_path(), "re"); fp = fopen(selinux_default_context_path(), "re");
if (fp) { if (fp) {
__fsetlocking(fp, FSETLOCKING_BYCALLER); __fsetlocking(fp, FSETLOCKING_BYCALLER);
rc = get_context_order(fp, fromcon, reachable, nreach, ordering, rc = get_context_user(fp, fromcon, user, &reachable, &nreachable);
&nordered);
fclose(fp); fclose(fp);
if (rc < 0 && errno != ENOENT) { if (rc < 0 && errno != ENOENT) {
fprintf(stderr, fprintf(stderr,
@ -463,42 +456,20 @@ int get_ordered_context_list(const char *user,
__FUNCTION__, selinux_default_context_path()); __FUNCTION__, selinux_default_context_path());
/* Fall through */ /* Fall through */
} }
rc = 0;
} }
if (!nordered) if (!nreachable)
goto failsafe; 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: out:
if (rc > 0) if (nreachable > 0) {
*list = reachable; *list = reachable;
rc = nreachable;
}
else else
freeconary(reachable); freeconary(reachable);
free(ordering); freecon(backup_fromcon);
if (freefrom)
freecon(fromcon);
return rc; return rc;
@ -519,8 +490,7 @@ int get_ordered_context_list(const char *user,
reachable = NULL; reachable = NULL;
goto out; goto out;
} }
rc = 1; /* one context in the list */ nreachable = 1; /* one context in the list */
goto out; goto out;
} }
hidden_def(get_ordered_context_list)

View file

@ -1,6 +1,2 @@
#include <selinux/get_context_list.h> #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)

View file

@ -1,4 +1,2 @@
#include <selinux/get_default_type.h> #include <selinux/get_default_type.h>
#include "dso.h"
hidden_proto(selinux_default_type_path)

View file

@ -53,7 +53,6 @@ int security_get_initial_context_raw(const char * name, char ** con)
return ret; return ret;
} }
hidden_def(security_get_initial_context_raw)
int security_get_initial_context(const char * name, char ** con) 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; return ret;
} }
hidden_def(security_get_initial_context)

View file

@ -37,4 +37,3 @@ int security_getenforce(void)
return !!enforce; return !!enforce;
} }
hidden_def(security_getenforce)

View file

@ -49,7 +49,6 @@ int getfilecon_raw(const char *path, char ** context)
return ret; return ret;
} }
hidden_def(getfilecon_raw)
int getfilecon(const char *path, char ** context) int getfilecon(const char *path, char ** context)
{ {
@ -70,4 +69,3 @@ int getfilecon(const char *path, char ** context)
return ret; return ret;
} }
hidden_def(getfilecon)

View file

@ -43,7 +43,6 @@ int getpeercon_raw(int fd, char ** context)
return ret; return ret;
} }
hidden_def(getpeercon_raw)
int getpeercon(int fd, char ** context) int getpeercon(int fd, char ** context)
{ {

View file

@ -12,7 +12,6 @@
#include <stdint.h> #include <stdint.h>
#include <limits.h> #include <limits.h>
#include "dso.h"
#include "policy.h" #include "policy.h"
#include "selinux_internal.h" #include "selinux_internal.h"
#include "setrans_internal.h" #include "setrans_internal.h"
@ -79,7 +78,6 @@ int selinuxfs_exists(void)
fclose(fp); fclose(fp);
return exists; return exists;
} }
hidden_def(selinuxfs_exists)
static void init_selinuxmnt(void) static void init_selinuxmnt(void)
{ {
@ -138,14 +136,12 @@ void fini_selinuxmnt(void)
selinux_mnt = NULL; selinux_mnt = NULL;
} }
hidden_def(fini_selinuxmnt)
void set_selinuxmnt(const char *mnt) void set_selinuxmnt(const char *mnt)
{ {
selinux_mnt = strdup(mnt); selinux_mnt = strdup(mnt);
} }
hidden_def(set_selinuxmnt)
static void init_lib(void) __attribute__ ((constructor)); static void init_lib(void) __attribute__ ((constructor));
static void init_lib(void) static void init_lib(void)

View file

@ -38,7 +38,7 @@ static int get_customizable_type_list(char *** retlist)
while (fgets_unlocked(buf, selinux_page_size, fp) while (fgets_unlocked(buf, selinux_page_size, fp)
&& i < ctr) { && i < ctr) {
buf[strlen(buf) - 1] = 0; buf[strlen(buf) - 1] = 0;
list[i] = (char *) strdup(buf); list[i] = strdup(buf);
if (!list[i]) { if (!list[i]) {
unsigned int j; unsigned int j;
for (j = 0; j < i; j++) for (j = 0; j < i; j++)

View file

@ -96,9 +96,15 @@ static int process_line(struct selabel_handle *rec,
items = read_spec_entries(line_buf, &errbuf, 2, &prop, &context); items = read_spec_entries(line_buf, &errbuf, 2, &prop, &context);
if (items < 0) { if (items < 0) {
items = errno; items = errno;
if (errbuf) {
selinux_log(SELINUX_ERROR, selinux_log(SELINUX_ERROR,
"%s: line %u error due to: %s\n", path, "%s: line %u error due to: %s\n", path,
lineno, errbuf ?: strerror(errno)); lineno, errbuf);
} else {
selinux_log(SELINUX_ERROR,
"%s: line %u error due to: %m\n", path,
lineno);
}
errno = items; errno = items;
return -1; return -1;
} }

View file

@ -277,7 +277,7 @@ db_init(const struct selinux_opt *opts, unsigned nopts,
if (!path) if (!path)
path = selinux_sepgsql_context_path(); path = selinux_sepgsql_context_path();
if ((filp = fopen(path, "rb")) == NULL) { if ((filp = fopen(path, "re")) == NULL) {
free(catalog); free(catalog);
return NULL; return NULL;
} }

View file

@ -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 // 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, // the allocated array and updates the match count. If match_count is NULL,
// stops early once the 1st match is found. // 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, const char *key,
int type, int type,
bool partial, 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 saved_data *data = (struct saved_data *)rec->data;
struct spec *spec_arr = data->spec_arr; struct spec *spec_arr = data->spec_arr;
int i, rc, file_stem; int i, rc, file_stem;
size_t len;
mode_t mode = (mode_t)type; mode_t mode = (mode_t)type;
char *clean_key = NULL; char *clean_key = NULL;
const char *prev_slash, *next_slash; const char *prev_slash, *next_slash;
unsigned int sofar = 0; unsigned int sofar = 0;
char *sub = NULL; char *sub = NULL;
const struct spec **result = NULL; struct spec **result = NULL;
if (match_count) { if (match_count) {
*match_count = 0; *match_count = 0;
result = calloc(data->nspec, sizeof(struct spec*)); result = calloc(data->nspec, sizeof(struct spec*));
@ -947,6 +948,27 @@ static const struct spec **lookup_all(struct selabel_handle *rec,
key = clean_key; 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); sub = selabel_sub_key(data, key);
if (sub) if (sub)
key = sub; key = sub;
@ -1001,6 +1023,8 @@ static const struct spec **lookup_all(struct selabel_handle *rec,
goto finish; goto finish;
} }
} }
if (!result[0])
errno = ENOENT;
finish: finish:
free(clean_key); free(clean_key);
@ -1016,11 +1040,11 @@ static struct spec *lookup_common(struct selabel_handle *rec,
const char *key, const char *key,
int type, int type,
bool partial) { 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) { if (!matches) {
return NULL; return NULL;
} }
struct spec *result = (struct spec*)matches[0]; struct spec *result = matches[0];
free(matches); free(matches);
return result; return result;
} }
@ -1083,7 +1107,7 @@ static bool hash_all_partial_matches(struct selabel_handle *rec, const char *key
assert(digest); assert(digest);
size_t total_matches; 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) { if (!matches) {
return false; return false;
} }

View file

@ -286,7 +286,6 @@ static inline int store_stem(struct saved_data *data, char *buf, int stem_len)
tmp_arr = realloc(data->stem_arr, tmp_arr = realloc(data->stem_arr,
sizeof(*tmp_arr) * alloc_stems); sizeof(*tmp_arr) * alloc_stems);
if (!tmp_arr) { if (!tmp_arr) {
free(buf);
return -1; return -1;
} }
data->alloc_stems = alloc_stems; 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 stem_len = get_stem_from_spec(buf);
int stemid; int stemid;
char *stem; char *stem;
int r;
if (!stem_len) if (!stem_len)
return -1; return -1;
@ -321,7 +321,11 @@ static inline int find_stem_from_spec(struct saved_data *data, const char *buf)
if (!stem) if (!stem)
return -1; 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 /* 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, &regex, &type, &context); items = read_spec_entries(line_buf, &errbuf, 3, &regex, &type, &context);
if (items < 0) { if (items < 0) {
rc = errno; rc = errno;
if (errbuf) {
selinux_log(SELINUX_ERROR, selinux_log(SELINUX_ERROR,
"%s: line %u error due to: %s\n", path, "%s: line %u error due to: %s\n", path,
lineno, errbuf ?: strerror(errno)); lineno, errbuf);
} else {
selinux_log(SELINUX_ERROR,
"%s: line %u error due to: %m\n", path,
lineno);
}
errno = rc; errno = rc;
return -1; return -1;
} }

View file

@ -13,7 +13,6 @@
#include <stdio.h> #include <stdio.h>
#include <selinux/selinux.h> #include <selinux/selinux.h>
#include <selinux/label.h> #include <selinux/label.h>
#include "dso.h"
#include "sha1.h" #include "sha1.h"
#if defined(ANDROID) || defined(__APPLE__) #if defined(ANDROID) || defined(__APPLE__)
@ -26,22 +25,22 @@
*/ */
int selabel_file_init(struct selabel_handle *rec, int selabel_file_init(struct selabel_handle *rec,
const struct selinux_opt *opts, const struct selinux_opt *opts,
unsigned nopts) hidden; unsigned nopts) ;
int selabel_media_init(struct selabel_handle *rec, int selabel_media_init(struct selabel_handle *rec,
const struct selinux_opt *opts, const struct selinux_opt *opts,
unsigned nopts) hidden; unsigned nopts) ;
int selabel_x_init(struct selabel_handle *rec, int selabel_x_init(struct selabel_handle *rec,
const struct selinux_opt *opts, const struct selinux_opt *opts,
unsigned nopts) hidden; unsigned nopts) ;
int selabel_db_init(struct selabel_handle *rec, int selabel_db_init(struct selabel_handle *rec,
const struct selinux_opt *opts, const struct selinux_opt *opts,
unsigned nopts) hidden; unsigned nopts) ;
int selabel_property_init(struct selabel_handle *rec, int selabel_property_init(struct selabel_handle *rec,
const struct selinux_opt *opts, const struct selinux_opt *opts,
unsigned nopts) hidden; unsigned nopts) ;
int selabel_exact_match_init(struct selabel_handle *rec, int selabel_exact_match_init(struct selabel_handle *rec,
const struct selinux_opt *opts, const struct selinux_opt *opts,
unsigned nopts) hidden; unsigned nopts) ;
/* /*
* Labeling internal structures * Labeling internal structures
@ -122,24 +121,26 @@ struct selabel_handle {
*/ */
extern int extern int
selabel_validate(struct selabel_handle *rec, selabel_validate(struct selabel_handle *rec,
struct selabel_lookup_rec *contexts) hidden; struct selabel_lookup_rec *contexts) ;
/* /*
* Compatibility support * Compatibility support
*/ */
extern int myprintf_compat; extern int myprintf_compat;
extern void __attribute__ ((format(printf, 1, 2))) extern void __attribute__ ((format(printf, 1, 2)))
(*myprintf) (const char *fmt, ...) hidden; (*myprintf) (const char *fmt, ...) ;
#define COMPAT_LOG(type, fmt...) if (myprintf_compat) \ #define COMPAT_LOG(type, fmt...) do { \
if (myprintf_compat) \
myprintf(fmt); \ myprintf(fmt); \
else \ else \
selinux_log(type, fmt); selinux_log(type, fmt); \
} while (0)
extern int extern int
compat_validate(struct selabel_handle *rec, compat_validate(struct selabel_handle *rec,
struct selabel_lookup_rec *contexts, 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 * The read_spec_entries function may be used to

View file

@ -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)) if (process_line(path, line_buf, pass, ++lineno, rec))
goto finish; goto finish;
} }
lineno = 0;
if (pass == 0) { if (pass == 0) {
if (data->nspec == 0) { if (data->nspec == 0) {

View file

@ -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. * This function calls read_spec_entry() to do the actual string processing.
* As such, can return anything from that function as well. * 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; char **spec_entry, *buf_p;
int len, rc, items, entry_len = 0; 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. */ /* 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; 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. * 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, char *from_addr, size_t buf_len,
const char *path) const char *path)
{ {

View file

@ -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)) if (process_line(path, line_buf, pass, ++lineno, rec))
goto finish; goto finish;
} }
lineno = 0;
if (pass == 0) { if (pass == 0) {
if (data->nspec == 0) { if (data->nspec == 0) {

View file

@ -49,7 +49,6 @@ int lgetfilecon_raw(const char *path, char ** context)
return ret; return ret;
} }
hidden_def(lgetfilecon_raw)
int lgetfilecon(const char *path, char ** context) int lgetfilecon(const char *path, char ** context)
{ {

View 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:
*;
};

View file

@ -45,7 +45,6 @@ int security_load_policy(void *data, size_t len)
return 0; return 0;
} }
hidden_def(security_load_policy)
#ifndef ANDROID #ifndef ANDROID
#undef max #undef max
@ -77,11 +76,11 @@ int selinux_mkload_policy(int preservebools __attribute__((unused)))
#ifdef SHARED #ifdef SHARED
char *errormsg = NULL; char *errormsg = NULL;
void *libsepolh = NULL; void *libsepolh = NULL;
libsepolh = dlopen("libsepol.so.1", RTLD_NOW); libsepolh = dlopen("libsepol.so.2", RTLD_NOW);
if (libsepolh) { if (libsepolh) {
usesepol = 1; usesepol = 1;
dlerror(); 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"); vers_max = dlsym(libsepolh, "sepol_policy_kern_vers_max");
DLERR(); DLERR();
vers_min = dlsym(libsepolh, "sepol_policy_kern_vers_min"); vers_min = dlsym(libsepolh, "sepol_policy_kern_vers_min");
@ -138,15 +137,15 @@ int selinux_mkload_policy(int preservebools __attribute__((unused)))
} }
if (fd < 0) { if (fd < 0) {
fprintf(stderr, fprintf(stderr,
"SELinux: Could not open policy file <= %s.%d: %s\n", "SELinux: Could not open policy file <= %s.%d: %m\n",
selinux_binary_policy_path(), maxvers, strerror(errno)); selinux_binary_policy_path(), maxvers);
goto dlclose; goto dlclose;
} }
if (fstat(fd, &sb) < 0) { if (fstat(fd, &sb) < 0) {
fprintf(stderr, fprintf(stderr,
"SELinux: Could not stat policy file %s: %s\n", "SELinux: Could not stat policy file %s: %m\n",
path, strerror(errno)); path);
goto close; 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); data = map = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
if (map == MAP_FAILED) { if (map == MAP_FAILED) {
fprintf(stderr, fprintf(stderr,
"SELinux: Could not map policy file %s: %s\n", "SELinux: Could not map policy file %s: %m\n",
path, strerror(errno)); path);
goto close; goto close;
} }
@ -194,8 +193,8 @@ int selinux_mkload_policy(int preservebools __attribute__((unused)))
if (rc) if (rc)
fprintf(stderr, fprintf(stderr,
"SELinux: Could not load policy file %s: %s\n", "SELinux: Could not load policy file %s: %m\n",
path, strerror(errno)); path);
unmap: unmap:
if (data != map) if (data != map)
@ -213,7 +212,6 @@ int selinux_mkload_policy(int preservebools __attribute__((unused)))
return rc; return rc;
} }
hidden_def(selinux_mkload_policy)
/* /*
* Mount point for selinuxfs. * Mount point for selinuxfs.
@ -281,7 +279,8 @@ int selinux_init_load_policy(int *enforce)
const char *mntpoint = NULL; const char *mntpoint = NULL;
/* First make sure /sys is mounted */ /* First make sure /sys is mounted */
if (mount("sysfs", "/sys", "sysfs", 0, 0) == 0 || errno == EBUSY) { 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; mntpoint = SELINUXMNT;
} else { } else {
/* check old mountpoint */ /* check old mountpoint */
@ -307,7 +306,7 @@ int selinux_init_load_policy(int *enforce)
*enforce = 0; *enforce = 0;
} else { } else {
/* Only emit this error if selinux was not disabled */ /* 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) if (rc == 0)
@ -353,7 +352,7 @@ int selinux_init_load_policy(int *enforce)
if (orig_enforce != *enforce) { if (orig_enforce != *enforce) {
rc = security_setenforce(*enforce); rc = security_setenforce(*enforce);
if (rc < 0) { 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) if (*enforce)
goto noload; goto noload;
} }

View file

@ -25,7 +25,6 @@ int lsetfilecon_raw(const char *path, const char * context)
return rc; return rc;
} }
hidden_def(lsetfilecon_raw)
int lsetfilecon(const char *path, const char *context) int lsetfilecon(const char *path, const char *context)
{ {

View file

@ -22,6 +22,7 @@ int matchmediacon(const char *media, char ** con)
return -1; return -1;
while (!feof_unlocked(infile)) { while (!feof_unlocked(infile)) {
if (!fgets_unlocked(current_line, sizeof(current_line), infile)) { if (!fgets_unlocked(current_line, sizeof(current_line), infile)) {
fclose(infile);
return -1; return -1;
} }
if (current_line[strlen(current_line) - 1]) if (current_line[strlen(current_line) - 1])

View file

@ -78,17 +78,30 @@ static pthread_once_t once = PTHREAD_ONCE_INIT;
static pthread_key_t destructor_key; static pthread_key_t destructor_key;
static int destructor_key_initialized = 0; 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) static int add_array_elt(char *con)
{ {
char **tmp;
if (con_array_size) { if (con_array_size) {
while (con_array_used >= con_array_size) { while (con_array_used >= con_array_size) {
con_array_size *= 2; con_array_size *= 2;
con_array = (char **)realloc(con_array, sizeof(char*) * tmp = (char **)realloc(con_array, sizeof(char*) *
con_array_size); con_array_size);
if (!con_array) { if (!tmp) {
con_array_size = con_array_used = 0; free_array_elts();
return -1; return -1;
} }
con_array = tmp;
} }
} else { } else {
con_array_size = 1000; con_array_size = 1000;
@ -105,13 +118,6 @@ static int add_array_elt(char *con)
return con_array_used++; 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)) void set_matchpathcon_invalidcon(int (*f) (const char *p, unsigned l, char *c))
{ {
myinvalidcon = f; myinvalidcon = f;
@ -315,14 +321,24 @@ void matchpathcon_filespec_destroy(void)
fl_head = NULL; 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) static void matchpathcon_thread_destructor(void __attribute__((unused)) *ptr)
{ {
matchpathcon_fini(); matchpathcon_fini_internal();
} }
void __attribute__((destructor)) matchpathcon_lib_destructor(void); 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) if (destructor_key_initialized)
__selinux_key_delete(destructor_key); __selinux_key_delete(destructor_key);
@ -351,7 +367,6 @@ int matchpathcon_init_prefix(const char *path, const char *subset)
return hnd ? 0 : -1; return hnd ? 0 : -1;
} }
hidden_def(matchpathcon_init_prefix)
int matchpathcon_init(const char *path) int matchpathcon_init(const char *path)
{ {
@ -360,12 +375,7 @@ int matchpathcon_init(const char *path)
void matchpathcon_fini(void) void matchpathcon_fini(void)
{ {
free_array_elts(); matchpathcon_fini_internal();
if (hnd) {
selabel_close(hnd);
hnd = NULL;
}
} }
/* /*
@ -383,8 +393,8 @@ int realpath_not_final(const char *name, char *resolved_path)
tmp_path = strdup(name); tmp_path = strdup(name);
if (!tmp_path) { if (!tmp_path) {
myprintf("symlink_realpath(%s) strdup() failed: %s\n", myprintf("symlink_realpath(%s) strdup() failed: %m\n",
name, strerror(errno)); name);
rc = -1; rc = -1;
goto out; goto out;
} }
@ -404,8 +414,8 @@ int realpath_not_final(const char *name, char *resolved_path)
} }
if (!p) { if (!p) {
myprintf("symlink_realpath(%s) realpath() failed: %s\n", myprintf("symlink_realpath(%s) realpath() failed: %m\n",
name, strerror(errno)); name);
rc = -1; rc = -1;
goto out; goto out;
} }
@ -428,7 +438,7 @@ out:
return rc; 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 stackpath[PATH_MAX + 1];
char *p = NULL; char *p = NULL;
@ -449,9 +459,13 @@ int matchpathcon(const char *path, mode_t mode, char ** con)
selabel_lookup(hnd, con, path, mode); 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 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) if (i < 0)
return -1; return -1;
@ -469,15 +483,15 @@ void matchpathcon_checkmatches(char *str __attribute__((unused)))
int selinux_file_context_cmp(const char * a, int selinux_file_context_cmp(const char * a,
const char * b) 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) if (!a && !b)
return 0; return 0;
if (!a) if (!a)
return -1; return -1;
if (!b) if (!b)
return 1; return 1;
rest_a = strchr((char *)a, ':'); rest_a = strchr(a, ':');
rest_b = strchr((char *)b, ':'); rest_b = strchr(b, ':');
if (!rest_a && !rest_b) if (!rest_a && !rest_b)
return 0; return 0;
if (!rest_a) if (!rest_a)

View file

@ -7,7 +7,6 @@
#include "selinux_internal.h" #include "selinux_internal.h"
#include <stdio.h> #include <stdio.h>
#include "policy.h" #include "policy.h"
#include "dso.h"
#include <limits.h> #include <limits.h>
int security_policyvers(void) int security_policyvers(void)
@ -42,4 +41,3 @@ int security_policyvers(void)
return vers; return vers;
} }
hidden_def(security_policyvers)

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